From 013c750abda2e2853f4e26c0c135b41596058f02 Mon Sep 17 00:00:00 2001 From: Massimo Biolcati Date: Wed, 17 Jun 2020 22:49:23 -0400 Subject: [PATCH] Update project to Swift 5 and Xcode 11 --- .DS_Store | Bin 6148 -> 6148 bytes .gitignore | 103 ++++- ICETutorial.xcodeproj/project.pbxproj | 105 +++-- .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcshareddata/WorkspaceSettings.xcsettings | 8 + ICETutorial/AppDelegate.swift | 68 +-- .../AppIcon.appiconset/Contents.json | 87 +++- ICETutorial/Images.xcassets/Contents.json | 6 + .../LaunchImage.launchimage/Contents.json | 51 --- ICETutorial/Info.plist | 4 +- ICETutorial/Launch Screen.storyboard | 48 +++ .../Libraries/ICETutorialController.swift | 399 +++++++++--------- ICETutorial/Libraries/ICETutorialPage.swift | 26 +- ICETutorialTests/ICETutorialTests.swift | 2 +- ICETutorialTests/Info.plist | 2 +- Resources/Default-568h@2x.png | Bin 18594 -> 0 bytes Resources/Default.png | Bin 6540 -> 0 bytes Resources/Default@2x.png | Bin 16107 -> 0 bytes Resources/button-background.png | Bin 6364 -> 0 bytes Resources/button-background@2x.png | Bin 6708 -> 0 bytes 20 files changed, 543 insertions(+), 374 deletions(-) create mode 100644 ICETutorial.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 ICETutorial.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings create mode 100644 ICETutorial/Images.xcassets/Contents.json delete mode 100755 ICETutorial/Images.xcassets/LaunchImage.launchimage/Contents.json create mode 100644 ICETutorial/Launch Screen.storyboard delete mode 100755 Resources/Default-568h@2x.png delete mode 100755 Resources/Default.png delete mode 100755 Resources/Default@2x.png delete mode 100755 Resources/button-background.png delete mode 100755 Resources/button-background@2x.png diff --git a/.DS_Store b/.DS_Store index 44876a7c9904b7bc977948337f993d0400797c16..bb8991b445710e18f53f70ab4e316c758a178af4 100644 GIT binary patch delta 157 zcmZoMXfc@J&&a(oU^g=(_hcRx%gOvK;+!eP$vH{+`8kY}dsy@)7qEmgGyEt5u|;z8 zU0jlK@{<@C7&sc%iPg3F9&&_Aq+pjQ$S@2}&d)6X>R@1C3;>Y=lP9oCj$cm_vDW(Vw2Ta5CL q(voBbhVuskA22XL1yj%kt(lk@Ca+_4*(}fYf^lL)#AbGmzx)7oZXn_S diff --git a/.gitignore b/.gitignore index fef6442..a159107 100644 --- a/.gitignore +++ b/.gitignore @@ -1,22 +1,103 @@ +##### +# OS X temporary files that should never be committed +.DS_Store +*.swp +*.lock +profile -*.xcworkspacedata +##### +# DotEnv files +.env -*.xcuserstate +#### +# Xcode temporary files that should never be committed +*~.nib -*.xcsettings +#### +# Objective-C/Swift specific +*.hmap +*.ipa -*.xcbkptlist +#### +# Xcode build files +DerivedData/ +build/ +Builds/ -*.xcscheme +##### +# Xcode private settings (window sizes, bookmarks, breakpoints, custom executables, smart groups) +*.pbxuser +*.mode1v3 +*.mode2v3 +*.perspectivev3 +!default.pbxuser +!default.mode1v3 +!default.mode2v3 +!default.perspectivev3 -ICETutorial.xcodeproj/xcuserdata/patrick.trillsam.xcuserdatad/xcschemes/xcschememanagement.plist +#### +# Xcode 4 +xcuserdata +!xcschemes +# Xcode 4 +*.moved-aside + +#### +# XCode 4 workspaces - more detailed +!xcshareddata +!default.xcworkspace +*.xcworkspacedata -ICETutorial.xcodeproj/xcuserdata/patrick.trillsam.xcuserdatad/xcschemes/ICETutorialSwift.xcscheme -ICETutorial.xcodeproj/xcuserdata/patrick.trillsam.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +#### +# Xcode 5 +*.xccheckout +*.xcuserstate -ICETutorial.xcodeproj/project.xcworkspace/xcuserdata/patrick.trillsam.xcuserdatad/WorkspaceSettings.xcsettings +#### +# Xcode 7 +*.xcscmblueprint -ICETutorial.xcodeproj/project.xcworkspace/xcuserdata/patrick.trillsam.xcuserdatad/UserInterfaceState.xcuserstate +#### +# AppCode +.idea/ -ICETutorial.xcodeproj/project.xcworkspace/contents.xcworkspacedata +#### +# Other Xcode files +profile +*.hmap +*.ipa + +#### +# CocoaPods +Pods/ +!Podfile +!Podfile.lock + +#### +# Carthage +Carthage/Build.rbenv-vars +!Cartfile +!Cartfile.private +!Cartfile.resolved + +#### +# Fastlane +# Temporary profiling data +/fastlane/report.xml +# Deliver temporary error output +/fastlane/Error*.png +# Deliver temporary preview output +/fastlane/Preview.html +# Snapshot generated screenshots +/fastlane/screenshots/*/*-portrait.png +/fastlane/screenshots/*/*-landscape.png +/fastlane/screenshots/screenshots.html +# Frameit generated screenshots +/fastlane/screenshots/*/*-portrait_framed.png +/fastlane/screenshots/*/*-landscape_framed.png + +#### +# rbenv +.rbenv-vars +*.xcscheme diff --git a/ICETutorial.xcodeproj/project.pbxproj b/ICETutorial.xcodeproj/project.pbxproj index 69ed317..b12343f 100755 --- a/ICETutorial.xcodeproj/project.pbxproj +++ b/ICETutorial.xcodeproj/project.pbxproj @@ -12,11 +12,6 @@ 55A1D56D193FEFCC00994874 /* ICETutorialTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55A1D56C193FEFCC00994874 /* ICETutorialTests.swift */; }; 55A1D583193FF01600994874 /* background-gradient.png in Resources */ = {isa = PBXBuildFile; fileRef = 55A1D577193FF01600994874 /* background-gradient.png */; }; 55A1D584193FF01600994874 /* background-gradient@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 55A1D578193FF01600994874 /* background-gradient@2x.png */; }; - 55A1D585193FF01600994874 /* button-background.png in Resources */ = {isa = PBXBuildFile; fileRef = 55A1D579193FF01600994874 /* button-background.png */; }; - 55A1D586193FF01600994874 /* button-background@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 55A1D57A193FF01600994874 /* button-background@2x.png */; }; - 55A1D587193FF01600994874 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 55A1D57B193FF01600994874 /* Default-568h@2x.png */; }; - 55A1D588193FF01600994874 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 55A1D57C193FF01600994874 /* Default.png */; }; - 55A1D589193FF01600994874 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 55A1D57D193FF01600994874 /* Default@2x.png */; }; 55A1D58A193FF01600994874 /* tutorial_background_00@2x.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 55A1D57E193FF01600994874 /* tutorial_background_00@2x.jpg */; }; 55A1D58B193FF01600994874 /* tutorial_background_01@2x.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 55A1D57F193FF01600994874 /* tutorial_background_01@2x.jpg */; }; 55A1D58C193FF01600994874 /* tutorial_background_02@2x.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 55A1D580193FF01600994874 /* tutorial_background_02@2x.jpg */; }; @@ -24,6 +19,7 @@ 55A1D58E193FF01600994874 /* tutorial_background_04@2x.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 55A1D582193FF01600994874 /* tutorial_background_04@2x.jpg */; }; 55A1D597193FF05400994874 /* ICETutorialPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55A1D596193FF05400994874 /* ICETutorialPage.swift */; }; 55A1D5F3193FFA9300994874 /* ICETutorialController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55A1D5F2193FFA9300994874 /* ICETutorialController.swift */; }; + 5626A6A2249AFF8300390246 /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5626A6A1249AFF8300390246 /* Launch Screen.storyboard */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -46,11 +42,6 @@ 55A1D56C193FEFCC00994874 /* ICETutorialTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ICETutorialTests.swift; sourceTree = ""; }; 55A1D577193FF01600994874 /* background-gradient.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "background-gradient.png"; sourceTree = ""; }; 55A1D578193FF01600994874 /* background-gradient@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "background-gradient@2x.png"; sourceTree = ""; }; - 55A1D579193FF01600994874 /* button-background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button-background.png"; sourceTree = ""; }; - 55A1D57A193FF01600994874 /* button-background@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button-background@2x.png"; sourceTree = ""; }; - 55A1D57B193FF01600994874 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; - 55A1D57C193FF01600994874 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; - 55A1D57D193FF01600994874 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; }; 55A1D57E193FF01600994874 /* tutorial_background_00@2x.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "tutorial_background_00@2x.jpg"; sourceTree = ""; }; 55A1D57F193FF01600994874 /* tutorial_background_01@2x.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "tutorial_background_01@2x.jpg"; sourceTree = ""; }; 55A1D580193FF01600994874 /* tutorial_background_02@2x.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "tutorial_background_02@2x.jpg"; sourceTree = ""; }; @@ -58,6 +49,7 @@ 55A1D582193FF01600994874 /* tutorial_background_04@2x.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "tutorial_background_04@2x.jpg"; sourceTree = ""; }; 55A1D596193FF05400994874 /* ICETutorialPage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ICETutorialPage.swift; sourceTree = ""; }; 55A1D5F2193FFA9300994874 /* ICETutorialController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ICETutorialController.swift; sourceTree = ""; }; + 5626A6A1249AFF8300390246 /* Launch Screen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = "Launch Screen.storyboard"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -104,6 +96,7 @@ 55A1D55E193FEFCC00994874 /* AppDelegate.swift */, 55A1D560193FEFCC00994874 /* Images.xcassets */, 55A1D55C193FEFCC00994874 /* Supporting Files */, + 5626A6A1249AFF8300390246 /* Launch Screen.storyboard */, ); path = ICETutorial; sourceTree = ""; @@ -138,11 +131,6 @@ children = ( 55A1D577193FF01600994874 /* background-gradient.png */, 55A1D578193FF01600994874 /* background-gradient@2x.png */, - 55A1D579193FF01600994874 /* button-background.png */, - 55A1D57A193FF01600994874 /* button-background@2x.png */, - 55A1D57B193FF01600994874 /* Default-568h@2x.png */, - 55A1D57C193FF01600994874 /* Default.png */, - 55A1D57D193FF01600994874 /* Default@2x.png */, 55A1D57E193FF01600994874 /* tutorial_background_00@2x.jpg */, 55A1D57F193FF01600994874 /* tutorial_background_01@2x.jpg */, 55A1D580193FF01600994874 /* tutorial_background_02@2x.jpg */, @@ -206,24 +194,29 @@ 55A1D551193FEFCC00994874 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0600; + LastUpgradeCheck = 1150; ORGANIZATIONNAME = "Patrick Trillsam"; TargetAttributes = { 55A1D558193FEFCC00994874 = { CreatedOnToolsVersion = 6.0; + LastSwiftMigration = 1150; + ProvisioningStyle = Automatic; }; 55A1D565193FEFCC00994874 = { CreatedOnToolsVersion = 6.0; + LastSwiftMigration = 1150; + ProvisioningStyle = Automatic; TestTargetID = 55A1D558193FEFCC00994874; }; }; }; buildConfigurationList = 55A1D554193FEFCC00994874 /* Build configuration list for PBXProject "ICETutorial" */; compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, + Base, ); mainGroup = 55A1D550193FEFCC00994874; productRefGroup = 55A1D55A193FEFCC00994874 /* Products */; @@ -241,18 +234,14 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 55A1D589193FF01600994874 /* Default@2x.png in Resources */, 55A1D58C193FF01600994874 /* tutorial_background_02@2x.jpg in Resources */, 55A1D58B193FF01600994874 /* tutorial_background_01@2x.jpg in Resources */, 55A1D561193FEFCC00994874 /* Images.xcassets in Resources */, - 55A1D586193FF01600994874 /* button-background@2x.png in Resources */, 55A1D58A193FF01600994874 /* tutorial_background_00@2x.jpg in Resources */, 55A1D58E193FF01600994874 /* tutorial_background_04@2x.jpg in Resources */, - 55A1D585193FF01600994874 /* button-background.png in Resources */, + 5626A6A2249AFF8300390246 /* Launch Screen.storyboard in Resources */, 55A1D584193FF01600994874 /* background-gradient@2x.png in Resources */, - 55A1D588193FF01600994874 /* Default.png in Resources */, 55A1D583193FF01600994874 /* background-gradient.png in Resources */, - 55A1D587193FF01600994874 /* Default-568h@2x.png in Resources */, 55A1D58D193FF01600994874 /* tutorial_background_03@2x.jpg in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -300,24 +289,37 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", @@ -330,7 +332,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.4; METAL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -343,17 +345,28 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -361,15 +374,17 @@ ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.4; METAL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; @@ -379,10 +394,15 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = ICETutorial/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "Patrick-Trillsam.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = ICETutorial; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; }; name = Debug; }; @@ -390,17 +410,26 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = ICETutorial/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "Patrick-Trillsam.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = ICETutorial; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; }; name = Release; }; 55A1D574193FEFCC00994874 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/ICETutorialSwift.app/ICETutorialSwift"; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = ""; FRAMEWORK_SEARCH_PATHS = ( "$(SDKROOT)/Developer/Library/Frameworks", "$(inherited)", @@ -409,27 +438,39 @@ "DEBUG=1", "$(inherited)", ); - INFOPLIST_FILE = ICETutorialSwiftTests/Info.plist; + INFOPLIST_FILE = ICETutorialTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; METAL_ENABLE_DEBUG_INFO = YES; + PRODUCT_BUNDLE_IDENTIFIER = "Patrick-Trillsam.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = ICETutorialTests; - TEST_HOST = "$(BUNDLE_LOADER)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ICETutorial.app/ICETutorial"; }; name = Debug; }; 55A1D575193FEFCC00994874 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/ICETutorialSwift.app/ICETutorialSwift"; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = ""; FRAMEWORK_SEARCH_PATHS = ( "$(SDKROOT)/Developer/Library/Frameworks", "$(inherited)", ); - INFOPLIST_FILE = ICETutorialSwiftTests/Info.plist; + INFOPLIST_FILE = ICETutorialTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; METAL_ENABLE_DEBUG_INFO = NO; + PRODUCT_BUNDLE_IDENTIFIER = "Patrick-Trillsam.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = ICETutorialTests; - TEST_HOST = "$(BUNDLE_LOADER)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ICETutorial.app/ICETutorial"; }; name = Release; }; diff --git a/ICETutorial.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ICETutorial.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/ICETutorial.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/ICETutorial.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ICETutorial.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..08de0be --- /dev/null +++ b/ICETutorial.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded + + + diff --git a/ICETutorial/AppDelegate.swift b/ICETutorial/AppDelegate.swift index 067bf39..3aefee4 100755 --- a/ICETutorial/AppDelegate.swift +++ b/ICETutorial/AppDelegate.swift @@ -10,69 +10,69 @@ import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { - + var window: UIWindow? - - func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool { - self.window = UIWindow(frame: UIScreen.mainScreen().bounds) + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]?) -> Bool { // Override point for customization after application launch. - self.window!.backgroundColor = UIColor.whiteColor() + self.window = UIWindow(frame: UIScreen.main.bounds) + self.window!.backgroundColor = .white + // Init the pages texts, and pictures. - var layer1: ICETutorialPage = ICETutorialPage(title: "Picture 1", subTitle: "Champs-Elysées by night", pictureName: "tutorial_background_00@2x.jpg", duration: 3.0) - var layer2: ICETutorialPage = ICETutorialPage(title: "Picture 2", subTitle: "The Eiffel Tower with\n cloudy weather", pictureName: "tutorial_background_01@2x.jpg", duration: 3.0) - var layer3: ICETutorialPage = ICETutorialPage(title: "Picture 3", subTitle: "An other famous street of Paris", pictureName: "tutorial_background_02@2x.jpg", duration: 3.0) - var layer4: ICETutorialPage = ICETutorialPage(title: "Picture 4", subTitle: "The Eiffel Tower with a better weather", pictureName: "tutorial_background_03@2x.jpg", duration: 3.0) - var layer5: ICETutorialPage = ICETutorialPage(title: "Picture 5", subTitle: "The Louvre's Museum Pyramide", pictureName: "tutorial_background_04@2x.jpg", duration: 3.0) + let layer1 = ICETutorialPage(title: "Picture 1", subTitle: "Champs-Elysées by night", pictureName: "tutorial_background_00@2x.jpg", duration: 3.0) + let layer2 = ICETutorialPage(title: "Picture 2", subTitle: "The Eiffel Tower with\n cloudy weather", pictureName: "tutorial_background_01@2x.jpg", duration: 3.0) + let layer3 = ICETutorialPage(title: "Picture 3", subTitle: "An other famous street of Paris", pictureName: "tutorial_background_02@2x.jpg", duration: 3.0) + let layer4 = ICETutorialPage(title: "Picture 4", subTitle: "The Eiffel Tower with a better weather", pictureName: "tutorial_background_03@2x.jpg", duration: 3.0) + let layer5 = ICETutorialPage(title: "Picture 5", subTitle: "The Louvre's Museum Pyramide", pictureName: "tutorial_background_04@2x.jpg", duration: 3.0) // Set the common style for SubTitles and Description (can be overrided on each page). - var titleStyle: ICETutorialLabelStyle = ICETutorialLabelStyle() - titleStyle.font = UIFont(name: "Helvetica-Bold", size: 17.0) - titleStyle.color = UIColor.whiteColor() + let titleStyle = ICETutorialLabelStyle() + titleStyle.font = .boldSystemFont(ofSize: 17) + titleStyle.color = .white titleStyle.linesNumber = 1 - titleStyle.offsset = 180 + titleStyle.offset = 180 - var subStyle: ICETutorialLabelStyle = ICETutorialLabelStyle() - subStyle.font = UIFont(name: "Helvetica", size: 15.0) - subStyle.color = UIColor.whiteColor() + let subStyle = ICETutorialLabelStyle() + subStyle.font = .systemFont(ofSize: 15) + subStyle.color = .white subStyle.linesNumber = 1 - subStyle.offsset = 150 - + subStyle.offset = 150 - var listPages: ICETutorialPage[] = [layer1, layer2, layer3, layer4, layer5] + let listPages = [layer1, layer2, layer3, layer4, layer5] - var controller: ICETutorialController = ICETutorialController(pages: listPages) + let controller = ICETutorialController(pages: listPages) controller.commonPageTitleStyle = titleStyle controller.commonPageSubTitleStyle = subStyle controller.startScrolling() - + self.window!.rootViewController = controller self.window!.makeKeyAndVisible() return true } - - func applicationWillResignActive(application: UIApplication) { + + func applicationWillResignActive(_ application: UIApplication) { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. } - - func applicationDidEnterBackground(application: UIApplication) { + + func applicationDidEnterBackground(_ application: UIApplication) { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. } - - func applicationWillEnterForeground(application: UIApplication) { + + func applicationWillEnterForeground(_ application: UIApplication) { // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. } - - func applicationDidBecomeActive(application: UIApplication) { + + func applicationDidBecomeActive(_ application: UIApplication) { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. } - - func applicationWillTerminate(application: UIApplication) { + + func applicationWillTerminate(_ application: UIApplication) { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } - - + + } diff --git a/ICETutorial/Images.xcassets/AppIcon.appiconset/Contents.json b/ICETutorial/Images.xcassets/AppIcon.appiconset/Contents.json index 91bf9c1..9221b9b 100755 --- a/ICETutorial/Images.xcassets/AppIcon.appiconset/Contents.json +++ b/ICETutorial/Images.xcassets/AppIcon.appiconset/Contents.json @@ -2,52 +2,97 @@ "images" : [ { "idiom" : "iphone", - "size" : "29x29", - "scale" : "2x" + "scale" : "2x", + "size" : "20x20" }, { "idiom" : "iphone", - "size" : "40x40", - "scale" : "2x" + "scale" : "3x", + "size" : "20x20" }, { "idiom" : "iphone", - "size" : "60x60", - "scale" : "2x" + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "60x60" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "60x60" }, { "idiom" : "ipad", - "size" : "29x29", - "scale" : "1x" + "scale" : "1x", + "size" : "20x20" }, { "idiom" : "ipad", - "size" : "29x29", - "scale" : "2x" + "scale" : "2x", + "size" : "20x20" }, { "idiom" : "ipad", - "size" : "40x40", - "scale" : "1x" + "scale" : "1x", + "size" : "29x29" }, { "idiom" : "ipad", - "size" : "40x40", - "scale" : "2x" + "scale" : "2x", + "size" : "29x29" }, { "idiom" : "ipad", - "size" : "76x76", - "scale" : "1x" + "scale" : "1x", + "size" : "40x40" }, { "idiom" : "ipad", - "size" : "76x76", - "scale" : "2x" + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "83.5x83.5" + }, + { + "idiom" : "ios-marketing", + "scale" : "1x", + "size" : "1024x1024" } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 } -} \ No newline at end of file +} diff --git a/ICETutorial/Images.xcassets/Contents.json b/ICETutorial/Images.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/ICETutorial/Images.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ICETutorial/Images.xcassets/LaunchImage.launchimage/Contents.json b/ICETutorial/Images.xcassets/LaunchImage.launchimage/Contents.json deleted file mode 100755 index 6f870a4..0000000 --- a/ICETutorial/Images.xcassets/LaunchImage.launchimage/Contents.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "images" : [ - { - "orientation" : "portrait", - "idiom" : "iphone", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "2x" - }, - { - "orientation" : "portrait", - "idiom" : "iphone", - "subtype" : "retina4", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "2x" - }, - { - "orientation" : "portrait", - "idiom" : "ipad", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "1x" - }, - { - "orientation" : "landscape", - "idiom" : "ipad", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "1x" - }, - { - "orientation" : "portrait", - "idiom" : "ipad", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "2x" - }, - { - "orientation" : "landscape", - "idiom" : "ipad", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/ICETutorial/Info.plist b/ICETutorial/Info.plist index 1101fb2..db8641f 100755 --- a/ICETutorial/Info.plist +++ b/ICETutorial/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - Patrick-Trillsam.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -22,6 +22,8 @@ 1 LSRequiresIPhoneOS + UILaunchStoryboardName + Launch Screen UIRequiredDeviceCapabilities armv7 diff --git a/ICETutorial/Launch Screen.storyboard b/ICETutorial/Launch Screen.storyboard new file mode 100644 index 0000000..e4402cd --- /dev/null +++ b/ICETutorial/Launch Screen.storyboard @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ICETutorial/Libraries/ICETutorialController.swift b/ICETutorial/Libraries/ICETutorialController.swift index 7326e3c..e33d2de 100755 --- a/ICETutorial/Libraries/ICETutorialController.swift +++ b/ICETutorial/Libraries/ICETutorialController.swift @@ -10,395 +10,376 @@ import Foundation import UIKit enum ScrollingState : Int { - case Auto - case Manual - case Looping + case auto + case manual + case looping } class ICETutorialController : UIViewController, UIScrollViewDelegate { - - var frontLayerView: UIImageView! - var backLayerView: UIImageView! - var scrollView: UIScrollView! - var pageControl: UIPageControl! - var leftButton: UIButton! - var rightButton: UIButton! - - var overlayLogo: UILabel! - - var currentPageIndex: NSInteger! - var nextPageIndex: NSInteger? - var currentState: ScrollingState? - var windowSize: CGSize? - var pages: ICETutorialPage[]! - var autoScrollEnabled: Bool! + + var frontLayerView = UIImageView() + var backLayerView = UIImageView() + var scrollView = UIScrollView() + var pageControl = UIPageControl() + var leftButton = UIButton() + var rightButton = UIButton() + + var overlayLogo = UILabel() + + var currentPageIndex = 0 + var nextPageIndex = 0 + var currentState = ScrollingState.auto + var pages: [ICETutorialPage] + var autoScrollEnabled = true var commonPageTitleStyle: ICETutorialLabelStyle! var commonPageSubTitleStyle: ICETutorialLabelStyle! - init(pages: ICETutorialPage[]) { - super.init(nibName: nil, bundle: nil) - - self.autoScrollEnabled = true - self.currentPageIndex = 0 - // Auto-scrollDuration + init(pages: [ICETutorialPage]) { self.pages = pages - - self.frontLayerView = UIImageView() - self.backLayerView = UIImageView() - self.scrollView = UIScrollView() - - self.overlayLogo = UILabel() - self.pageControl = UIPageControl() - self.leftButton = UIButton() - self.rightButton = UIButton() + super.init(nibName: nil, bundle: nil) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") } override func viewDidLoad() { super.viewDidLoad() - self.view!.backgroundColor = UIColor.blackColor() + view?.backgroundColor = UIColor.black - self.setupView() - - // Overlays. - self.setOverlayTexts() - self.setOverlayTitle() + setupView() + + // Overlays + setOverlayTexts() + setOverlayTitle() // Preset the origin state. - self.setOriginLayersState() + setOriginLayersState() } func setupView() { - self.frontLayerView!.frame = self.view.bounds - self.backLayerView!.frame = self.view.bounds + frontLayerView.frame = view.bounds + backLayerView.frame = view.bounds - // Decoration. - var gradientView = UIImageView(frame: CGRectMake(0, 368, 320, 200)) + // Decoration + let gradientView = UIImageView(frame: view.bounds) gradientView.image = UIImage(named: "background-gradient.png") - // Title. - self.overlayLogo!.frame = CGRectMake(84, 116, 212, 50) - self.overlayLogo!.textColor = UIColor.whiteColor() - self.overlayLogo!.font = UIFont(name: "Helvetica-Bold", size: 32.0) - - // ScrollView configuration. - self.scrollView!.frame = self.view.bounds - self.scrollView!.delegate = self - self.scrollView!.pagingEnabled = true - self.scrollView!.contentSize = CGSizeMake(5 * 320, self.view.bounds.height) - - // PageControl. - self.pageControl!.frame = CGRectMake(141, 453, 36, 32) - self.pageControl!.numberOfPages = self.numberOfPages() - self.pageControl!.currentPage = 0 - self.pageControl!.addTarget(self, action: "didClickOnPageControl:", forControlEvents: UIControlEvents.ValueChanged) - - // UIButtons. - self.leftButton!.frame = CGRectMake(20, 494, 130, 36) - self.rightButton!.frame = CGRectMake(172, 494, 130, 36) - self.leftButton!.backgroundColor = UIColor.darkGrayColor() - self.rightButton!.backgroundColor = UIColor.darkGrayColor() - self.leftButton!.setTitle("Button 1", forState: UIControlState.Normal) - self.rightButton!.setTitle("Button 2", forState: UIControlState.Normal) - self.leftButton!.addTarget(self, action: "didClickOnButton1:", forControlEvents: UIControlEvents.TouchUpInside) - self.rightButton!.addTarget(self, action: "didClickOnButton2:", forControlEvents: UIControlEvents.TouchUpInside) - - - // Fetch on screen. - self.view.addSubview(self.frontLayerView) - self.view.addSubview(self.backLayerView) - self.view.addSubview(gradientView) - self.view.addSubview(self.scrollView) - self.view.addSubview(self.overlayLogo) - self.view.addSubview(self.pageControl) - self.view.addSubview(self.leftButton) - self.view.addSubview(self.rightButton) + // Title + overlayLogo.frame = CGRect.init(origin: CGPoint.init(x: 0, y: 40), size: CGSize.init(width: view.bounds.size.width, height: 40)) + overlayLogo.textColor = .white + overlayLogo.textAlignment = .center + overlayLogo.font = .boldSystemFont(ofSize: 32) + + // ScrollView configuration + scrollView.frame = view.bounds + scrollView.delegate = self + scrollView.isPagingEnabled = true + scrollView.contentSize = CGSize(width: CGFloat(pages.count) * view.bounds.width, height: view.bounds.height) + + // PageControl + var rect = CGRect.zero + rect.size.width = CGFloat(pages.count) * 8.0 + rect.size.height = 32 + rect.origin.x = (view.bounds.size.width - rect.size.width) / 2.0 + rect.origin.y = view.bounds.size.height - 120 + pageControl.frame = rect + pageControl.numberOfPages = pages.count + pageControl.currentPage = 0 + pageControl.addTarget(self, action: #selector(didClickOnPageControl(sender:)), for: UIControl.Event.valueChanged) + + // UIButtons + rect.size.width = 130 + rect.size.height = 36 + rect.origin.x = 30 + rect.origin.y = view.bounds.size.height - 80.0 + leftButton.frame = rect + rect.origin.x = view.bounds.size.width - rect.size.width - rect.origin.x + rightButton.frame = rect + leftButton.backgroundColor = .darkGray + rightButton.backgroundColor = .darkGray + leftButton.setTitle("Button 1", for: .normal) + rightButton.setTitle("Button 2", for: .normal) + leftButton.addTarget(self, action: #selector(didClickOnButton1(sender:)), for: .touchUpInside) + rightButton.addTarget(self, action: #selector(didClickOnButton2(sender:)), for: .touchUpInside) + + // Fetch on screen + view.addSubview(frontLayerView) + view.addSubview(backLayerView) + view.addSubview(gradientView) + view.addSubview(scrollView) + view.addSubview(overlayLogo) + view.addSubview(pageControl) + view.addSubview(leftButton) + view.addSubview(rightButton) } - func didClickOnButton1(sender: UIButton) { + @objc func didClickOnButton1(sender: UIButton) { } - func didClickOnButton2(sender: UIButton) { + @objc func didClickOnButton2(sender: UIButton) { } - func didClickOnPageControl(sender: UIPageControl) { - self.stopScrolling() + @objc func didClickOnPageControl(sender: UIPageControl) { + stopScrolling() - // Make the scrollView animation. - self.scrollToNextPageIndex(sender.currentPage) + // Make the scrollView animation + scrollToNextPageIndex(nextPageIndex: sender.currentPage) } - // Set the list of pages (ICETutorialPage). - func setPages(pages: ICETutorialPage[] ) { + // Set the list of pages (ICETutorialPage) + func setPages(pages: [ICETutorialPage] ) { self.pages = pages } - func numberOfPages() -> Int { - if (self.pages) { - return self.pages!.count - } - return 0 - } - - func animateScrolling() { - if (self.currentState == ScrollingState.Manual) { + @objc func animateScrolling() { + if (currentState == ScrollingState.manual) { return; } // Jump to the next page... - var nextPage: Int = self.currentPageIndex! + 1 - if (nextPage == self.numberOfPages()) { + var nextPage = currentPageIndex + 1 + if (nextPage == pages.count) { // ...stop the auto-scrolling or... - if (!self.autoScrollEnabled) { - self.currentState = ScrollingState.Manual + if (!autoScrollEnabled) { + currentState = ScrollingState.manual return; } // ...jump to the first page. nextPage = 0 - self.currentState = ScrollingState.Looping + currentState = ScrollingState.looping // Set alpha on layers. - self.setOriginLayerAlpha() - self.setBackLayerPictureWithPageIndex(-1) + setOriginLayerAlpha() + setBackLayerPictureWithPageIndex(index: -1) } else { - self.currentState = ScrollingState.Auto + currentState = ScrollingState.auto } // Make the scrollView animation. - var nextPagePosition: Float = Float(nextPage) * 320 - self.scrollView!.setContentOffset(CGPointMake(nextPagePosition, 0), animated: true) + let nextPagePosition = CGFloat(nextPage) * view.frame.size.width + scrollView.setContentOffset(CGPoint(x: nextPagePosition, y: 0), animated: true) // Set the PageControl on the right page. - self.pageControl!.currentPage = nextPage + pageControl.currentPage = nextPage // Call the next animation after X seconds. - self.autoScrollToNextPage() + autoScrollToNextPage() } func autoScrollToNextPage() { - let page: ICETutorialPage = self.pages[self.currentPageIndex!] - - if (self.autoScrollEnabled) { - NSTimer.scheduledTimerWithTimeInterval(page.duration!, target: self, selector: Selector("animateScrolling"), userInfo: nil, repeats: false) + if (autoScrollEnabled) { + Timer.scheduledTimer(timeInterval: pages[currentPageIndex].duration!, target: self, selector: #selector(animateScrolling), userInfo: nil, repeats: false) } } func scrollToNextPageIndex(nextPageIndex: NSInteger) { // Make the scrollView animation. - self.scrollView!.setContentOffset(CGPointMake(Float(nextPageIndex) * self.view.frame.size.width,0), animated: true) + scrollView.setContentOffset(CGPoint(x: CGFloat(nextPageIndex) * view.frame.size.width, y: 0), animated: true) // Set the PageControl on the right page. - self.pageControl!.currentPage = nextPageIndex + pageControl.currentPage = nextPageIndex } // Run it. func startScrolling() { - self.autoScrollToNextPage() + autoScrollToNextPage() } // Manually stop the scrolling func stopScrolling() { - self.currentState = ScrollingState.Manual - } - - // State. - func getCurrentState() -> ScrollingState { - return self.currentState! + currentState = ScrollingState.manual } // Setup the Title Label. func setOverlayTitle() { - self.overlayLogo!.text = "Welcome" + overlayLogo.text = "Welcome" } // Setup the Title/Subtitle style/text. func setOverlayTexts() { var index: Int = 0 - for page in self.pages! { - if (page.title.text) { - var title: UILabel = self.overlayLabelWithText(page.title.text!, style: page.title!, commonStyle: self.commonPageTitleStyle, index: index) - self.scrollView!.addSubview(title) - } - if (page.subTitle.text) { - var subTitle: UILabel = self.overlayLabelWithText(page.subTitle.text!, style: page.subTitle!, commonStyle: self.commonPageSubTitleStyle!, index: index) - self.scrollView!.addSubview(subTitle) - } - index++ + for page in pages { + let title = overlayLabelWithText(text: page.title.text!, style: page.title!, commonStyle: commonPageTitleStyle, index: index) + scrollView.addSubview(title) + let subTitle = overlayLabelWithText(text: page.subTitle.text!, style: page.subTitle!, commonStyle: commonPageSubTitleStyle!, index: index) + scrollView.addSubview(subTitle) + index += 1 } } - func overlayLabelWithText(text: NSString, style: ICETutorialLabelStyle, commonStyle: ICETutorialLabelStyle, index: NSInteger) -> UILabel { - var position: CGFloat = (CGFloat)(index * 320) - var positionY: CGFloat = (CGFloat)(540 - commonStyle.offsset) - var overlayLabel: UILabel = UILabel() - overlayLabel.frame = CGRectMake(position, positionY, 320, 34) + func overlayLabelWithText(text: String, style: ICETutorialLabelStyle, commonStyle: ICETutorialLabelStyle, index: Int) -> UILabel { + let position = CGFloat(index) * view.bounds.size.width + let positionY = view.bounds.size.height - commonStyle.offset + let overlayLabel = UILabel() + overlayLabel.frame = CGRect(x: position, y: positionY, width: view.bounds.size.width, height: 34) // SubTitles. - overlayLabel.setTranslatesAutoresizingMaskIntoConstraints(false) + overlayLabel.translatesAutoresizingMaskIntoConstraints = false overlayLabel.numberOfLines = commonStyle.linesNumber - overlayLabel.backgroundColor = UIColor.clearColor() - overlayLabel.textAlignment = NSTextAlignment.Center - + overlayLabel.backgroundColor = .clear + overlayLabel.textAlignment = .center + // Datas and style. - overlayLabel.text = text - if (style.font) { + overlayLabel.text = text as String + overlayLabel.font = commonStyle.font + if (style.font != commonStyle.font) { overlayLabel.font = style.font - } else { - overlayLabel.font = commonStyle.font } - if (style.color) { + overlayLabel.textColor = commonStyle.color + if (style.color != commonStyle.color) { overlayLabel.textColor = style.color - } else { - overlayLabel.textColor = commonStyle.color } - + return overlayLabel } // Handle the background layer image switch. func setBackLayerPictureWithPageIndex(index: NSInteger) { - self.setBackgroundImage(self.backLayerView!, pageIndex: index + 1) + setBackgroundImage(imageView: backLayerView, pageIndex: index + 1) } // Handle the front layer image switch. func setFrontLayerPictureWithPageIndex(index: NSInteger) { - self.setBackgroundImage(self.frontLayerView!, pageIndex: index) + setBackgroundImage(imageView: frontLayerView, pageIndex: index) } // Handle page image's loading func setBackgroundImage(imageView: UIImageView, pageIndex: NSInteger) { - if (pageIndex >= self.pages!.count) { + if (pageIndex >= pages.count) { imageView.image = nil return } - let page: ICETutorialPage = self.pages[pageIndex] + let page: ICETutorialPage = pages[pageIndex] imageView.image = UIImage(named: page.pictureName!) } // Setup layer's alpha. func setOriginLayerAlpha() { - self.frontLayerView!.alpha = 1 - self.backLayerView!.alpha = 0 + frontLayerView.alpha = 1 + backLayerView.alpha = 0 } // Preset the origin state. func setOriginLayersState() { - self.currentState = ScrollingState.Auto - self.backLayerView!.backgroundColor = UIColor.blackColor() - self.frontLayerView!.backgroundColor = UIColor.blackColor() - self.setLayersPicturesWithIndex(0) + currentState = ScrollingState.auto + backLayerView.backgroundColor = .black + frontLayerView.backgroundColor = .black + setLayersPicturesWithIndex(index: 0) } - + // Setup the layers with the page index. func setLayersPicturesWithIndex(index: NSInteger) { - self.currentPageIndex = index - self.setOriginLayerAlpha() - self.setFrontLayerPictureWithPageIndex(index) - self.setBackLayerPictureWithPageIndex(index) + currentPageIndex = index + setOriginLayerAlpha() + setFrontLayerPictureWithPageIndex(index: index) + setBackLayerPictureWithPageIndex(index: index) } // Animate the fade-in/out (Cross-disolve) with the scrollView translation. - func disolveBackgroundWithContentOffset(offset: Float) { - if (self.currentState == ScrollingState.Looping) { + func disolveBackgroundWithContentOffset(offset: CGFloat) { + if (currentState == ScrollingState.looping) { // Jump from the last page to the first. - self.scrollingToFirstPageWithOffset(offset) + scrollingToFirstPageWithOffset(offset: offset) } else { // Or just scroll to the next/previous page. - self.scrollingToNextPageWithOffset(offset) + scrollingToNextPageWithOffset(offset: offset) } } // Handle alpha on layers when the auto-scrolling is looping to the first page. - func scrollingToFirstPageWithOffset(offset: Float) { + func scrollingToFirstPageWithOffset(offset: CGFloat) { // Compute the scrolling percentage on all the page. - let offsetX: Float = (offset * 320) - let numberOfPage: Float = 5 - let offsetY: Float = (320 * numberOfPage) - let finalOffset: Float = offsetX / offsetY + let offsetX = offset * view.bounds.size.width + let numberOfPage = CGFloat(pages.count) + let offsetY = view.bounds.size.width * numberOfPage + let finalOffset = offsetX / offsetY // Scrolling finished... - if (offset == 0) { - self.setOriginLayersState() + if (finalOffset == 0) { + setOriginLayersState() return } // Invert alpha for the back picture. - var backLayerAlpha: Float = (1 - offset) - var frontLayerAlpha: Float = offset + let backLayerAlpha = 1.0 - finalOffset + let frontLayerAlpha = finalOffset // Set alpha. - self.backLayerView!.alpha = backLayerAlpha - self.frontLayerView!.alpha = frontLayerAlpha + backLayerView.alpha = backLayerAlpha + frontLayerView.alpha = frontLayerAlpha } // Handle alpha on layers when we are scrolling to the next/previous page. - func scrollingToNextPageWithOffset(offset: Float) { + func scrollingToNextPageWithOffset(offset: CGFloat) { // Current page index in scrolling. - var page: Int = Int(offset) + let page: Int = Int(offset) // Keep only the float value. - var alphaValue: Float = offset - Float(Int(offset)); + let alphaValue = offset - CGFloat(Int(offset)); // This is only when you scroll to the right on the first page. // That will fade-in black the first picture. - if (alphaValue < 0 && self.currentPageIndex == 0) { - self.backLayerView!.image = nil - self.frontLayerView!.alpha = (1 + alphaValue) + if (alphaValue < 0 && currentPageIndex == 0) { + backLayerView.image = nil + frontLayerView.alpha = 1.0 + alphaValue return } // Switch pictures, and imageView alpha. - if (page != self.currentPageIndex || - (page == self.currentPageIndex && 0.0 < offset && offset < 1.0)) { - self.setLayersPicturesWithIndex(page) + if (page != currentPageIndex || + (page == currentPageIndex && 0.0 < offset && offset < 1.0)) { + setLayersPicturesWithIndex(index: page) } // Invert alpha for the front picture. - var backLayerAlpha: Float = alphaValue - var frontLayerAlpha: Float = (1 - alphaValue) + let backLayerAlpha = alphaValue + let frontLayerAlpha = 1.0 - alphaValue // Set alpha. - self.backLayerView!.alpha = backLayerAlpha - self.frontLayerView!.alpha = frontLayerAlpha + backLayerView.alpha = backLayerAlpha + frontLayerView.alpha = frontLayerAlpha } - - func scrollViewDidScroll(scrollView: UIScrollView!) { + + func scrollViewDidScroll(_ scrollView: UIScrollView) { // Get scrolling position, and nextPageindex. - var scrollingPosition: Float = self.scrollView!.contentOffset.x / 320.0 - var nextPageIndex: Int = Int(scrollingPosition) + let scrollingPosition = scrollView.contentOffset.x / view.bounds.size.width + var nextPageIndex = Int(scrollingPosition) // If we are looping, we reset the indexPage. - if (self.currentState == ScrollingState.Looping) { + if (currentState == ScrollingState.looping) { nextPageIndex = 0 } // If we are going to the next page, let's call the delegate. - if (nextPageIndex != self.nextPageIndex) { + if (self.nextPageIndex != nextPageIndex) { // DELEGATE self.nextPageIndex = nextPageIndex } // Delegate when we reach the end. - if (self.nextPageIndex == self.numberOfPages() - 1) { + if (nextPageIndex == pages.count - 1) { // DELEGATE } // Animate. - self.disolveBackgroundWithContentOffset(scrollingPosition) + disolveBackgroundWithContentOffset(offset: scrollingPosition) } - func scrollViewWillBeginDragging(scrollView: UIScrollView!) { + func scrollViewWillBeginDragging(_ scrollView: UIScrollView) { // At the first user interaction, we disable the auto scrolling. - if (self.scrollView!.tracking) { - self.stopScrolling() + if (scrollView.isTracking) { + stopScrolling() } } - func scrollViewDidEndDecelerating(scrollView: UIScrollView!) { + func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { // Update the page index. - self.pageControl!.currentPage = self.currentPageIndex!; + pageControl.currentPage = currentPageIndex; } -} \ No newline at end of file + +} diff --git a/ICETutorial/Libraries/ICETutorialPage.swift b/ICETutorial/Libraries/ICETutorialPage.swift index fa6a93b..26981f6 100755 --- a/ICETutorial/Libraries/ICETutorialPage.swift +++ b/ICETutorial/Libraries/ICETutorialPage.swift @@ -9,18 +9,16 @@ import Foundation import UIKit -class ICETutorialLabelStyle : NSObject { +class ICETutorialLabelStyle { var text: String? - var font: UIFont? - var color: UIColor? - var linesNumber: Int = 0 - var offsset: Int = 0 + var font = UIFont.systemFont(ofSize: 17) + var color = UIColor.white + var linesNumber = 0 + var offset: CGFloat = 0 + + init() {} - init() { - super.init() - } - init(text: String) { self.text = text } @@ -30,17 +28,18 @@ class ICETutorialLabelStyle : NSObject { self.font = font self.color = color } + } -class ICETutorialPage : NSObject { +class ICETutorialPage { var title: ICETutorialLabelStyle! var subTitle: ICETutorialLabelStyle! var pictureName: String? - var duration: NSTimeInterval? + var duration: TimeInterval? - init(title: String, subTitle: NSString, pictureName: String, duration: NSTimeInterval) { + init(title: String, subTitle: String, pictureName: String, duration: TimeInterval) { self.title = ICETutorialLabelStyle(text: title) self.subTitle = ICETutorialLabelStyle(text: subTitle) self.pictureName = pictureName @@ -54,4 +53,5 @@ class ICETutorialPage : NSObject { func setTitleStyle(style: ICETutorialLabelStyle) { self.title = style } -} \ No newline at end of file + +} diff --git a/ICETutorialTests/ICETutorialTests.swift b/ICETutorialTests/ICETutorialTests.swift index 92fa904..80d3b07 100755 --- a/ICETutorialTests/ICETutorialTests.swift +++ b/ICETutorialTests/ICETutorialTests.swift @@ -27,7 +27,7 @@ class ICETutorialTests: XCTestCase { func testPerformanceExample() { // This is an example of a performance test case. - self.measureBlock() { + self.measure() { // Put the code you want to measure the time of here. } } diff --git a/ICETutorialTests/Info.plist b/ICETutorialTests/Info.plist index 1cc7f6e..6d32c15 100755 --- a/ICETutorialTests/Info.plist +++ b/ICETutorialTests/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - Patrick-Trillsam.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/Resources/Default-568h@2x.png b/Resources/Default-568h@2x.png deleted file mode 100755 index 0891b7aabfcf3422423b109c8beed2bab838c607..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18594 zcmeI4X;f257Jx&9fS`ixvS;&$x8J@slQFSel)6zJN=?13FB7H(lQjRkSy8x_-S~tvu2gzn1oS+dLcF#eqtq$ z%tf9TTvX?`)R@}3uBI;jzS-=ZR-Td&MHaS&;!0?Ni*#$#`n*~CcQK)Q9vAQ~TUpnI!j)a2biYK^R)M~A5wUDZhx?ULMX z3x1P&qt=trOY6P2U67L=m=U?F|5#Uj(eCueNTZaHs_ceWiHeET+j+tp3Jt9g(ekqP z2WOvfR{qV+9r+o4J5?qK>7;;^+I7tGv-i)es$X_D=EoKF+S?zsyj^oRFElP}c}JT< zd8SUs-?O?}2YD#ngKbnHgzHBcboxK_2r9l(?eNCl-pEzkJm}fY?WC*jnS?VBE4EpY zO$fEejz6fU;W2Kl>JeQBZBl-%Irg`obSlg*@4QB;Dd1H7^Oi5wvt4d{RZ!8Og?^aE z)k0$1g+V3fd(gdQ3d&q2q-FL*uy#}|bc^=VhFsl0jBgUGJ+-s3U8MK9A!YJJMxpci z5hJ%|{DwV48fZn0{n5l$N_KcSb#NKE4plB`9I6Zt=Z!~-zw0{9tg$L&Ju1F0X)Cy8 zKF;(&lJ>x)Jw(=;p~sF(Sd9VWGwFE2rnyS9!f^DZ8+aCLq zQ};>lcJ1GDLqjm6Hd>|Eabno@P`~Bn(~6^aD_#yoEH(a?Nm1S<;S+hSxI5d16^<1lEM3NPFi zkqPrpL)+ zgnseFikg`gJVBha1&7C4;O6>h=dt~`ND+;Zd?W(4v2JIb7Pt>Td42%M-Ju-XAH#Pns762L}K3 zDhvsRqN0Ni(1UrishD2YvV?4*h2iFj$+&N||Fn$4n|^NSU+o?~jq`0jVQt8T9l{7b zXiwwODFh2V!Q6sqP9S>WH$oOf$N~=d0-bqTlD61!=`&0eAP-F>XN?*|gtOXX{ zQVTWyYo4ZK0GAw!GHf|pz9`D;-bbb*5LBX*{bnz|+)$@&P9|ORM2o?95{;ejvo&r- zq8cBhTN6nn)7~W>54U)%-F_-b?YKdfk5I8MHcuzBD5)!;yv#Z&R&^y=@=>VTIMy#r zX&U<=BsPkdqcMe<_}2+>H%XKyrr5ZR8_KVe>ZqYN z^=^~TFD};;rHJ$U;{~w^hYojl4hRI@SH$^K{YEo=sg)WY87r!*7blQK&qnpDo0`Vn zkl)9u9g=mCh&ZCJS(L4yN3k0kQ zuvg$h2KEEk51T+O0JQ+r0`R>g{jvqM0Mr6d3qUOZwE!?PI7HY@CE|dr sfw?Q;rAv?G4&^^8-z_>&sWXMxvD*gPOU4CBe-*@OtE+wfmVJNyHv)PfH~;_u diff --git a/Resources/Default.png b/Resources/Default.png deleted file mode 100755 index 4c8ca6f693f96d511e9113c0eb59eec552354e42..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6540 zcmeAS@N?(olHy`uVBq!ia0y~yU~~ZD2OMlbkt;o0To@QwR5G2N13aCb6#|O#(=u~X z85k@CTSM>X-wqM6>&y>YB4)1;;ojbLbbV-W^iFB1wa3^zCog^LCAReC4K0-?R_2{6 zrP*)4+_uWUy3w5N52M3PW_}MFMP9a~>YLvVZ1D_k*IMQ2QT^fwzoOb(*3gH$%aYWC zkHmcab=va2<#X%jakpJ;<1@F;k__#bwtC&%^D0v(FBh9K&$sK+<}2RJS609D)17$w ztdQP8(eLM8Ka}m_IQ@3wyMKP)l=oM4-?`YS_*P?4V_ORLPxsj&7Ju#kH;>6^Kp?T7~ zl+q?{UOOqV==?+d{=)5s|M~T1mwtH@+Z^$G&eEO9JNP^AX@3jZ*J*!!>lc|1-W%fA z@AOQpXZ_Lt>rxFXrGp*zLPiW@uo_c7C{As>j zWeX)wi+LTp_)@KYZCX{j;H?|1yXT4DnlS(Fr8gyP5|uaX_gLvaW0ScZdnG7o+u{T6 zFI-%d{ls*WuCDa5UJ@|RXv&ejZe}*BMkiWY51&pnRPw(hlykSzvj6e%mYz-GdvzBD zF10?szF_~!jS=?2HyQuPCvARXAe}C}WP|yQ*>5~~=*Nxq8+HHW1~FMDRCP^TcacKuk$ z(U#REVv)D!PhJ*ecH-ELFUrfyV&*)Z)>UCOuS?yd^L@Afk>ihynYPc{^CRwu+JHX+#$@YsC4c|l0tGigsn@jy) zXD($Ouk>H+V(Mr6NQT0S9BFM~V6nkj;1OBOz`zY;a|<&v%$g$sEJPk;hD4M^`1)8S z=jZArrsOB3>Q&?x097+E*i={nnYpPYi3%0DIeEoa6}C!X6;?ntNLXJ<0j#7X+g2&U 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 diff --git a/Resources/button-background.png b/Resources/button-background.png deleted file mode 100755 index a8286f2ac33463c216dc018a6c80a6ba5ed4f8d9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6364 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 PKZBzruLdfYGY|PMd#PAu diff --git a/Resources/button-background@2x.png b/Resources/button-background@2x.png deleted file mode 100755 index 9d8b78a8f6b2d755f5264956460d7d56eb29f7ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6708 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