├── .DS_Store
├── Resources
├── Default.png
├── Default@2x.png
├── Default-568h@2x.png
├── button-background.png
├── background-gradient.png
├── button-background@2x.png
├── background-gradient@2x.png
├── tutorial_background_00@2x.jpg
├── tutorial_background_01@2x.jpg
├── tutorial_background_02@2x.jpg
├── tutorial_background_03@2x.jpg
└── tutorial_background_04@2x.jpg
├── .gitignore
├── ICETutorialTests
├── Info.plist
└── ICETutorialTests.swift
├── ICETutorial
├── Info.plist
├── Images.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ └── LaunchImage.launchimage
│ │ └── Contents.json
├── Libraries
│ ├── ICETutorialPage.swift
│ └── ICETutorialController.swift
└── AppDelegate.swift
├── README.md
└── ICETutorial.xcodeproj
└── project.pbxproj
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/icepat/ICETutorialSwift/HEAD/.DS_Store
--------------------------------------------------------------------------------
/Resources/Default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/icepat/ICETutorialSwift/HEAD/Resources/Default.png
--------------------------------------------------------------------------------
/Resources/Default@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/icepat/ICETutorialSwift/HEAD/Resources/Default@2x.png
--------------------------------------------------------------------------------
/Resources/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/icepat/ICETutorialSwift/HEAD/Resources/Default-568h@2x.png
--------------------------------------------------------------------------------
/Resources/button-background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/icepat/ICETutorialSwift/HEAD/Resources/button-background.png
--------------------------------------------------------------------------------
/Resources/background-gradient.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/icepat/ICETutorialSwift/HEAD/Resources/background-gradient.png
--------------------------------------------------------------------------------
/Resources/button-background@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/icepat/ICETutorialSwift/HEAD/Resources/button-background@2x.png
--------------------------------------------------------------------------------
/Resources/background-gradient@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/icepat/ICETutorialSwift/HEAD/Resources/background-gradient@2x.png
--------------------------------------------------------------------------------
/Resources/tutorial_background_00@2x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/icepat/ICETutorialSwift/HEAD/Resources/tutorial_background_00@2x.jpg
--------------------------------------------------------------------------------
/Resources/tutorial_background_01@2x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/icepat/ICETutorialSwift/HEAD/Resources/tutorial_background_01@2x.jpg
--------------------------------------------------------------------------------
/Resources/tutorial_background_02@2x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/icepat/ICETutorialSwift/HEAD/Resources/tutorial_background_02@2x.jpg
--------------------------------------------------------------------------------
/Resources/tutorial_background_03@2x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/icepat/ICETutorialSwift/HEAD/Resources/tutorial_background_03@2x.jpg
--------------------------------------------------------------------------------
/Resources/tutorial_background_04@2x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/icepat/ICETutorialSwift/HEAD/Resources/tutorial_background_04@2x.jpg
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | *.xcworkspacedata
3 |
4 | *.xcuserstate
5 |
6 | *.xcsettings
7 |
8 | *.xcbkptlist
9 |
10 | *.xcscheme
11 |
12 | ICETutorial.xcodeproj/xcuserdata/patrick.trillsam.xcuserdatad/xcschemes/xcschememanagement.plist
13 |
14 | ICETutorial.xcodeproj/xcuserdata/patrick.trillsam.xcuserdatad/xcschemes/ICETutorialSwift.xcscheme
15 |
16 | ICETutorial.xcodeproj/xcuserdata/patrick.trillsam.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
17 |
18 | ICETutorial.xcodeproj/project.xcworkspace/xcuserdata/patrick.trillsam.xcuserdatad/WorkspaceSettings.xcsettings
19 |
20 | ICETutorial.xcodeproj/project.xcworkspace/xcuserdata/patrick.trillsam.xcuserdatad/UserInterfaceState.xcuserstate
21 |
22 | ICETutorial.xcodeproj/project.xcworkspace/contents.xcworkspacedata
23 |
--------------------------------------------------------------------------------
/ICETutorialTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | Patrick-Trillsam.${PRODUCT_NAME:rfc1034identifier}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ${PRODUCT_NAME}
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/ICETutorial/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | Patrick-Trillsam.${PRODUCT_NAME:rfc1034identifier}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ${PRODUCT_NAME}
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UIRequiredDeviceCapabilities
26 |
27 | armv7
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/ICETutorialTests/ICETutorialTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ICETutorialTests.swift
3 | // ICETutorialTests
4 | //
5 | // Created by Patrick Trillsam on 5/06/2014.
6 | // Copyright (c) 2014 Patrick Trillsam. All rights reserved.
7 | //
8 |
9 | import XCTest
10 |
11 | class ICETutorialTests: XCTestCase {
12 |
13 | override func setUp() {
14 | super.setUp()
15 | // Put setup code here. This method is called before the invocation of each test method in the class.
16 | }
17 |
18 | override func tearDown() {
19 | // Put teardown code here. This method is called after the invocation of each test method in the class.
20 | super.tearDown()
21 | }
22 |
23 | func testExample() {
24 | // This is an example of a functional test case.
25 | XCTAssert(true, "Pass")
26 | }
27 |
28 | func testPerformanceExample() {
29 | // This is an example of a performance test case.
30 | self.measureBlock() {
31 | // Put the code you want to measure the time of here.
32 | }
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/ICETutorial/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "40x40",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "60x60",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "ipad",
20 | "size" : "29x29",
21 | "scale" : "1x"
22 | },
23 | {
24 | "idiom" : "ipad",
25 | "size" : "29x29",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "ipad",
30 | "size" : "40x40",
31 | "scale" : "1x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "40x40",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "76x76",
41 | "scale" : "1x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "76x76",
46 | "scale" : "2x"
47 | }
48 | ],
49 | "info" : {
50 | "version" : 1,
51 | "author" : "xcode"
52 | }
53 | }
--------------------------------------------------------------------------------
/ICETutorial/Images.xcassets/LaunchImage.launchimage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "orientation" : "portrait",
5 | "idiom" : "iphone",
6 | "extent" : "full-screen",
7 | "minimum-system-version" : "7.0",
8 | "scale" : "2x"
9 | },
10 | {
11 | "orientation" : "portrait",
12 | "idiom" : "iphone",
13 | "subtype" : "retina4",
14 | "extent" : "full-screen",
15 | "minimum-system-version" : "7.0",
16 | "scale" : "2x"
17 | },
18 | {
19 | "orientation" : "portrait",
20 | "idiom" : "ipad",
21 | "extent" : "full-screen",
22 | "minimum-system-version" : "7.0",
23 | "scale" : "1x"
24 | },
25 | {
26 | "orientation" : "landscape",
27 | "idiom" : "ipad",
28 | "extent" : "full-screen",
29 | "minimum-system-version" : "7.0",
30 | "scale" : "1x"
31 | },
32 | {
33 | "orientation" : "portrait",
34 | "idiom" : "ipad",
35 | "extent" : "full-screen",
36 | "minimum-system-version" : "7.0",
37 | "scale" : "2x"
38 | },
39 | {
40 | "orientation" : "landscape",
41 | "idiom" : "ipad",
42 | "extent" : "full-screen",
43 | "minimum-system-version" : "7.0",
44 | "scale" : "2x"
45 | }
46 | ],
47 | "info" : {
48 | "version" : 1,
49 | "author" : "xcode"
50 | }
51 | }
--------------------------------------------------------------------------------
/ICETutorial/Libraries/ICETutorialPage.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ICETutorialPage.swift
3 | // ICETutorial
4 | //
5 | // Created by Patrick Trillsam on 5/06/2014.
6 | // Copyright (c) 2014 Patrick Trillsam. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | class ICETutorialLabelStyle : NSObject {
13 |
14 | var text: String?
15 | var font: UIFont?
16 | var color: UIColor?
17 | var linesNumber: Int = 0
18 | var offsset: Int = 0
19 |
20 | init() {
21 | super.init()
22 | }
23 |
24 | init(text: String) {
25 | self.text = text
26 | }
27 |
28 | init(text: String, font: UIFont, color: UIColor) {
29 | self.text = text
30 | self.font = font
31 | self.color = color
32 | }
33 | }
34 |
35 |
36 | class ICETutorialPage : NSObject {
37 |
38 | var title: ICETutorialLabelStyle!
39 | var subTitle: ICETutorialLabelStyle!
40 | var pictureName: String?
41 | var duration: NSTimeInterval?
42 |
43 | init(title: String, subTitle: NSString, pictureName: String, duration: NSTimeInterval) {
44 | self.title = ICETutorialLabelStyle(text: title)
45 | self.subTitle = ICETutorialLabelStyle(text: subTitle)
46 | self.pictureName = pictureName
47 | self.duration = duration
48 | }
49 |
50 | func setSubTitleStyle(style: ICETutorialLabelStyle) {
51 | self.subTitle = style
52 | }
53 |
54 | func setTitleStyle(style: ICETutorialLabelStyle) {
55 | self.title = style
56 | }
57 | }
--------------------------------------------------------------------------------
/ICETutorial/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // ICETutorial
4 | //
5 | // Created by Patrick Trillsam on 5/06/2014.
6 | // Copyright (c) 2014 Patrick Trillsam. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
17 | self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
18 | // Override point for customization after application launch.
19 | self.window!.backgroundColor = UIColor.whiteColor()
20 |
21 | // Init the pages texts, and pictures.
22 | var layer1: ICETutorialPage = ICETutorialPage(title: "Picture 1", subTitle: "Champs-Elysées by night", pictureName: "tutorial_background_00@2x.jpg", duration: 3.0)
23 | var layer2: ICETutorialPage = ICETutorialPage(title: "Picture 2", subTitle: "The Eiffel Tower with\n cloudy weather", pictureName: "tutorial_background_01@2x.jpg", duration: 3.0)
24 | var layer3: ICETutorialPage = ICETutorialPage(title: "Picture 3", subTitle: "An other famous street of Paris", pictureName: "tutorial_background_02@2x.jpg", duration: 3.0)
25 | var layer4: ICETutorialPage = ICETutorialPage(title: "Picture 4", subTitle: "The Eiffel Tower with a better weather", pictureName: "tutorial_background_03@2x.jpg", duration: 3.0)
26 | var layer5: ICETutorialPage = ICETutorialPage(title: "Picture 5", subTitle: "The Louvre's Museum Pyramide", pictureName: "tutorial_background_04@2x.jpg", duration: 3.0)
27 |
28 | // Set the common style for SubTitles and Description (can be overrided on each page).
29 | var titleStyle: ICETutorialLabelStyle = ICETutorialLabelStyle()
30 | titleStyle.font = UIFont(name: "Helvetica-Bold", size: 17.0)
31 | titleStyle.color = UIColor.whiteColor()
32 | titleStyle.linesNumber = 1
33 | titleStyle.offsset = 180
34 |
35 | var subStyle: ICETutorialLabelStyle = ICETutorialLabelStyle()
36 | subStyle.font = UIFont(name: "Helvetica", size: 15.0)
37 | subStyle.color = UIColor.whiteColor()
38 | subStyle.linesNumber = 1
39 | subStyle.offsset = 150
40 |
41 |
42 | var listPages: ICETutorialPage[] = [layer1, layer2, layer3, layer4, layer5]
43 |
44 | var controller: ICETutorialController = ICETutorialController(pages: listPages)
45 | controller.commonPageTitleStyle = titleStyle
46 | controller.commonPageSubTitleStyle = subStyle
47 | controller.startScrolling()
48 |
49 | self.window!.rootViewController = controller
50 | self.window!.makeKeyAndVisible()
51 | return true
52 | }
53 |
54 | func applicationWillResignActive(application: UIApplication) {
55 | // 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.
56 | // 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.
57 | }
58 |
59 | func applicationDidEnterBackground(application: UIApplication) {
60 | // 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.
61 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
62 | }
63 |
64 | func applicationWillEnterForeground(application: UIApplication) {
65 | // 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.
66 | }
67 |
68 | func applicationDidBecomeActive(application: UIApplication) {
69 | // 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.
70 | }
71 |
72 | func applicationWillTerminate(application: UIApplication) {
73 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
74 | }
75 |
76 |
77 | }
78 |
79 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ICETutorialSwift
2 | ================
3 |
4 | ### Welcome to ICETutorial (Swfit edition).
5 | This small project is an implementation of the newly tutorial introduced by the Path 3.X app, ported to Swift.
6 | Very simple and efficient tutorial, composed with N full-screen pictures that you can swipe for switching to the next/previous page.
7 |
8 | Here are the features :
9 | * Compose your own tutorial with N pictures
10 | * Fixed incrusted title (can be easily replaced by an UIImageView, or just removed)
11 | * Scrolling sub-titles for page, with associated descriptions (change the texts, font, color...)
12 | * Auto-scrolling (enable/disable, loop, setup duration for each pages)
13 | * Cross fade between next/previous background
14 | * Full delegate support available (for scrolling and button interactions)
15 |
16 | 
17 |
18 | ### Setting-up the ICETutorial
19 | The code is commented, and I guess, easy to read/understand/modify.
20 | All the available settings for the scrolling are located in the header : ICETutorial.h :
21 |
22 | **Pages configuration :**
23 | ```swift
24 | // Init the pages texts, and pictures.
25 | let layer1: ICETutorialPage = ICETutorialPage(title: "Picture 1", subTitle: "Champs-Elysées by night", pictureName: "tutorial_background_00@2x.jpg", duration: 3.0)
26 | let layer2: ICETutorialPage = ICETutorialPage(title: "Picture 2", subTitle: "The Eiffel Tower with\n cloudy weather", pictureName: "tutorial_background_01@2x.jpg", duration: 3.0)
27 | let layer3: ICETutorialPage = ICETutorialPage(title: "Picture 3", subTitle: "An other famous street of Paris", pictureName: "tutorial_background_02@2x.jpg", duration: 3.0)
28 | let layer4: ICETutorialPage = ICETutorialPage(title: "Picture 4", subTitle: "The Eiffel Tower with a better weather", pictureName: "tutorial_background_03@2x.jpg", duration: 3.0)
29 | let layer5: ICETutorialPage = ICETutorialPage(title: "Picture 5", subTitle: "The Louvre's Museum Pyramide", pictureName: "tutorial_background_04@2x.jpg", duration: 3.0)
30 | [...]
31 | ```
32 |
33 | **Common styles for SubTitles and Descriptions :**
34 | ```swift
35 | // Set the common style for SubTitles and Description (can be overrided on each page).
36 | let titleStyle: ICETutorialLabelStyle = ICETutorialLabelStyle()
37 | titleStyle.font = UIFont(name: "Helvetica-Bold", size: 17.0)
38 | titleStyle.color = UIColor.whiteColor()
39 | titleStyle.linesNumber = 1
40 | titleStyle.offsset = 180
41 |
42 | let subStyle: ICETutorialLabelStyle = ICETutorialLabelStyle()
43 | subStyle.font = UIFont(name: "Helvetica", size: 15.0)
44 | subStyle.color = UIColor.whiteColor()
45 | subStyle.linesNumber = 1
46 | subStyle.offsset = 150
47 |
48 | // Load into an array.
49 | let listPages: [ICETutorialPage] = [layer1, layer2, layer3, layer4, layer5]
50 |
51 | ```
52 |
53 | **Init and load :**
54 | ```swift
55 | // Load the ICETutorialController.
56 | let controller: ICETutorialController = ICETutorialController(pages: listPages)
57 |
58 | // Set the common styles, and start scrolling (auto scroll, and looping enabled by default)
59 | controller.commonPageTitleStyle = titleStyle
60 | controller.commonPageSubTitleStyle = subStyle
61 | controller.startScrolling()
62 | ```
63 |
64 | **The title is located in the ICETutorialController.swift :**
65 | ```swift
66 | // Setup the Title Label.
67 | func setOverlayTitle() {
68 | self.overlayLogo!.text = "Welcome"
69 | }
70 | ```
71 |
72 | **Delegate implementation :**
73 | ```swift
74 | #pragma mark - ICETutorialController delegate
75 | - (void)tutorialController:(ICETutorialController *)tutorialController scrollingFromPageIndex:(NSUInteger)fromIndex toPageIndex:(NSUInteger)toIndex {
76 | NSLog(@"Scrolling from %lu to %lu", (unsigned long)fromIndex, (unsigned long)toIndex);
77 | }
78 |
79 | - (void)tutorialControllerDidReachLastPage:(ICETutorialController *)tutorialController {
80 | NSLog(@"Tutorial reached the last page.");
81 | }
82 |
83 | - (void)tutorialController:(ICETutorialController *)tutorialController didClickOnLeftButton:(UIButton *)sender {
84 | NSLog(@"Button 1 pressed.");
85 | }
86 |
87 | - (void)tutorialController:(ICETutorialController *)tutorialController didClickOnRightButton:(UIButton *)sender {
88 | NSLog(@"Button 2 pressed.");
89 | NSLog(@"Auto-scrolling stopped.");
90 |
91 | [self.viewController stopScrolling];
92 | }
93 | ```
94 |
95 | Checkout the others projects available on my account [@Icepat](https://github.com/icepat/) :
96 |
97 | [ICETutorial](https://github.com/icepat/ICETutorial)
98 |
99 | A nice tutorial like the one introduced in the Path 3.X App
100 |
101 | [ICETutorialSwift](https://github.com/icepat/ICETutorialSwift)
102 |
103 | A nice tutorial like the one introduced in the Path 3.X App (in Swift)
104 |
105 |
106 | Questions or ideas : patrick.trillsam@gmail.com.
107 |
108 |
109 | ###License :
110 |
111 | The MIT License
112 |
113 | Copyright (c) 2015 Patrick Trillsam - ICETutorial
114 |
115 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
116 |
117 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
118 |
119 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
120 |
--------------------------------------------------------------------------------
/ICETutorial/Libraries/ICETutorialController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ICETutorialController.swift
3 | // ICETutorial
4 | //
5 | // Created by Patrick Trillsam on 5/06/2014.
6 | // Copyright (c) 2014 Patrick Trillsam. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | enum ScrollingState : Int {
13 | case Auto
14 | case Manual
15 | case Looping
16 | }
17 |
18 | class ICETutorialController : UIViewController, UIScrollViewDelegate {
19 |
20 | var frontLayerView: UIImageView!
21 | var backLayerView: UIImageView!
22 | var scrollView: UIScrollView!
23 | var pageControl: UIPageControl!
24 | var leftButton: UIButton!
25 | var rightButton: UIButton!
26 |
27 | var overlayLogo: UILabel!
28 |
29 | var currentPageIndex: NSInteger!
30 | var nextPageIndex: NSInteger?
31 | var currentState: ScrollingState?
32 | var windowSize: CGSize?
33 | var pages: ICETutorialPage[]!
34 | var autoScrollEnabled: Bool!
35 | var commonPageTitleStyle: ICETutorialLabelStyle!
36 | var commonPageSubTitleStyle: ICETutorialLabelStyle!
37 |
38 | init(pages: ICETutorialPage[]) {
39 | super.init(nibName: nil, bundle: nil)
40 |
41 | self.autoScrollEnabled = true
42 | self.currentPageIndex = 0
43 | // Auto-scrollDuration
44 | self.pages = pages
45 |
46 | self.frontLayerView = UIImageView()
47 | self.backLayerView = UIImageView()
48 | self.scrollView = UIScrollView()
49 |
50 | self.overlayLogo = UILabel()
51 | self.pageControl = UIPageControl()
52 | self.leftButton = UIButton()
53 | self.rightButton = UIButton()
54 | }
55 |
56 | override func viewDidLoad() {
57 | super.viewDidLoad()
58 | self.view!.backgroundColor = UIColor.blackColor()
59 |
60 | self.setupView()
61 |
62 | // Overlays.
63 | self.setOverlayTexts()
64 | self.setOverlayTitle()
65 |
66 | // Preset the origin state.
67 | self.setOriginLayersState()
68 | }
69 |
70 | func setupView() {
71 | self.frontLayerView!.frame = self.view.bounds
72 | self.backLayerView!.frame = self.view.bounds
73 |
74 | // Decoration.
75 | var gradientView = UIImageView(frame: CGRectMake(0, 368, 320, 200))
76 | gradientView.image = UIImage(named: "background-gradient.png")
77 |
78 | // Title.
79 | self.overlayLogo!.frame = CGRectMake(84, 116, 212, 50)
80 | self.overlayLogo!.textColor = UIColor.whiteColor()
81 | self.overlayLogo!.font = UIFont(name: "Helvetica-Bold", size: 32.0)
82 |
83 | // ScrollView configuration.
84 | self.scrollView!.frame = self.view.bounds
85 | self.scrollView!.delegate = self
86 | self.scrollView!.pagingEnabled = true
87 | self.scrollView!.contentSize = CGSizeMake(5 * 320, self.view.bounds.height)
88 |
89 | // PageControl.
90 | self.pageControl!.frame = CGRectMake(141, 453, 36, 32)
91 | self.pageControl!.numberOfPages = self.numberOfPages()
92 | self.pageControl!.currentPage = 0
93 | self.pageControl!.addTarget(self, action: "didClickOnPageControl:", forControlEvents: UIControlEvents.ValueChanged)
94 |
95 | // UIButtons.
96 | self.leftButton!.frame = CGRectMake(20, 494, 130, 36)
97 | self.rightButton!.frame = CGRectMake(172, 494, 130, 36)
98 | self.leftButton!.backgroundColor = UIColor.darkGrayColor()
99 | self.rightButton!.backgroundColor = UIColor.darkGrayColor()
100 | self.leftButton!.setTitle("Button 1", forState: UIControlState.Normal)
101 | self.rightButton!.setTitle("Button 2", forState: UIControlState.Normal)
102 | self.leftButton!.addTarget(self, action: "didClickOnButton1:", forControlEvents: UIControlEvents.TouchUpInside)
103 | self.rightButton!.addTarget(self, action: "didClickOnButton2:", forControlEvents: UIControlEvents.TouchUpInside)
104 |
105 |
106 | // Fetch on screen.
107 | self.view.addSubview(self.frontLayerView)
108 | self.view.addSubview(self.backLayerView)
109 | self.view.addSubview(gradientView)
110 | self.view.addSubview(self.scrollView)
111 | self.view.addSubview(self.overlayLogo)
112 | self.view.addSubview(self.pageControl)
113 | self.view.addSubview(self.leftButton)
114 | self.view.addSubview(self.rightButton)
115 | }
116 |
117 | func didClickOnButton1(sender: UIButton) {
118 |
119 | }
120 |
121 | func didClickOnButton2(sender: UIButton) {
122 |
123 | }
124 |
125 | func didClickOnPageControl(sender: UIPageControl) {
126 | self.stopScrolling()
127 |
128 | // Make the scrollView animation.
129 | self.scrollToNextPageIndex(sender.currentPage)
130 | }
131 |
132 | // Set the list of pages (ICETutorialPage).
133 | func setPages(pages: ICETutorialPage[] ) {
134 | self.pages = pages
135 | }
136 |
137 | func numberOfPages() -> Int {
138 | if (self.pages) {
139 | return self.pages!.count
140 | }
141 | return 0
142 | }
143 |
144 | func animateScrolling() {
145 | if (self.currentState == ScrollingState.Manual) {
146 | return;
147 | }
148 |
149 | // Jump to the next page...
150 | var nextPage: Int = self.currentPageIndex! + 1
151 | if (nextPage == self.numberOfPages()) {
152 | // ...stop the auto-scrolling or...
153 | if (!self.autoScrollEnabled) {
154 | self.currentState = ScrollingState.Manual
155 | return;
156 | }
157 |
158 | // ...jump to the first page.
159 | nextPage = 0
160 | self.currentState = ScrollingState.Looping
161 |
162 | // Set alpha on layers.
163 | self.setOriginLayerAlpha()
164 | self.setBackLayerPictureWithPageIndex(-1)
165 | } else {
166 | self.currentState = ScrollingState.Auto
167 | }
168 |
169 | // Make the scrollView animation.
170 | var nextPagePosition: Float = Float(nextPage) * 320
171 | self.scrollView!.setContentOffset(CGPointMake(nextPagePosition, 0), animated: true)
172 |
173 | // Set the PageControl on the right page.
174 | self.pageControl!.currentPage = nextPage
175 |
176 | // Call the next animation after X seconds.
177 | self.autoScrollToNextPage()
178 | }
179 |
180 | func autoScrollToNextPage() {
181 | let page: ICETutorialPage = self.pages[self.currentPageIndex!]
182 |
183 | if (self.autoScrollEnabled) {
184 | NSTimer.scheduledTimerWithTimeInterval(page.duration!, target: self, selector: Selector("animateScrolling"), userInfo: nil, repeats: false)
185 | }
186 | }
187 |
188 | func scrollToNextPageIndex(nextPageIndex: NSInteger) {
189 | // Make the scrollView animation.
190 | self.scrollView!.setContentOffset(CGPointMake(Float(nextPageIndex) * self.view.frame.size.width,0), animated: true)
191 |
192 | // Set the PageControl on the right page.
193 | self.pageControl!.currentPage = nextPageIndex
194 | }
195 |
196 | // Run it.
197 | func startScrolling() {
198 | self.autoScrollToNextPage()
199 | }
200 |
201 | // Manually stop the scrolling
202 | func stopScrolling() {
203 | self.currentState = ScrollingState.Manual
204 | }
205 |
206 | // State.
207 | func getCurrentState() -> ScrollingState {
208 | return self.currentState!
209 | }
210 |
211 | // Setup the Title Label.
212 | func setOverlayTitle() {
213 | self.overlayLogo!.text = "Welcome"
214 | }
215 |
216 | // Setup the Title/Subtitle style/text.
217 | func setOverlayTexts() {
218 | var index: Int = 0
219 | for page in self.pages! {
220 | if (page.title.text) {
221 | var title: UILabel = self.overlayLabelWithText(page.title.text!, style: page.title!, commonStyle: self.commonPageTitleStyle, index: index)
222 | self.scrollView!.addSubview(title)
223 | }
224 | if (page.subTitle.text) {
225 | var subTitle: UILabel = self.overlayLabelWithText(page.subTitle.text!, style: page.subTitle!, commonStyle: self.commonPageSubTitleStyle!, index: index)
226 | self.scrollView!.addSubview(subTitle)
227 | }
228 | index++
229 | }
230 | }
231 |
232 | func overlayLabelWithText(text: NSString, style: ICETutorialLabelStyle, commonStyle: ICETutorialLabelStyle, index: NSInteger) -> UILabel {
233 | var position: CGFloat = (CGFloat)(index * 320)
234 | var positionY: CGFloat = (CGFloat)(540 - commonStyle.offsset)
235 | var overlayLabel: UILabel = UILabel()
236 | overlayLabel.frame = CGRectMake(position, positionY, 320, 34)
237 |
238 | // SubTitles.
239 | overlayLabel.setTranslatesAutoresizingMaskIntoConstraints(false)
240 | overlayLabel.numberOfLines = commonStyle.linesNumber
241 | overlayLabel.backgroundColor = UIColor.clearColor()
242 | overlayLabel.textAlignment = NSTextAlignment.Center
243 |
244 | // Datas and style.
245 | overlayLabel.text = text
246 | if (style.font) {
247 | overlayLabel.font = style.font
248 | } else {
249 | overlayLabel.font = commonStyle.font
250 | }
251 | if (style.color) {
252 | overlayLabel.textColor = style.color
253 | } else {
254 | overlayLabel.textColor = commonStyle.color
255 | }
256 |
257 | return overlayLabel
258 | }
259 |
260 | // Handle the background layer image switch.
261 | func setBackLayerPictureWithPageIndex(index: NSInteger) {
262 | self.setBackgroundImage(self.backLayerView!, pageIndex: index + 1)
263 | }
264 |
265 | // Handle the front layer image switch.
266 | func setFrontLayerPictureWithPageIndex(index: NSInteger) {
267 | self.setBackgroundImage(self.frontLayerView!, pageIndex: index)
268 | }
269 |
270 | // Handle page image's loading
271 | func setBackgroundImage(imageView: UIImageView, pageIndex: NSInteger) {
272 | if (pageIndex >= self.pages!.count) {
273 | imageView.image = nil
274 | return
275 | }
276 |
277 | let page: ICETutorialPage = self.pages[pageIndex]
278 | imageView.image = UIImage(named: page.pictureName!)
279 | }
280 |
281 | // Setup layer's alpha.
282 | func setOriginLayerAlpha() {
283 | self.frontLayerView!.alpha = 1
284 | self.backLayerView!.alpha = 0
285 | }
286 |
287 | // Preset the origin state.
288 | func setOriginLayersState() {
289 | self.currentState = ScrollingState.Auto
290 | self.backLayerView!.backgroundColor = UIColor.blackColor()
291 | self.frontLayerView!.backgroundColor = UIColor.blackColor()
292 | self.setLayersPicturesWithIndex(0)
293 | }
294 |
295 | // Setup the layers with the page index.
296 | func setLayersPicturesWithIndex(index: NSInteger) {
297 | self.currentPageIndex = index
298 | self.setOriginLayerAlpha()
299 | self.setFrontLayerPictureWithPageIndex(index)
300 | self.setBackLayerPictureWithPageIndex(index)
301 | }
302 |
303 | // Animate the fade-in/out (Cross-disolve) with the scrollView translation.
304 | func disolveBackgroundWithContentOffset(offset: Float) {
305 | if (self.currentState == ScrollingState.Looping) {
306 | // Jump from the last page to the first.
307 | self.scrollingToFirstPageWithOffset(offset)
308 | } else {
309 | // Or just scroll to the next/previous page.
310 | self.scrollingToNextPageWithOffset(offset)
311 | }
312 | }
313 |
314 | // Handle alpha on layers when the auto-scrolling is looping to the first page.
315 | func scrollingToFirstPageWithOffset(offset: Float) {
316 | // Compute the scrolling percentage on all the page.
317 | let offsetX: Float = (offset * 320)
318 | let numberOfPage: Float = 5
319 | let offsetY: Float = (320 * numberOfPage)
320 | let finalOffset: Float = offsetX / offsetY
321 |
322 | // Scrolling finished...
323 | if (offset == 0) {
324 | self.setOriginLayersState()
325 | return
326 | }
327 |
328 | // Invert alpha for the back picture.
329 | var backLayerAlpha: Float = (1 - offset)
330 | var frontLayerAlpha: Float = offset
331 |
332 | // Set alpha.
333 | self.backLayerView!.alpha = backLayerAlpha
334 | self.frontLayerView!.alpha = frontLayerAlpha
335 | }
336 |
337 | // Handle alpha on layers when we are scrolling to the next/previous page.
338 | func scrollingToNextPageWithOffset(offset: Float) {
339 | // Current page index in scrolling.
340 | var page: Int = Int(offset)
341 |
342 | // Keep only the float value.
343 | var alphaValue: Float = offset - Float(Int(offset));
344 |
345 | // This is only when you scroll to the right on the first page.
346 | // That will fade-in black the first picture.
347 | if (alphaValue < 0 && self.currentPageIndex == 0) {
348 | self.backLayerView!.image = nil
349 | self.frontLayerView!.alpha = (1 + alphaValue)
350 | return
351 | }
352 |
353 | // Switch pictures, and imageView alpha.
354 | if (page != self.currentPageIndex ||
355 | (page == self.currentPageIndex && 0.0 < offset && offset < 1.0)) {
356 | self.setLayersPicturesWithIndex(page)
357 | }
358 |
359 | // Invert alpha for the front picture.
360 | var backLayerAlpha: Float = alphaValue
361 | var frontLayerAlpha: Float = (1 - alphaValue)
362 |
363 | // Set alpha.
364 | self.backLayerView!.alpha = backLayerAlpha
365 | self.frontLayerView!.alpha = frontLayerAlpha
366 | }
367 |
368 | func scrollViewDidScroll(scrollView: UIScrollView!) {
369 | // Get scrolling position, and nextPageindex.
370 | var scrollingPosition: Float = self.scrollView!.contentOffset.x / 320.0
371 | var nextPageIndex: Int = Int(scrollingPosition)
372 |
373 | // If we are looping, we reset the indexPage.
374 | if (self.currentState == ScrollingState.Looping) {
375 | nextPageIndex = 0
376 | }
377 |
378 | // If we are going to the next page, let's call the delegate.
379 | if (nextPageIndex != self.nextPageIndex) {
380 | // DELEGATE
381 | self.nextPageIndex = nextPageIndex
382 | }
383 |
384 | // Delegate when we reach the end.
385 | if (self.nextPageIndex == self.numberOfPages() - 1) {
386 | // DELEGATE
387 | }
388 |
389 | // Animate.
390 | self.disolveBackgroundWithContentOffset(scrollingPosition)
391 | }
392 |
393 | func scrollViewWillBeginDragging(scrollView: UIScrollView!) {
394 | // At the first user interaction, we disable the auto scrolling.
395 | if (self.scrollView!.tracking) {
396 | self.stopScrolling()
397 | }
398 | }
399 |
400 | func scrollViewDidEndDecelerating(scrollView: UIScrollView!) {
401 | // Update the page index.
402 | self.pageControl!.currentPage = self.currentPageIndex!;
403 | }
404 | }
--------------------------------------------------------------------------------
/ICETutorial.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 55A1D55F193FEFCC00994874 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55A1D55E193FEFCC00994874 /* AppDelegate.swift */; };
11 | 55A1D561193FEFCC00994874 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 55A1D560193FEFCC00994874 /* Images.xcassets */; };
12 | 55A1D56D193FEFCC00994874 /* ICETutorialTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55A1D56C193FEFCC00994874 /* ICETutorialTests.swift */; };
13 | 55A1D583193FF01600994874 /* background-gradient.png in Resources */ = {isa = PBXBuildFile; fileRef = 55A1D577193FF01600994874 /* background-gradient.png */; };
14 | 55A1D584193FF01600994874 /* background-gradient@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 55A1D578193FF01600994874 /* background-gradient@2x.png */; };
15 | 55A1D585193FF01600994874 /* button-background.png in Resources */ = {isa = PBXBuildFile; fileRef = 55A1D579193FF01600994874 /* button-background.png */; };
16 | 55A1D586193FF01600994874 /* button-background@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 55A1D57A193FF01600994874 /* button-background@2x.png */; };
17 | 55A1D587193FF01600994874 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 55A1D57B193FF01600994874 /* Default-568h@2x.png */; };
18 | 55A1D588193FF01600994874 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 55A1D57C193FF01600994874 /* Default.png */; };
19 | 55A1D589193FF01600994874 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 55A1D57D193FF01600994874 /* Default@2x.png */; };
20 | 55A1D58A193FF01600994874 /* tutorial_background_00@2x.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 55A1D57E193FF01600994874 /* tutorial_background_00@2x.jpg */; };
21 | 55A1D58B193FF01600994874 /* tutorial_background_01@2x.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 55A1D57F193FF01600994874 /* tutorial_background_01@2x.jpg */; };
22 | 55A1D58C193FF01600994874 /* tutorial_background_02@2x.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 55A1D580193FF01600994874 /* tutorial_background_02@2x.jpg */; };
23 | 55A1D58D193FF01600994874 /* tutorial_background_03@2x.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 55A1D581193FF01600994874 /* tutorial_background_03@2x.jpg */; };
24 | 55A1D58E193FF01600994874 /* tutorial_background_04@2x.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 55A1D582193FF01600994874 /* tutorial_background_04@2x.jpg */; };
25 | 55A1D597193FF05400994874 /* ICETutorialPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55A1D596193FF05400994874 /* ICETutorialPage.swift */; };
26 | 55A1D5F3193FFA9300994874 /* ICETutorialController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55A1D5F2193FFA9300994874 /* ICETutorialController.swift */; };
27 | /* End PBXBuildFile section */
28 |
29 | /* Begin PBXContainerItemProxy section */
30 | 55A1D567193FEFCC00994874 /* PBXContainerItemProxy */ = {
31 | isa = PBXContainerItemProxy;
32 | containerPortal = 55A1D551193FEFCC00994874 /* Project object */;
33 | proxyType = 1;
34 | remoteGlobalIDString = 55A1D558193FEFCC00994874;
35 | remoteInfo = ICETutorialSwift;
36 | };
37 | /* End PBXContainerItemProxy section */
38 |
39 | /* Begin PBXFileReference section */
40 | 55A1D559193FEFCC00994874 /* ICETutorial.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ICETutorial.app; sourceTree = BUILT_PRODUCTS_DIR; };
41 | 55A1D55D193FEFCC00994874 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
42 | 55A1D55E193FEFCC00994874 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
43 | 55A1D560193FEFCC00994874 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
44 | 55A1D566193FEFCC00994874 /* ICETutorialTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ICETutorialTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
45 | 55A1D56B193FEFCC00994874 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
46 | 55A1D56C193FEFCC00994874 /* ICETutorialTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ICETutorialTests.swift; sourceTree = ""; };
47 | 55A1D577193FF01600994874 /* background-gradient.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "background-gradient.png"; sourceTree = ""; };
48 | 55A1D578193FF01600994874 /* background-gradient@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "background-gradient@2x.png"; sourceTree = ""; };
49 | 55A1D579193FF01600994874 /* button-background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button-background.png"; sourceTree = ""; };
50 | 55A1D57A193FF01600994874 /* button-background@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button-background@2x.png"; sourceTree = ""; };
51 | 55A1D57B193FF01600994874 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; };
52 | 55A1D57C193FF01600994874 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; };
53 | 55A1D57D193FF01600994874 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; };
54 | 55A1D57E193FF01600994874 /* tutorial_background_00@2x.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "tutorial_background_00@2x.jpg"; sourceTree = ""; };
55 | 55A1D57F193FF01600994874 /* tutorial_background_01@2x.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "tutorial_background_01@2x.jpg"; sourceTree = ""; };
56 | 55A1D580193FF01600994874 /* tutorial_background_02@2x.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "tutorial_background_02@2x.jpg"; sourceTree = ""; };
57 | 55A1D581193FF01600994874 /* tutorial_background_03@2x.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "tutorial_background_03@2x.jpg"; sourceTree = ""; };
58 | 55A1D582193FF01600994874 /* tutorial_background_04@2x.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "tutorial_background_04@2x.jpg"; sourceTree = ""; };
59 | 55A1D596193FF05400994874 /* ICETutorialPage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ICETutorialPage.swift; sourceTree = ""; };
60 | 55A1D5F2193FFA9300994874 /* ICETutorialController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ICETutorialController.swift; sourceTree = ""; };
61 | /* End PBXFileReference section */
62 |
63 | /* Begin PBXFrameworksBuildPhase section */
64 | 55A1D556193FEFCC00994874 /* Frameworks */ = {
65 | isa = PBXFrameworksBuildPhase;
66 | buildActionMask = 2147483647;
67 | files = (
68 | );
69 | runOnlyForDeploymentPostprocessing = 0;
70 | };
71 | 55A1D563193FEFCC00994874 /* Frameworks */ = {
72 | isa = PBXFrameworksBuildPhase;
73 | buildActionMask = 2147483647;
74 | files = (
75 | );
76 | runOnlyForDeploymentPostprocessing = 0;
77 | };
78 | /* End PBXFrameworksBuildPhase section */
79 |
80 | /* Begin PBXGroup section */
81 | 55A1D550193FEFCC00994874 = {
82 | isa = PBXGroup;
83 | children = (
84 | 55A1D58F193FF02000994874 /* Libraries */,
85 | 55A1D576193FF01600994874 /* Resources */,
86 | 55A1D55B193FEFCC00994874 /* ICETutorial */,
87 | 55A1D569193FEFCC00994874 /* ICETutorialTests */,
88 | 55A1D55A193FEFCC00994874 /* Products */,
89 | );
90 | sourceTree = "";
91 | };
92 | 55A1D55A193FEFCC00994874 /* Products */ = {
93 | isa = PBXGroup;
94 | children = (
95 | 55A1D559193FEFCC00994874 /* ICETutorial.app */,
96 | 55A1D566193FEFCC00994874 /* ICETutorialTests.xctest */,
97 | );
98 | name = Products;
99 | sourceTree = "";
100 | };
101 | 55A1D55B193FEFCC00994874 /* ICETutorial */ = {
102 | isa = PBXGroup;
103 | children = (
104 | 55A1D55E193FEFCC00994874 /* AppDelegate.swift */,
105 | 55A1D560193FEFCC00994874 /* Images.xcassets */,
106 | 55A1D55C193FEFCC00994874 /* Supporting Files */,
107 | );
108 | path = ICETutorial;
109 | sourceTree = "";
110 | };
111 | 55A1D55C193FEFCC00994874 /* Supporting Files */ = {
112 | isa = PBXGroup;
113 | children = (
114 | 55A1D55D193FEFCC00994874 /* Info.plist */,
115 | );
116 | name = "Supporting Files";
117 | sourceTree = "";
118 | };
119 | 55A1D569193FEFCC00994874 /* ICETutorialTests */ = {
120 | isa = PBXGroup;
121 | children = (
122 | 55A1D56C193FEFCC00994874 /* ICETutorialTests.swift */,
123 | 55A1D56A193FEFCC00994874 /* Supporting Files */,
124 | );
125 | path = ICETutorialTests;
126 | sourceTree = "";
127 | };
128 | 55A1D56A193FEFCC00994874 /* Supporting Files */ = {
129 | isa = PBXGroup;
130 | children = (
131 | 55A1D56B193FEFCC00994874 /* Info.plist */,
132 | );
133 | name = "Supporting Files";
134 | sourceTree = "";
135 | };
136 | 55A1D576193FF01600994874 /* Resources */ = {
137 | isa = PBXGroup;
138 | children = (
139 | 55A1D577193FF01600994874 /* background-gradient.png */,
140 | 55A1D578193FF01600994874 /* background-gradient@2x.png */,
141 | 55A1D579193FF01600994874 /* button-background.png */,
142 | 55A1D57A193FF01600994874 /* button-background@2x.png */,
143 | 55A1D57B193FF01600994874 /* Default-568h@2x.png */,
144 | 55A1D57C193FF01600994874 /* Default.png */,
145 | 55A1D57D193FF01600994874 /* Default@2x.png */,
146 | 55A1D57E193FF01600994874 /* tutorial_background_00@2x.jpg */,
147 | 55A1D57F193FF01600994874 /* tutorial_background_01@2x.jpg */,
148 | 55A1D580193FF01600994874 /* tutorial_background_02@2x.jpg */,
149 | 55A1D581193FF01600994874 /* tutorial_background_03@2x.jpg */,
150 | 55A1D582193FF01600994874 /* tutorial_background_04@2x.jpg */,
151 | );
152 | path = Resources;
153 | sourceTree = "";
154 | };
155 | 55A1D58F193FF02000994874 /* Libraries */ = {
156 | isa = PBXGroup;
157 | children = (
158 | 55A1D596193FF05400994874 /* ICETutorialPage.swift */,
159 | 55A1D5F2193FFA9300994874 /* ICETutorialController.swift */,
160 | );
161 | name = Libraries;
162 | path = ICETutorial/Libraries;
163 | sourceTree = "";
164 | };
165 | /* End PBXGroup section */
166 |
167 | /* Begin PBXNativeTarget section */
168 | 55A1D558193FEFCC00994874 /* ICETutorial */ = {
169 | isa = PBXNativeTarget;
170 | buildConfigurationList = 55A1D570193FEFCC00994874 /* Build configuration list for PBXNativeTarget "ICETutorial" */;
171 | buildPhases = (
172 | 55A1D555193FEFCC00994874 /* Sources */,
173 | 55A1D556193FEFCC00994874 /* Frameworks */,
174 | 55A1D557193FEFCC00994874 /* Resources */,
175 | );
176 | buildRules = (
177 | );
178 | dependencies = (
179 | );
180 | name = ICETutorial;
181 | productName = ICETutorialSwift;
182 | productReference = 55A1D559193FEFCC00994874 /* ICETutorial.app */;
183 | productType = "com.apple.product-type.application";
184 | };
185 | 55A1D565193FEFCC00994874 /* ICETutorialTests */ = {
186 | isa = PBXNativeTarget;
187 | buildConfigurationList = 55A1D573193FEFCC00994874 /* Build configuration list for PBXNativeTarget "ICETutorialTests" */;
188 | buildPhases = (
189 | 55A1D562193FEFCC00994874 /* Sources */,
190 | 55A1D563193FEFCC00994874 /* Frameworks */,
191 | 55A1D564193FEFCC00994874 /* Resources */,
192 | );
193 | buildRules = (
194 | );
195 | dependencies = (
196 | 55A1D568193FEFCC00994874 /* PBXTargetDependency */,
197 | );
198 | name = ICETutorialTests;
199 | productName = ICETutorialSwiftTests;
200 | productReference = 55A1D566193FEFCC00994874 /* ICETutorialTests.xctest */;
201 | productType = "com.apple.product-type.bundle.unit-test";
202 | };
203 | /* End PBXNativeTarget section */
204 |
205 | /* Begin PBXProject section */
206 | 55A1D551193FEFCC00994874 /* Project object */ = {
207 | isa = PBXProject;
208 | attributes = {
209 | LastUpgradeCheck = 0600;
210 | ORGANIZATIONNAME = "Patrick Trillsam";
211 | TargetAttributes = {
212 | 55A1D558193FEFCC00994874 = {
213 | CreatedOnToolsVersion = 6.0;
214 | };
215 | 55A1D565193FEFCC00994874 = {
216 | CreatedOnToolsVersion = 6.0;
217 | TestTargetID = 55A1D558193FEFCC00994874;
218 | };
219 | };
220 | };
221 | buildConfigurationList = 55A1D554193FEFCC00994874 /* Build configuration list for PBXProject "ICETutorial" */;
222 | compatibilityVersion = "Xcode 3.2";
223 | developmentRegion = English;
224 | hasScannedForEncodings = 0;
225 | knownRegions = (
226 | en,
227 | );
228 | mainGroup = 55A1D550193FEFCC00994874;
229 | productRefGroup = 55A1D55A193FEFCC00994874 /* Products */;
230 | projectDirPath = "";
231 | projectRoot = "";
232 | targets = (
233 | 55A1D558193FEFCC00994874 /* ICETutorial */,
234 | 55A1D565193FEFCC00994874 /* ICETutorialTests */,
235 | );
236 | };
237 | /* End PBXProject section */
238 |
239 | /* Begin PBXResourcesBuildPhase section */
240 | 55A1D557193FEFCC00994874 /* Resources */ = {
241 | isa = PBXResourcesBuildPhase;
242 | buildActionMask = 2147483647;
243 | files = (
244 | 55A1D589193FF01600994874 /* Default@2x.png in Resources */,
245 | 55A1D58C193FF01600994874 /* tutorial_background_02@2x.jpg in Resources */,
246 | 55A1D58B193FF01600994874 /* tutorial_background_01@2x.jpg in Resources */,
247 | 55A1D561193FEFCC00994874 /* Images.xcassets in Resources */,
248 | 55A1D586193FF01600994874 /* button-background@2x.png in Resources */,
249 | 55A1D58A193FF01600994874 /* tutorial_background_00@2x.jpg in Resources */,
250 | 55A1D58E193FF01600994874 /* tutorial_background_04@2x.jpg in Resources */,
251 | 55A1D585193FF01600994874 /* button-background.png in Resources */,
252 | 55A1D584193FF01600994874 /* background-gradient@2x.png in Resources */,
253 | 55A1D588193FF01600994874 /* Default.png in Resources */,
254 | 55A1D583193FF01600994874 /* background-gradient.png in Resources */,
255 | 55A1D587193FF01600994874 /* Default-568h@2x.png in Resources */,
256 | 55A1D58D193FF01600994874 /* tutorial_background_03@2x.jpg in Resources */,
257 | );
258 | runOnlyForDeploymentPostprocessing = 0;
259 | };
260 | 55A1D564193FEFCC00994874 /* Resources */ = {
261 | isa = PBXResourcesBuildPhase;
262 | buildActionMask = 2147483647;
263 | files = (
264 | );
265 | runOnlyForDeploymentPostprocessing = 0;
266 | };
267 | /* End PBXResourcesBuildPhase section */
268 |
269 | /* Begin PBXSourcesBuildPhase section */
270 | 55A1D555193FEFCC00994874 /* Sources */ = {
271 | isa = PBXSourcesBuildPhase;
272 | buildActionMask = 2147483647;
273 | files = (
274 | 55A1D55F193FEFCC00994874 /* AppDelegate.swift in Sources */,
275 | 55A1D5F3193FFA9300994874 /* ICETutorialController.swift in Sources */,
276 | 55A1D597193FF05400994874 /* ICETutorialPage.swift in Sources */,
277 | );
278 | runOnlyForDeploymentPostprocessing = 0;
279 | };
280 | 55A1D562193FEFCC00994874 /* Sources */ = {
281 | isa = PBXSourcesBuildPhase;
282 | buildActionMask = 2147483647;
283 | files = (
284 | 55A1D56D193FEFCC00994874 /* ICETutorialTests.swift in Sources */,
285 | );
286 | runOnlyForDeploymentPostprocessing = 0;
287 | };
288 | /* End PBXSourcesBuildPhase section */
289 |
290 | /* Begin PBXTargetDependency section */
291 | 55A1D568193FEFCC00994874 /* PBXTargetDependency */ = {
292 | isa = PBXTargetDependency;
293 | target = 55A1D558193FEFCC00994874 /* ICETutorial */;
294 | targetProxy = 55A1D567193FEFCC00994874 /* PBXContainerItemProxy */;
295 | };
296 | /* End PBXTargetDependency section */
297 |
298 | /* Begin XCBuildConfiguration section */
299 | 55A1D56E193FEFCC00994874 /* Debug */ = {
300 | isa = XCBuildConfiguration;
301 | buildSettings = {
302 | ALWAYS_SEARCH_USER_PATHS = NO;
303 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
304 | CLANG_CXX_LIBRARY = "libc++";
305 | CLANG_ENABLE_MODULES = YES;
306 | CLANG_ENABLE_OBJC_ARC = YES;
307 | CLANG_WARN_BOOL_CONVERSION = YES;
308 | CLANG_WARN_CONSTANT_CONVERSION = YES;
309 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
310 | CLANG_WARN_EMPTY_BODY = YES;
311 | CLANG_WARN_ENUM_CONVERSION = YES;
312 | CLANG_WARN_INT_CONVERSION = YES;
313 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
314 | CLANG_WARN_UNREACHABLE_CODE = YES;
315 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
316 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
317 | COPY_PHASE_STRIP = NO;
318 | ENABLE_STRICT_OBJC_MSGSEND = YES;
319 | GCC_C_LANGUAGE_STANDARD = gnu99;
320 | GCC_DYNAMIC_NO_PIC = NO;
321 | GCC_OPTIMIZATION_LEVEL = 0;
322 | GCC_PREPROCESSOR_DEFINITIONS = (
323 | "DEBUG=1",
324 | "$(inherited)",
325 | );
326 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
327 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
328 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
329 | GCC_WARN_UNDECLARED_SELECTOR = YES;
330 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
331 | GCC_WARN_UNUSED_FUNCTION = YES;
332 | GCC_WARN_UNUSED_VARIABLE = YES;
333 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
334 | METAL_ENABLE_DEBUG_INFO = YES;
335 | ONLY_ACTIVE_ARCH = YES;
336 | SDKROOT = iphoneos;
337 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
338 | TARGETED_DEVICE_FAMILY = "1,2";
339 | };
340 | name = Debug;
341 | };
342 | 55A1D56F193FEFCC00994874 /* Release */ = {
343 | isa = XCBuildConfiguration;
344 | buildSettings = {
345 | ALWAYS_SEARCH_USER_PATHS = NO;
346 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
347 | CLANG_CXX_LIBRARY = "libc++";
348 | CLANG_ENABLE_MODULES = YES;
349 | CLANG_ENABLE_OBJC_ARC = YES;
350 | CLANG_WARN_BOOL_CONVERSION = YES;
351 | CLANG_WARN_CONSTANT_CONVERSION = YES;
352 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
353 | CLANG_WARN_EMPTY_BODY = YES;
354 | CLANG_WARN_ENUM_CONVERSION = YES;
355 | CLANG_WARN_INT_CONVERSION = YES;
356 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
357 | CLANG_WARN_UNREACHABLE_CODE = YES;
358 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
359 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
360 | COPY_PHASE_STRIP = YES;
361 | ENABLE_NS_ASSERTIONS = NO;
362 | ENABLE_STRICT_OBJC_MSGSEND = YES;
363 | GCC_C_LANGUAGE_STANDARD = gnu99;
364 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
365 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
366 | GCC_WARN_UNDECLARED_SELECTOR = YES;
367 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
368 | GCC_WARN_UNUSED_FUNCTION = YES;
369 | GCC_WARN_UNUSED_VARIABLE = YES;
370 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
371 | METAL_ENABLE_DEBUG_INFO = NO;
372 | SDKROOT = iphoneos;
373 | TARGETED_DEVICE_FAMILY = "1,2";
374 | VALIDATE_PRODUCT = YES;
375 | };
376 | name = Release;
377 | };
378 | 55A1D571193FEFCC00994874 /* Debug */ = {
379 | isa = XCBuildConfiguration;
380 | buildSettings = {
381 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
382 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
383 | INFOPLIST_FILE = ICETutorial/Info.plist;
384 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
385 | PRODUCT_NAME = ICETutorial;
386 | };
387 | name = Debug;
388 | };
389 | 55A1D572193FEFCC00994874 /* Release */ = {
390 | isa = XCBuildConfiguration;
391 | buildSettings = {
392 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
393 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
394 | INFOPLIST_FILE = ICETutorial/Info.plist;
395 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
396 | PRODUCT_NAME = ICETutorial;
397 | };
398 | name = Release;
399 | };
400 | 55A1D574193FEFCC00994874 /* Debug */ = {
401 | isa = XCBuildConfiguration;
402 | buildSettings = {
403 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/ICETutorialSwift.app/ICETutorialSwift";
404 | FRAMEWORK_SEARCH_PATHS = (
405 | "$(SDKROOT)/Developer/Library/Frameworks",
406 | "$(inherited)",
407 | );
408 | GCC_PREPROCESSOR_DEFINITIONS = (
409 | "DEBUG=1",
410 | "$(inherited)",
411 | );
412 | INFOPLIST_FILE = ICETutorialSwiftTests/Info.plist;
413 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
414 | METAL_ENABLE_DEBUG_INFO = YES;
415 | PRODUCT_NAME = ICETutorialTests;
416 | TEST_HOST = "$(BUNDLE_LOADER)";
417 | };
418 | name = Debug;
419 | };
420 | 55A1D575193FEFCC00994874 /* Release */ = {
421 | isa = XCBuildConfiguration;
422 | buildSettings = {
423 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/ICETutorialSwift.app/ICETutorialSwift";
424 | FRAMEWORK_SEARCH_PATHS = (
425 | "$(SDKROOT)/Developer/Library/Frameworks",
426 | "$(inherited)",
427 | );
428 | INFOPLIST_FILE = ICETutorialSwiftTests/Info.plist;
429 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
430 | METAL_ENABLE_DEBUG_INFO = NO;
431 | PRODUCT_NAME = ICETutorialTests;
432 | TEST_HOST = "$(BUNDLE_LOADER)";
433 | };
434 | name = Release;
435 | };
436 | /* End XCBuildConfiguration section */
437 |
438 | /* Begin XCConfigurationList section */
439 | 55A1D554193FEFCC00994874 /* Build configuration list for PBXProject "ICETutorial" */ = {
440 | isa = XCConfigurationList;
441 | buildConfigurations = (
442 | 55A1D56E193FEFCC00994874 /* Debug */,
443 | 55A1D56F193FEFCC00994874 /* Release */,
444 | );
445 | defaultConfigurationIsVisible = 0;
446 | defaultConfigurationName = Release;
447 | };
448 | 55A1D570193FEFCC00994874 /* Build configuration list for PBXNativeTarget "ICETutorial" */ = {
449 | isa = XCConfigurationList;
450 | buildConfigurations = (
451 | 55A1D571193FEFCC00994874 /* Debug */,
452 | 55A1D572193FEFCC00994874 /* Release */,
453 | );
454 | defaultConfigurationIsVisible = 0;
455 | defaultConfigurationName = Release;
456 | };
457 | 55A1D573193FEFCC00994874 /* Build configuration list for PBXNativeTarget "ICETutorialTests" */ = {
458 | isa = XCConfigurationList;
459 | buildConfigurations = (
460 | 55A1D574193FEFCC00994874 /* Debug */,
461 | 55A1D575193FEFCC00994874 /* Release */,
462 | );
463 | defaultConfigurationIsVisible = 0;
464 | defaultConfigurationName = Release;
465 | };
466 | /* End XCConfigurationList section */
467 | };
468 | rootObject = 55A1D551193FEFCC00994874 /* Project object */;
469 | }
470 |
--------------------------------------------------------------------------------