├── .swift-version
├── Assets
├── demo.gif
├── banner.png
└── custom_examples.png
├── .gitignore
├── Example
├── OnboardExample
│ ├── Assets.xcassets
│ │ ├── Contents.json
│ │ ├── Onboarding1.imageset
│ │ │ ├── Onboarding1.pdf
│ │ │ └── Contents.json
│ │ ├── Onboarding2.imageset
│ │ │ ├── Onboarding2.pdf
│ │ │ └── Contents.json
│ │ ├── Onboarding3.imageset
│ │ │ ├── Onboarding3.pdf
│ │ │ └── Contents.json
│ │ ├── Onboarding4.imageset
│ │ │ ├── Onboarding4.pdf
│ │ │ └── Contents.json
│ │ ├── Onboarding5.imageset
│ │ │ ├── Onboarding5.pdf
│ │ │ └── Contents.json
│ │ ├── Onboarding1_alt.imageset
│ │ │ ├── app_logo_alt.pdf
│ │ │ └── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── AppDelegate.swift
│ ├── Info.plist
│ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ └── ViewController.swift
└── OnboardExample.xcodeproj
│ └── project.pbxproj
├── OnboardKit.xcodeproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
├── xcuserdata
│ └── nikolakirev.xcuserdatad
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
├── xcshareddata
│ └── xcschemes
│ │ └── OnboardKit.xcscheme
└── project.pbxproj
├── OnboardKit.xcworkspace
├── xcshareddata
│ └── IDEWorkspaceChecks.plist
└── contents.xcworkspacedata
├── Package.swift
├── Metadata
├── OnboardKit.h
└── Info.plist
├── OnboardKitTests
├── AppearanceConfigurationTests.swift
└── Info.plist
├── OnboardKit.podspec
├── LICENSE
├── OnboardKit
├── OnboardPage.swift
├── OnboardPageViewController.swift
└── OnboardViewController.swift
└── README.md
/.swift-version:
--------------------------------------------------------------------------------
1 | 5.0
2 |
--------------------------------------------------------------------------------
/Assets/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NikolaKirev/OnboardKit/HEAD/Assets/demo.gif
--------------------------------------------------------------------------------
/Assets/banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NikolaKirev/OnboardKit/HEAD/Assets/banner.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.xcbkptlist
2 | *.xcuserstate
3 | *.xcuserdata
4 | .DS_Store
5 | xcuserdata
6 | xcshareddata
7 |
--------------------------------------------------------------------------------
/Assets/custom_examples.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NikolaKirev/OnboardKit/HEAD/Assets/custom_examples.png
--------------------------------------------------------------------------------
/Example/OnboardExample/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Example/OnboardExample/Assets.xcassets/Onboarding1.imageset/Onboarding1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NikolaKirev/OnboardKit/HEAD/Example/OnboardExample/Assets.xcassets/Onboarding1.imageset/Onboarding1.pdf
--------------------------------------------------------------------------------
/Example/OnboardExample/Assets.xcassets/Onboarding2.imageset/Onboarding2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NikolaKirev/OnboardKit/HEAD/Example/OnboardExample/Assets.xcassets/Onboarding2.imageset/Onboarding2.pdf
--------------------------------------------------------------------------------
/Example/OnboardExample/Assets.xcassets/Onboarding3.imageset/Onboarding3.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NikolaKirev/OnboardKit/HEAD/Example/OnboardExample/Assets.xcassets/Onboarding3.imageset/Onboarding3.pdf
--------------------------------------------------------------------------------
/Example/OnboardExample/Assets.xcassets/Onboarding4.imageset/Onboarding4.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NikolaKirev/OnboardKit/HEAD/Example/OnboardExample/Assets.xcassets/Onboarding4.imageset/Onboarding4.pdf
--------------------------------------------------------------------------------
/Example/OnboardExample/Assets.xcassets/Onboarding5.imageset/Onboarding5.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NikolaKirev/OnboardKit/HEAD/Example/OnboardExample/Assets.xcassets/Onboarding5.imageset/Onboarding5.pdf
--------------------------------------------------------------------------------
/Example/OnboardExample/Assets.xcassets/Onboarding1_alt.imageset/app_logo_alt.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NikolaKirev/OnboardKit/HEAD/Example/OnboardExample/Assets.xcassets/Onboarding1_alt.imageset/app_logo_alt.pdf
--------------------------------------------------------------------------------
/OnboardKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Example/OnboardExample/Assets.xcassets/Onboarding1.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "Onboarding1.pdf"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/Example/OnboardExample/Assets.xcassets/Onboarding2.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "Onboarding2.pdf"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/Example/OnboardExample/Assets.xcassets/Onboarding3.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "Onboarding3.pdf"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/Example/OnboardExample/Assets.xcassets/Onboarding4.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "Onboarding4.pdf"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/Example/OnboardExample/Assets.xcassets/Onboarding5.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "Onboarding5.pdf"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/Example/OnboardExample/Assets.xcassets/Onboarding1_alt.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "app_logo_alt.pdf"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/OnboardKit.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/OnboardKit.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.0
2 | import PackageDescription
3 |
4 | let package = Package(
5 | name: "OnboardKit",
6 | platforms: [.iOS(.v11)],
7 | products: [
8 | .library(name: "OnboardKit", targets: ["OnboardKit"])
9 | ],
10 | dependencies: [],
11 | targets: [
12 | .target(name: "OnboardKit", path: "OnboardKit")
13 | ]
14 | )
--------------------------------------------------------------------------------
/Example/OnboardExample/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // OnboardExample
4 | //
5 |
6 | import UIKit
7 |
8 | @UIApplicationMain
9 | class AppDelegate: UIResponder, UIApplicationDelegate {
10 |
11 | var window: UIWindow?
12 |
13 | func application(_ application: UIApplication,
14 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
15 | return true
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Metadata/OnboardKit.h:
--------------------------------------------------------------------------------
1 | //
2 | // OnboardKit.h
3 | // OnboardKit
4 | //
5 | // Created by Nikola Kirev on 22/07/2017.
6 | // Copyright © 2017 Nikola Kirev. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for OnboardKit.
12 | FOUNDATION_EXPORT double OnboardKitVersionNumber;
13 |
14 | //! Project version string for OnboardKit.
15 | FOUNDATION_EXPORT const unsigned char OnboardKitVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 |
20 |
--------------------------------------------------------------------------------
/OnboardKitTests/AppearanceConfigurationTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppearanceConfigurationTests.swift
3 | // OnboardKitTests
4 | //
5 |
6 | import XCTest
7 | @testable import OnboardKit
8 |
9 | final class AppearanceConfigurationTests: XCTestCase {
10 |
11 | func testAppearanceConfiguration_usesSpecificColor_whenTitleColorSpecified() {
12 | let sut = OnboardViewController.AppearanceConfiguration(titleColor: .purple, textColor: .green)
13 | XCTAssertNotEqual(sut.titleColor, .green)
14 | XCTAssertEqual(sut.titleColor, .purple)
15 | }
16 |
17 | func testAppearanceConfiguration_usesTextColor_whenTitleColorNotSpecified() {
18 | let sut = OnboardViewController.AppearanceConfiguration(textColor: .green)
19 | XCTAssertEqual(sut.titleColor, .green)
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/OnboardKitTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/OnboardKit.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 |
3 | s.name = "OnboardKit"
4 | s.version = "1.5.0"
5 | s.summary = "Customisable user onboarding for your iOS app"
6 |
7 | s.description = <<-DESC
8 | OnboardKit gives you an easy way to add onboarding to your iOS app.
9 | It is written in Swift.
10 | DESC
11 |
12 | s.homepage = "https://github.com/NikolaKirev/OnboardKit"
13 |
14 | s.license = { :type => "MIT", :file => "LICENSE" }
15 |
16 | s.author = { "Nikola Kirev" => "n@nikolakirev.com" }
17 | s.social_media_url = "http://twitter.com/NikolaKirev"
18 |
19 | s.platform = :ios, "11.0"
20 |
21 | s.source = { :git => "https://github.com/NikolaKirev/OnboardKit.git", :tag => "v1.5.0" }
22 | s.source_files = "OnboardKit"
23 |
24 | end
25 |
--------------------------------------------------------------------------------
/Metadata/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.4.2
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 | NSPrincipalClass
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/OnboardKit.xcodeproj/xcuserdata/nikolakirev.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | OnboardKit.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 9437E2A41F238E7E00E294BE
16 |
17 | primary
18 |
19 |
20 | 9437E2AD1F238E7E00E294BE
21 |
22 | primary
23 |
24 |
25 | 9437E2D11F2392FC00E294BE
26 |
27 | primary
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Nikola Kirev
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Example/OnboardExample/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.3.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/Example/OnboardExample/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/OnboardKit/OnboardPage.swift:
--------------------------------------------------------------------------------
1 | //
2 | // OnboardPage.swift
3 | // OnboardKit
4 | //
5 |
6 | import Foundation
7 |
8 | public typealias OnboardPageCompletion = ((_ success: Bool, _ error: Error?) -> Void)
9 | public typealias OnboardPageAction = (@escaping OnboardPageCompletion) -> Void
10 |
11 | public struct OnboardPage {
12 | /// The title text used for the top label of the onboarding page
13 | let title: String
14 |
15 | /// An optional image to be used in the onboarding page
16 | ///
17 | /// - note: If no image is used, the description label will adjust fill the empty space
18 | let imageName: String?
19 |
20 | /// An optional description text to be used underneath the image
21 | ///
22 | /// - note: If no description text is used, the image will adjust fill the empty space
23 | let description: String?
24 |
25 | /// The title text to be used for the secondary button that is used to advance to the next page
26 | let advanceButtonTitle: String
27 |
28 | /// The title text to be used for the optional action button on the page
29 | ///
30 | /// - note: If no action button title is set, the button will not appear
31 | let actionButtonTitle: String?
32 |
33 | /// The action to be called when tapping the action button on the page
34 | ///
35 | /// - note: calling the completion on the action will advance the onboarding to the next page
36 | let action: OnboardPageAction?
37 |
38 | public init(title: String,
39 | imageName: String? = nil,
40 | description: String?,
41 | advanceButtonTitle: String = NSLocalizedString("Next", comment: ""),
42 | actionButtonTitle: String? = nil,
43 | action: OnboardPageAction? = nil) {
44 | self.title = title
45 | self.imageName = imageName
46 | self.description = description
47 | self.advanceButtonTitle = advanceButtonTitle
48 | self.actionButtonTitle = actionButtonTitle
49 | self.action = action
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Example/OnboardExample/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/OnboardKit.xcodeproj/xcshareddata/xcschemes/OnboardKit.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
49 |
50 |
51 |
52 |
53 |
54 |
64 |
65 |
71 |
72 |
73 |
74 |
75 |
76 |
82 |
83 |
89 |
90 |
91 |
92 |
94 |
95 |
98 |
99 |
100 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | [](https://developer.apple.com/swift/)
4 | [](http://cocoapods.org/pods/OnboardKit)
5 | [](http://cocoapods.org/pods/OnboardKit)
6 | [](https://github.com/Carthage/Carthage)
7 | [](https://twitter.com/NikolaKirev)
8 |
9 | # OnboardKit
10 | *Customizable user onboarding for your UIKit app in Swift*
11 |
12 | 
13 |
14 | ## Requirements
15 |
16 | * Swift 5.0
17 | * Xcode 10
18 | * iOS 11.0+
19 |
20 | ## Installation
21 |
22 | #### [Carthage](https://github.com/Carthage/Carthage)
23 |
24 | ````bash
25 | github "NikolaKirev/OnboardKit"
26 | ````
27 |
28 | #### [CocoaPods](http://cocoapods.org)
29 |
30 | ````ruby
31 | use_frameworks!
32 |
33 | # Latest release in CocoaPods
34 | pod 'OnboardKit'
35 |
36 | # Get the latest on master
37 | pod 'OnboardKit', :git => 'https://github.com/NikolaKirev/OnboardKit.git', :branch => 'master'
38 | ````
39 |
40 | Don't forget to `import OnboardKit` in the file you intend to use it.
41 |
42 | ## Usage
43 |
44 | 1. Create and populate a bunch of `OnboardPage` instances
45 | ````swift
46 | let page = OnboardPage(title: "Welcome to OnboardKit",
47 | imageName: "Onboarding1",
48 | description: "OnboardKit helps you add onboarding to your iOS app")
49 | ````
50 | 2. Create an `OnboardViewController`
51 | ````swift
52 | let onboardingViewController = OnboardViewController(pageItems: [pageOne, ...])
53 | ````
54 | 3. Present the view controller
55 | ````swift
56 | onboardingViewController.presentFrom(self, animated: true)
57 | ````
58 | (use this convenience method to make sure you present it modally)
59 |
60 | ## Customization
61 |
62 | 
63 |
64 | #### Customizing Fonts and Colors
65 | You can customize the look of your onboarding by changing the default colors and fonts.
66 |
67 | 1. Initialize an `AppearanceConfiguration` instance with the desired custom style properties
68 | ````swift
69 | let appearance = AppearanceConfiguration(tintColor: .orange,
70 | titleColor: .red,
71 | textColor: .white,
72 | backgroundColor: .black,
73 | imageContentMode: .scaleAspectFit,
74 | titleFont: UIFont.boldSystemFont(ofSize: 32.0),
75 | textFont: UIFont.boldSystemFont(ofSize: 17.0))
76 | ````
77 | 2. Pass the `AppearanceConfiguration` instance as a parameter when initialising an `OnboardViewController`
78 | ````swift
79 | let onboardingVC = OnboardViewController(pageItems: onboardingPages,
80 | appearanceConfiguration: appearance)
81 | ````
82 |
83 | ##### List of customizable properties:
84 | - `tintColor` - used for tinting the advance and action buttons
85 | - `titleColor` - used to set title color (textColor is used if not specified)
86 | - `textColor` - used to set description text color
87 | - `backgroundColor` - used to set view background color
88 | - `imageContentMode` - used to set the content mode of page imageViews
89 | - `titleFont` - used to set the title font (used for the action button font as well)
90 | - `textFont` - used to set the description text font (used for the advance button font as well)
91 | - `advanceButtonStyling` - a block used to customize the advance button
92 | - `actionButtonStyling` - a block used to customize the action button
93 |
94 | #### Customizing Buttons
95 | To customize the style of the advance and action buttons on each page of the onboarding flow, you can use a `ButtonStyling` closure.
96 |
97 | 1. Create the closure
98 | ````swift
99 | let advanceButtonStyling: OnboardViewController.ButtonStyling = { button in
100 | button.setTitleColor(UIColor.lightGray, for: .normal)
101 | button.titleLabel?.font = UIFont.systemFont(ofSize: 16.0, weight: .semibold)
102 | }
103 | ````
104 | 2. Pass the closure in the `AppearanceConfiguration` initializer
105 | ````swift
106 | let appearance = OnboardViewController.AppearanceConfiguration(tintColor: .orange,
107 | advanceButtonStyling: advanceButtonStyling)
108 | ````
109 |
110 | ## Author
111 |
112 | ### Nikola Kirev
113 |
114 | * Website: [http://nikolakirev.com](http://nikolakirev.com)
115 | * Twitter: [@NikolaKirev](http://twitter.com/nikolakirev)
116 |
117 | ## License
118 |
119 | OnboardKit is available under the MIT license. See the [LICENSE](https://github.com/NikolaKirev/OnboardKit/blob/master/LICENSE) file for more info.
120 |
--------------------------------------------------------------------------------
/Example/OnboardExample/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
28 |
35 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/Example/OnboardExample/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // OnboardExample
4 | //
5 |
6 | import UIKit
7 | import OnboardKit
8 |
9 | class ViewController: UIViewController {
10 |
11 | lazy var onboardingPages: [OnboardPage] = {
12 | let pageOne = OnboardPage(title: "Welcome to Habitat",
13 | imageName: "Onboarding1",
14 | description: "Habitat is an easy to use productivity app designed to keep you motivated.")
15 |
16 | let pageTwo = OnboardPage(title: "Habit Entries",
17 | imageName: "Onboarding2",
18 | description: "For each of your habits an entry is created for every day you need to complete it.")
19 |
20 | let pageThree = OnboardPage(title: "Marking and Tracking",
21 | imageName: "Onboarding3",
22 | description: "By marking entries as Done you can track your progress on the path to success.")
23 |
24 | let pageFour = OnboardPage(title: "Notifications",
25 | imageName: "Onboarding4",
26 | description: "Turn on notifications to get reminders and keep up with your goals.",
27 | advanceButtonTitle: "Decide Later",
28 | actionButtonTitle: "Enable Notifications",
29 | action: { [weak self] completion in
30 | self?.showAlert(completion)
31 | })
32 |
33 | let pageFive = OnboardPage(title: "All Ready",
34 | imageName: "Onboarding5",
35 | description: "You are all set up and ready to use Habitat. Begin by adding your first habit.",
36 | advanceButtonTitle: "Done")
37 |
38 | return [pageOne, pageTwo, pageThree, pageFour, pageFive]
39 | }()
40 |
41 | lazy var onboardingPagesAlternative: [OnboardPage] = {
42 | let pageOne = OnboardPage(title: "Welcome to Habitat",
43 | imageName: "Onboarding1_alt",
44 | description: "Habitat is an easy to use productivity app designed to keep you motivated.")
45 |
46 | let pageTwo = OnboardPage(title: "Habit Entries",
47 | imageName: "Onboarding2",
48 | description: "An entry is created for every day you need to complete each habit.")
49 |
50 | let pageThree = OnboardPage(title: "Marking and Tracking",
51 | imageName: "Onboarding3",
52 | description: "By marking entries as Done you can track your progress.")
53 |
54 | let pageFour = OnboardPage(title: "Notifications",
55 | imageName: "Onboarding4",
56 | description: "Turn on notifications to get reminders and keep up with your goals.",
57 | advanceButtonTitle: "Decide Later",
58 | actionButtonTitle: "Enable Notifications",
59 | action: { [weak self] completion in
60 | self?.showAlert(completion)
61 | })
62 |
63 | let pageFive = OnboardPage(title: "All Ready",
64 | imageName: "Onboarding5",
65 | description: "You are all set up and ready to use Habitat. Adding your first habit.",
66 | advanceButtonTitle: "Done")
67 |
68 | return [pageOne, pageTwo, pageThree, pageFour, pageFive]
69 | }()
70 |
71 | @IBAction func showOnboardingDefaultTapped(_ sender: Any) {
72 | let onboardingVC = OnboardViewController(pageItems: onboardingPages, completion: {
73 | print("onboarding complete")
74 | })
75 | onboardingVC.modalPresentationStyle = .formSheet
76 | onboardingVC.presentFrom(self, animated: true)
77 | }
78 |
79 | @IBAction func showOnboardingCustomTapped(_ sender: Any) {
80 | let tintColor = UIColor(red: 1.00, green: 0.52, blue: 0.40, alpha: 1.00)
81 | let titleColor = UIColor(red: 1.00, green: 0.35, blue: 0.43, alpha: 1.00)
82 | let boldTitleFont = UIFont.systemFont(ofSize: 32.0, weight: .bold)
83 | let mediumTextFont = UIFont.systemFont(ofSize: 17.0, weight: .semibold)
84 | let appearanceConfiguration = OnboardViewController.AppearanceConfiguration(tintColor: tintColor,
85 | titleColor: titleColor,
86 | textColor: .white,
87 | backgroundColor: .black,
88 | titleFont: boldTitleFont,
89 | textFont: mediumTextFont)
90 | let onboardingVC = OnboardViewController(pageItems: onboardingPagesAlternative,
91 | appearanceConfiguration: appearanceConfiguration)
92 | onboardingVC.modalPresentationStyle = .formSheet
93 | onboardingVC.presentFrom(self, animated: true)
94 | }
95 |
96 | @IBAction func showOnboardingStyledButtonsTapped(_ sender: Any) {
97 | let advanceButtonStyling: OnboardViewController.ButtonStyling = { button in
98 | button.setTitleColor(UIColor.lightGray, for: .normal)
99 | button.titleLabel?.font = UIFont.systemFont(ofSize: 16.0, weight: .semibold)
100 | }
101 | let actionButtonStyling: OnboardViewController.ButtonStyling = { button in
102 | button.setTitleColor(.black, for: .normal)
103 | button.titleLabel?.font = UIFont.systemFont(ofSize: 22.0, weight: .semibold)
104 | button.backgroundColor = UIColor(white: 0.95, alpha: 1.0)
105 | button.layer.cornerRadius = button.bounds.height / 2.0
106 | button.contentEdgeInsets = UIEdgeInsets(top: 8, left: 16, bottom: 8, right: 16)
107 | button.layer.shadowColor = UIColor.black.cgColor
108 | button.layer.shadowOffset = CGSize(width: 0.0, height: 1.0)
109 | button.layer.shadowRadius = 2.0
110 | button.layer.shadowOpacity = 0.2
111 | }
112 | let appearance = OnboardViewController.AppearanceConfiguration(advanceButtonStyling: advanceButtonStyling,
113 | actionButtonStyling: actionButtonStyling)
114 | let onboardingVC = OnboardViewController(pageItems: onboardingPages,
115 | appearanceConfiguration: appearance)
116 | onboardingVC.modalPresentationStyle = .formSheet
117 | onboardingVC.presentFrom(self, animated: true)
118 | }
119 |
120 | /// Only for the purpouses of the example.
121 | /// Not really asking for notifications permissions.
122 | private func showAlert(_ completion: @escaping (_ success: Bool, _ error: Error?) -> Void) {
123 | let alert = UIAlertController(title: "Allow Notifications?",
124 | message: "Habitat wants to send you notifications",
125 | preferredStyle: .alert)
126 | alert.addAction(UIAlertAction(title: "OK", style: .default) { _ in
127 | completion(true, nil)
128 | })
129 | alert.addAction(UIAlertAction(title: "Cancel", style: .cancel) { _ in
130 | completion(false, nil)
131 | })
132 | presentedViewController?.present(alert, animated: true)
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/OnboardKit/OnboardPageViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // OnboardPageViewController.swift
3 | // OnboardKit
4 | //
5 |
6 | import UIKit
7 |
8 | internal protocol OnboardPageViewControllerDelegate: class {
9 |
10 | /// Informs the `delegate` that the action button was tapped
11 | ///
12 | /// - Parameters:
13 | /// - pageVC: The `OnboardPageViewController` object
14 | /// - index: The page index
15 | func pageViewController(_ pageVC: OnboardPageViewController, actionTappedAt index: Int)
16 |
17 | /// Informs the `delegate` that the advance(next) button was tapped
18 | ///
19 | /// - Parameters:
20 | /// - pageVC: The `OnboardPageViewController` object
21 | /// - index: The page index
22 | func pageViewController(_ pageVC: OnboardPageViewController, advanceTappedAt index: Int)
23 | }
24 |
25 | internal final class OnboardPageViewController: UIViewController {
26 |
27 | private lazy var pageStackView: UIStackView = {
28 | let stackView = UIStackView()
29 | stackView.translatesAutoresizingMaskIntoConstraints = false
30 | stackView.spacing = 16.0
31 | stackView.axis = .vertical
32 | stackView.alignment = .center
33 | return stackView
34 | }()
35 |
36 | private lazy var titleLabel: UILabel = {
37 | let label = UILabel()
38 | label.translatesAutoresizingMaskIntoConstraints = false
39 | label.font = UIFont.preferredFont(forTextStyle: .title1)
40 | label.numberOfLines = 0
41 | label.textAlignment = .center
42 | return label
43 | }()
44 |
45 | private lazy var imageView: UIImageView = {
46 | let imageView = UIImageView()
47 | imageView.translatesAutoresizingMaskIntoConstraints = false
48 | return imageView
49 | }()
50 |
51 | private lazy var descriptionLabel: UILabel = {
52 | let label = UILabel()
53 | label.translatesAutoresizingMaskIntoConstraints = false
54 | label.font = UIFont.preferredFont(forTextStyle: .title3)
55 | label.numberOfLines = 0
56 | label.textAlignment = .center
57 | return label
58 | }()
59 |
60 | private lazy var actionButton: UIButton = {
61 | let button = UIButton()
62 | button.translatesAutoresizingMaskIntoConstraints = false
63 | button.titleLabel?.font = UIFont.preferredFont(forTextStyle: .title2)
64 | return button
65 | }()
66 |
67 | private lazy var advanceButton: UIButton = {
68 | let button = UIButton()
69 | button.translatesAutoresizingMaskIntoConstraints = false
70 | button.titleLabel?.font = UIFont.preferredFont(forTextStyle: .body)
71 | return button
72 | }()
73 |
74 | let pageIndex: Int
75 |
76 | weak var delegate: OnboardPageViewControllerDelegate?
77 |
78 | private let appearanceConfiguration: OnboardViewController.AppearanceConfiguration
79 |
80 | init(pageIndex: Int, appearanceConfiguration: OnboardViewController.AppearanceConfiguration) {
81 | self.pageIndex = pageIndex
82 | self.appearanceConfiguration = appearanceConfiguration
83 | super.init(nibName: nil, bundle: nil)
84 | customizeStyleWith(appearanceConfiguration)
85 | }
86 |
87 | required init?(coder aDecoder: NSCoder) {
88 | fatalError("init(coder:) has not been implemented")
89 | }
90 |
91 | private func customizeStyleWith(_ appearanceConfiguration: OnboardViewController.AppearanceConfiguration) {
92 | view.backgroundColor = appearanceConfiguration.backgroundColor
93 | // Setup imageView
94 | imageView.contentMode = appearanceConfiguration.imageContentMode
95 | // Style title
96 | titleLabel.textColor = appearanceConfiguration.titleColor
97 | titleLabel.font = appearanceConfiguration.titleFont
98 | // Style description
99 | descriptionLabel.textColor = appearanceConfiguration.textColor
100 | descriptionLabel.font = appearanceConfiguration.textFont
101 | }
102 |
103 | private func customizeButtonsWith(_ appearanceConfiguration: OnboardViewController.AppearanceConfiguration) {
104 | advanceButton.sizeToFit()
105 | if let advanceButtonStyling = appearanceConfiguration.advanceButtonStyling {
106 | advanceButtonStyling(advanceButton)
107 | } else {
108 | advanceButton.setTitleColor(appearanceConfiguration.tintColor, for: .normal)
109 | advanceButton.titleLabel?.font = appearanceConfiguration.textFont
110 | }
111 | actionButton.sizeToFit()
112 | if let actionButtonStyling = appearanceConfiguration.actionButtonStyling {
113 | actionButtonStyling(actionButton)
114 | } else {
115 | actionButton.setTitleColor(appearanceConfiguration.tintColor, for: .normal)
116 | actionButton.titleLabel?.font = appearanceConfiguration.titleFont
117 | }
118 | }
119 |
120 | override func loadView() {
121 | view = UIView(frame: CGRect.zero)
122 | view.addSubview(titleLabel)
123 | view.addSubview(pageStackView)
124 | NSLayoutConstraint.activate([
125 | titleLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
126 | titleLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 16.0),
127 | pageStackView.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 16.0),
128 | pageStackView.rightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.rightAnchor),
129 | pageStackView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
130 | pageStackView.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor)
131 | ])
132 | pageStackView.addArrangedSubview(imageView)
133 | pageStackView.addArrangedSubview(descriptionLabel)
134 | pageStackView.addArrangedSubview(actionButton)
135 | pageStackView.addArrangedSubview(advanceButton)
136 |
137 | actionButton.addTarget(self,
138 | action: #selector(OnboardPageViewController.actionTapped),
139 | for: .touchUpInside)
140 | advanceButton.addTarget(self,
141 | action: #selector(OnboardPageViewController.advanceTapped),
142 | for: .touchUpInside)
143 |
144 | }
145 |
146 | override func viewWillAppear(_ animated: Bool) {
147 | super.viewWillAppear(animated)
148 | customizeButtonsWith(appearanceConfiguration)
149 | }
150 |
151 | func configureWithPage(_ page: OnboardPage) {
152 | configureTitleLabel(page.title)
153 | configureImageView(page.imageName)
154 | configureDescriptionLabel(page.description)
155 | configureActionButton(page.actionButtonTitle, action: page.action)
156 | configureAdvanceButton(page.advanceButtonTitle)
157 | }
158 |
159 | private func configureTitleLabel(_ title: String) {
160 | titleLabel.text = title
161 | NSLayoutConstraint.activate([
162 | titleLabel.widthAnchor.constraint(equalTo: pageStackView.widthAnchor, multiplier: 0.8)
163 | ])
164 | }
165 |
166 | private func configureImageView(_ imageName: String?) {
167 | if let imageName = imageName, let image = UIImage(named: imageName) {
168 | imageView.image = image
169 | imageView.heightAnchor.constraint(equalTo: pageStackView.heightAnchor, multiplier: 0.5).isActive = true
170 | } else {
171 | imageView.isHidden = true
172 | }
173 | }
174 |
175 | private func configureDescriptionLabel(_ description: String?) {
176 | if let pageDescription = description {
177 | descriptionLabel.text = pageDescription
178 | NSLayoutConstraint.activate([
179 | descriptionLabel.heightAnchor.constraint(greaterThanOrEqualTo: pageStackView.heightAnchor, multiplier: 0.2),
180 | descriptionLabel.widthAnchor.constraint(equalTo: pageStackView.widthAnchor, multiplier: 0.8)
181 | ])
182 | } else {
183 | descriptionLabel.isHidden = true
184 | }
185 | }
186 |
187 | private func configureActionButton(_ title: String?, action: OnboardPageAction?) {
188 | if let actionButtonTitle = title {
189 | actionButton.setTitle(actionButtonTitle, for: .normal)
190 | } else {
191 | actionButton.isHidden = true
192 | }
193 | }
194 |
195 | private func configureAdvanceButton(_ title: String) {
196 | advanceButton.setTitle(title, for: .normal)
197 | }
198 |
199 | // MARK: - User Actions
200 | @objc fileprivate func actionTapped() {
201 | delegate?.pageViewController(self, actionTappedAt: pageIndex)
202 | }
203 |
204 | @objc fileprivate func advanceTapped() {
205 | delegate?.pageViewController(self, advanceTappedAt: pageIndex)
206 | }
207 | }
208 |
--------------------------------------------------------------------------------
/OnboardKit/OnboardViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // OnboardViewController.swift
3 | // OnboardKit
4 | //
5 |
6 | import UIKit
7 |
8 | /**
9 | */
10 | final public class OnboardViewController: UIViewController {
11 |
12 | private let pageViewController = UIPageViewController(transitionStyle: .scroll,
13 | navigationOrientation: .horizontal,
14 | options: nil)
15 | private let pageItems: [OnboardPage]
16 | private let appearanceConfiguration: AppearanceConfiguration
17 | private let completion: (() -> Void)?
18 |
19 | required public init?(coder: NSCoder) {
20 | fatalError("init(coder:) has not been implemented")
21 | }
22 |
23 | /// Initializes a new `OnboardViewController` to be presented
24 | /// The onboard view controller encapsulates the whole onboarding flow
25 | ///
26 | /// - Parameters:
27 | /// - pageItems: An array of `OnboardPage` items
28 | /// - appearanceConfiguration: An optional configuration struct for appearance customization
29 | /// - completion: An optional completion block that gets executed when the onboarding VC is dismissed
30 | public init(pageItems: [OnboardPage],
31 | appearanceConfiguration: AppearanceConfiguration = AppearanceConfiguration(),
32 | completion: (() -> Void)? = nil) {
33 | self.pageItems = pageItems
34 | self.appearanceConfiguration = appearanceConfiguration
35 | self.completion = completion
36 | super.init(nibName: nil, bundle: nil)
37 | }
38 |
39 | override public var supportedInterfaceOrientations: UIInterfaceOrientationMask {
40 | return .portrait
41 | }
42 |
43 | override public func loadView() {
44 | view = UIView(frame: CGRect.zero)
45 | view.backgroundColor = appearanceConfiguration.backgroundColor
46 | pageViewController.setViewControllers([pageViwControllerFor(pageIndex: 0)!],
47 | direction: .forward,
48 | animated: false,
49 | completion: nil)
50 | pageViewController.dataSource = self
51 | pageViewController.delegate = self
52 | pageViewController.view.frame = view.bounds
53 |
54 | let pageControlApperance = UIPageControl.appearance(whenContainedInInstancesOf: [OnboardViewController.self])
55 | pageControlApperance.pageIndicatorTintColor = appearanceConfiguration.tintColor.withAlphaComponent(0.3)
56 | pageControlApperance.currentPageIndicatorTintColor = appearanceConfiguration.tintColor
57 |
58 | addChild(pageViewController)
59 | view.addSubview(pageViewController.view)
60 | pageViewController.didMove(toParent: self)
61 | }
62 |
63 | private func pageViwControllerFor(pageIndex: Int) -> OnboardPageViewController? {
64 | let pageVC = OnboardPageViewController(pageIndex: pageIndex, appearanceConfiguration: appearanceConfiguration)
65 | guard pageIndex >= 0 else { return nil }
66 | guard pageIndex < pageItems.count else { return nil }
67 | pageVC.delegate = self
68 | pageVC.configureWithPage(pageItems[pageIndex])
69 | return pageVC
70 | }
71 |
72 | private func advanceToPageWithIndex(_ pageIndex: Int) {
73 | DispatchQueue.main.async { [weak self] in
74 | guard let nextPage = self?.pageViwControllerFor(pageIndex: pageIndex) else { return }
75 | self?.pageViewController.setViewControllers([nextPage],
76 | direction: .forward,
77 | animated: true,
78 | completion: nil)
79 | }
80 | }
81 | }
82 |
83 | // MARK: Presenting
84 | public extension OnboardViewController {
85 |
86 | /// Presents the configured `OnboardViewController`
87 | ///
88 | /// - Parameters:
89 | /// - viewController: the presenting view controller
90 | /// - animated: Defines if the presentation should be animated
91 | func presentFrom(_ viewController: UIViewController, animated: Bool) {
92 | viewController.present(self, animated: animated)
93 | }
94 | }
95 |
96 | extension OnboardViewController: UIPageViewControllerDataSource {
97 |
98 | public func pageViewController(_ pageViewController: UIPageViewController,
99 | viewControllerBefore viewController: UIViewController) -> UIViewController? {
100 | guard let pageVC = viewController as? OnboardPageViewController else { return nil }
101 | let pageIndex = pageVC.pageIndex
102 | guard pageIndex != 0 else { return nil }
103 | return pageViwControllerFor(pageIndex: pageIndex - 1)
104 | }
105 |
106 | public func pageViewController(_ pageViewController: UIPageViewController,
107 | viewControllerAfter viewController: UIViewController) -> UIViewController? {
108 | guard let pageVC = viewController as? OnboardPageViewController else { return nil }
109 | let pageIndex = pageVC.pageIndex
110 | return pageViwControllerFor(pageIndex: pageIndex + 1)
111 | }
112 |
113 | public func presentationCount(for pageViewController: UIPageViewController) -> Int {
114 | return pageItems.count
115 | }
116 |
117 | public func presentationIndex(for pageViewController: UIPageViewController) -> Int {
118 | if let currentPage = pageViewController.viewControllers?.first as? OnboardPageViewController {
119 | return currentPage.pageIndex
120 | }
121 | return 0
122 | }
123 | }
124 |
125 | extension OnboardViewController: UIPageViewControllerDelegate {
126 |
127 | }
128 |
129 | extension OnboardViewController: OnboardPageViewControllerDelegate {
130 |
131 | func pageViewController(_ pageVC: OnboardPageViewController, actionTappedAt index: Int) {
132 | if let pageAction = pageItems[index].action {
133 | pageAction({ (success, error) in
134 | guard error == nil else { return }
135 | if success {
136 | self.advanceToPageWithIndex(index + 1)
137 | }
138 | })
139 | }
140 | }
141 |
142 | func pageViewController(_ pageVC: OnboardPageViewController, advanceTappedAt index: Int) {
143 | if index == pageItems.count - 1 {
144 | dismiss(animated: true, completion: self.completion)
145 | } else {
146 | advanceToPageWithIndex(index + 1)
147 | }
148 | }
149 | }
150 |
151 | // MARK: - AppearanceConfiguration
152 | public extension OnboardViewController {
153 |
154 | typealias ButtonStyling = ((UIButton) -> Void)
155 |
156 | struct AppearanceConfiguration {
157 | /// The color used for the page indicator and buttons
158 | ///
159 | /// - note: Defualts to the blue tint color used troughout iOS
160 | let tintColor: UIColor
161 |
162 | /// The color used for the title text
163 | ///
164 | /// - note: If not specified, defualts to whatever `textColor` is
165 | let titleColor: UIColor
166 |
167 | /// The color used for the description text (and title text `titleColor` if not set)
168 | ///
169 | /// - note: Defualts to `.darkText`
170 | let textColor: UIColor
171 |
172 | /// The color used for onboarding background
173 | ///
174 | /// - note: Defualts to white
175 | let backgroundColor: UIColor
176 |
177 | /// The `contentMode` used for the slide imageView
178 | ///
179 | /// - note: Defualts to white
180 | let imageContentMode: UIView.ContentMode
181 |
182 | /// The font used for the title and action button
183 | ///
184 | /// - note: Defualts to preferred text style `.title1` (supports dinamyc type)
185 | let titleFont: UIFont
186 |
187 | /// The font used for the desctiption label and advance button
188 | ///
189 | /// - note: Defualts to preferred text style `.body` (supports dinamyc type)
190 | let textFont: UIFont
191 |
192 | /// A Swift closure used to expose and customize the button used to advance to the next page
193 | ///
194 | /// - note: Defualts to nil. If not used, the button will be customized based on the tint and text properties
195 | let advanceButtonStyling: ButtonStyling?
196 |
197 | /// A Swift closure used to expose and customize the button used to trigger page specific action
198 | ///
199 | /// - note: Defualts to nil. If not used, the button will be customized based on the title properties
200 | let actionButtonStyling: ButtonStyling?
201 |
202 | public init(tintColor: UIColor = UIColor(red: 0.0, green: 122.0/255.0, blue: 1.0, alpha: 1.0),
203 | titleColor: UIColor? = nil,
204 | textColor: UIColor = .darkText,
205 | backgroundColor: UIColor = .white,
206 | imageContentMode: UIView.ContentMode = .center,
207 | titleFont: UIFont = UIFont.preferredFont(forTextStyle: .title1),
208 | textFont: UIFont = UIFont.preferredFont(forTextStyle: .body),
209 | advanceButtonStyling: ButtonStyling? = nil,
210 | actionButtonStyling: ButtonStyling? = nil) {
211 | self.tintColor = tintColor
212 | self.titleColor = titleColor ?? textColor
213 | self.textColor = textColor
214 | self.backgroundColor = backgroundColor
215 | self.imageContentMode = imageContentMode
216 | self.titleFont = titleFont
217 | self.textFont = textFont
218 | self.advanceButtonStyling = advanceButtonStyling
219 | self.actionButtonStyling = actionButtonStyling
220 | }
221 | }
222 | }
223 |
--------------------------------------------------------------------------------
/Example/OnboardExample.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 50;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 9497BC2820D701F800CCC791 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9497BC2720D701F800CCC791 /* AppDelegate.swift */; };
11 | 9497BC2A20D701F800CCC791 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9497BC2920D701F800CCC791 /* ViewController.swift */; };
12 | 9497BC2D20D701F800CCC791 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9497BC2B20D701F800CCC791 /* Main.storyboard */; };
13 | 9497BC2F20D701F900CCC791 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9497BC2E20D701F900CCC791 /* Assets.xcassets */; };
14 | 9497BC3220D701F900CCC791 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9497BC3020D701F900CCC791 /* LaunchScreen.storyboard */; };
15 | 9497BC4120D7029D00CCC791 /* OnboardKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9497BC4020D7029D00CCC791 /* OnboardKit.framework */; };
16 | /* End PBXBuildFile section */
17 |
18 | /* Begin PBXFileReference section */
19 | 9497BC2420D701F800CCC791 /* OnboardExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OnboardExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
20 | 9497BC2720D701F800CCC791 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
21 | 9497BC2920D701F800CCC791 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
22 | 9497BC2C20D701F800CCC791 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
23 | 9497BC2E20D701F900CCC791 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
24 | 9497BC3120D701F900CCC791 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
25 | 9497BC3320D701F900CCC791 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
26 | 9497BC4020D7029D00CCC791 /* OnboardKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = OnboardKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
27 | /* End PBXFileReference section */
28 |
29 | /* Begin PBXFrameworksBuildPhase section */
30 | 9497BC2120D701F800CCC791 /* Frameworks */ = {
31 | isa = PBXFrameworksBuildPhase;
32 | buildActionMask = 2147483647;
33 | files = (
34 | 9497BC4120D7029D00CCC791 /* OnboardKit.framework in Frameworks */,
35 | );
36 | runOnlyForDeploymentPostprocessing = 0;
37 | };
38 | /* End PBXFrameworksBuildPhase section */
39 |
40 | /* Begin PBXGroup section */
41 | 9497BC1B20D701F800CCC791 = {
42 | isa = PBXGroup;
43 | children = (
44 | 9497BC2620D701F800CCC791 /* OnboardExample */,
45 | 9497BC2520D701F800CCC791 /* Products */,
46 | 9497BC3F20D7029D00CCC791 /* Frameworks */,
47 | );
48 | sourceTree = "";
49 | };
50 | 9497BC2520D701F800CCC791 /* Products */ = {
51 | isa = PBXGroup;
52 | children = (
53 | 9497BC2420D701F800CCC791 /* OnboardExample.app */,
54 | );
55 | name = Products;
56 | sourceTree = "";
57 | };
58 | 9497BC2620D701F800CCC791 /* OnboardExample */ = {
59 | isa = PBXGroup;
60 | children = (
61 | 9497BC2720D701F800CCC791 /* AppDelegate.swift */,
62 | 9497BC2920D701F800CCC791 /* ViewController.swift */,
63 | 9497BC2B20D701F800CCC791 /* Main.storyboard */,
64 | 9497BC2E20D701F900CCC791 /* Assets.xcassets */,
65 | 9497BC3020D701F900CCC791 /* LaunchScreen.storyboard */,
66 | 9497BC3320D701F900CCC791 /* Info.plist */,
67 | );
68 | path = OnboardExample;
69 | sourceTree = "";
70 | };
71 | 9497BC3F20D7029D00CCC791 /* Frameworks */ = {
72 | isa = PBXGroup;
73 | children = (
74 | 9497BC4020D7029D00CCC791 /* OnboardKit.framework */,
75 | );
76 | name = Frameworks;
77 | sourceTree = "";
78 | };
79 | /* End PBXGroup section */
80 |
81 | /* Begin PBXNativeTarget section */
82 | 9497BC2320D701F800CCC791 /* OnboardExample */ = {
83 | isa = PBXNativeTarget;
84 | buildConfigurationList = 9497BC3620D701F900CCC791 /* Build configuration list for PBXNativeTarget "OnboardExample" */;
85 | buildPhases = (
86 | 9497BC2020D701F800CCC791 /* Sources */,
87 | 9497BC2120D701F800CCC791 /* Frameworks */,
88 | 9497BC2220D701F800CCC791 /* Resources */,
89 | );
90 | buildRules = (
91 | );
92 | dependencies = (
93 | );
94 | name = OnboardExample;
95 | productName = OnboardExample;
96 | productReference = 9497BC2420D701F800CCC791 /* OnboardExample.app */;
97 | productType = "com.apple.product-type.application";
98 | };
99 | /* End PBXNativeTarget section */
100 |
101 | /* Begin PBXProject section */
102 | 9497BC1C20D701F800CCC791 /* Project object */ = {
103 | isa = PBXProject;
104 | attributes = {
105 | LastSwiftUpdateCheck = 0940;
106 | LastUpgradeCheck = 0940;
107 | TargetAttributes = {
108 | 9497BC2320D701F800CCC791 = {
109 | CreatedOnToolsVersion = 9.4;
110 | LastSwiftMigration = 1020;
111 | };
112 | };
113 | };
114 | buildConfigurationList = 9497BC1F20D701F800CCC791 /* Build configuration list for PBXProject "OnboardExample" */;
115 | compatibilityVersion = "Xcode 9.3";
116 | developmentRegion = en;
117 | hasScannedForEncodings = 0;
118 | knownRegions = (
119 | en,
120 | Base,
121 | );
122 | mainGroup = 9497BC1B20D701F800CCC791;
123 | productRefGroup = 9497BC2520D701F800CCC791 /* Products */;
124 | projectDirPath = "";
125 | projectRoot = "";
126 | targets = (
127 | 9497BC2320D701F800CCC791 /* OnboardExample */,
128 | );
129 | };
130 | /* End PBXProject section */
131 |
132 | /* Begin PBXResourcesBuildPhase section */
133 | 9497BC2220D701F800CCC791 /* Resources */ = {
134 | isa = PBXResourcesBuildPhase;
135 | buildActionMask = 2147483647;
136 | files = (
137 | 9497BC3220D701F900CCC791 /* LaunchScreen.storyboard in Resources */,
138 | 9497BC2F20D701F900CCC791 /* Assets.xcassets in Resources */,
139 | 9497BC2D20D701F800CCC791 /* Main.storyboard in Resources */,
140 | );
141 | runOnlyForDeploymentPostprocessing = 0;
142 | };
143 | /* End PBXResourcesBuildPhase section */
144 |
145 | /* Begin PBXSourcesBuildPhase section */
146 | 9497BC2020D701F800CCC791 /* Sources */ = {
147 | isa = PBXSourcesBuildPhase;
148 | buildActionMask = 2147483647;
149 | files = (
150 | 9497BC2A20D701F800CCC791 /* ViewController.swift in Sources */,
151 | 9497BC2820D701F800CCC791 /* AppDelegate.swift in Sources */,
152 | );
153 | runOnlyForDeploymentPostprocessing = 0;
154 | };
155 | /* End PBXSourcesBuildPhase section */
156 |
157 | /* Begin PBXVariantGroup section */
158 | 9497BC2B20D701F800CCC791 /* Main.storyboard */ = {
159 | isa = PBXVariantGroup;
160 | children = (
161 | 9497BC2C20D701F800CCC791 /* Base */,
162 | );
163 | name = Main.storyboard;
164 | sourceTree = "";
165 | };
166 | 9497BC3020D701F900CCC791 /* LaunchScreen.storyboard */ = {
167 | isa = PBXVariantGroup;
168 | children = (
169 | 9497BC3120D701F900CCC791 /* Base */,
170 | );
171 | name = LaunchScreen.storyboard;
172 | sourceTree = "";
173 | };
174 | /* End PBXVariantGroup section */
175 |
176 | /* Begin XCBuildConfiguration section */
177 | 9497BC3420D701F900CCC791 /* Debug */ = {
178 | isa = XCBuildConfiguration;
179 | buildSettings = {
180 | ALWAYS_SEARCH_USER_PATHS = NO;
181 | CLANG_ANALYZER_NONNULL = YES;
182 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
183 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
184 | CLANG_CXX_LIBRARY = "libc++";
185 | CLANG_ENABLE_MODULES = YES;
186 | CLANG_ENABLE_OBJC_ARC = YES;
187 | CLANG_ENABLE_OBJC_WEAK = YES;
188 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
189 | CLANG_WARN_BOOL_CONVERSION = YES;
190 | CLANG_WARN_COMMA = YES;
191 | CLANG_WARN_CONSTANT_CONVERSION = YES;
192 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
193 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
194 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
195 | CLANG_WARN_EMPTY_BODY = YES;
196 | CLANG_WARN_ENUM_CONVERSION = YES;
197 | CLANG_WARN_INFINITE_RECURSION = YES;
198 | CLANG_WARN_INT_CONVERSION = YES;
199 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
200 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
201 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
202 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
203 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
204 | CLANG_WARN_STRICT_PROTOTYPES = YES;
205 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
206 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
207 | CLANG_WARN_UNREACHABLE_CODE = YES;
208 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
209 | CODE_SIGN_IDENTITY = "iPhone Developer";
210 | COPY_PHASE_STRIP = NO;
211 | DEBUG_INFORMATION_FORMAT = dwarf;
212 | ENABLE_STRICT_OBJC_MSGSEND = YES;
213 | ENABLE_TESTABILITY = YES;
214 | GCC_C_LANGUAGE_STANDARD = gnu11;
215 | GCC_DYNAMIC_NO_PIC = NO;
216 | GCC_NO_COMMON_BLOCKS = YES;
217 | GCC_OPTIMIZATION_LEVEL = 0;
218 | GCC_PREPROCESSOR_DEFINITIONS = (
219 | "DEBUG=1",
220 | "$(inherited)",
221 | );
222 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
223 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
224 | GCC_WARN_UNDECLARED_SELECTOR = YES;
225 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
226 | GCC_WARN_UNUSED_FUNCTION = YES;
227 | GCC_WARN_UNUSED_VARIABLE = YES;
228 | IPHONEOS_DEPLOYMENT_TARGET = 11.4;
229 | MTL_ENABLE_DEBUG_INFO = YES;
230 | ONLY_ACTIVE_ARCH = YES;
231 | SDKROOT = iphoneos;
232 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
233 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
234 | };
235 | name = Debug;
236 | };
237 | 9497BC3520D701F900CCC791 /* Release */ = {
238 | isa = XCBuildConfiguration;
239 | buildSettings = {
240 | ALWAYS_SEARCH_USER_PATHS = NO;
241 | CLANG_ANALYZER_NONNULL = YES;
242 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
243 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
244 | CLANG_CXX_LIBRARY = "libc++";
245 | CLANG_ENABLE_MODULES = YES;
246 | CLANG_ENABLE_OBJC_ARC = YES;
247 | CLANG_ENABLE_OBJC_WEAK = YES;
248 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
249 | CLANG_WARN_BOOL_CONVERSION = YES;
250 | CLANG_WARN_COMMA = YES;
251 | CLANG_WARN_CONSTANT_CONVERSION = YES;
252 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
253 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
254 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
255 | CLANG_WARN_EMPTY_BODY = YES;
256 | CLANG_WARN_ENUM_CONVERSION = YES;
257 | CLANG_WARN_INFINITE_RECURSION = YES;
258 | CLANG_WARN_INT_CONVERSION = YES;
259 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
260 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
261 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
262 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
263 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
264 | CLANG_WARN_STRICT_PROTOTYPES = YES;
265 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
266 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
267 | CLANG_WARN_UNREACHABLE_CODE = YES;
268 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
269 | CODE_SIGN_IDENTITY = "iPhone Developer";
270 | COPY_PHASE_STRIP = NO;
271 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
272 | ENABLE_NS_ASSERTIONS = NO;
273 | ENABLE_STRICT_OBJC_MSGSEND = YES;
274 | GCC_C_LANGUAGE_STANDARD = gnu11;
275 | GCC_NO_COMMON_BLOCKS = YES;
276 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
277 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
278 | GCC_WARN_UNDECLARED_SELECTOR = YES;
279 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
280 | GCC_WARN_UNUSED_FUNCTION = YES;
281 | GCC_WARN_UNUSED_VARIABLE = YES;
282 | IPHONEOS_DEPLOYMENT_TARGET = 11.4;
283 | MTL_ENABLE_DEBUG_INFO = NO;
284 | SDKROOT = iphoneos;
285 | SWIFT_COMPILATION_MODE = wholemodule;
286 | SWIFT_OPTIMIZATION_LEVEL = "-O";
287 | VALIDATE_PRODUCT = YES;
288 | };
289 | name = Release;
290 | };
291 | 9497BC3720D701F900CCC791 /* Debug */ = {
292 | isa = XCBuildConfiguration;
293 | buildSettings = {
294 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
295 | CODE_SIGN_STYLE = Manual;
296 | DEVELOPMENT_TEAM = "";
297 | INFOPLIST_FILE = OnboardExample/Info.plist;
298 | LD_RUNPATH_SEARCH_PATHS = (
299 | "$(inherited)",
300 | "@executable_path/Frameworks",
301 | );
302 | PRODUCT_BUNDLE_IDENTIFIER = com.onboardkit.OnboardExample;
303 | PRODUCT_NAME = "$(TARGET_NAME)";
304 | PROVISIONING_PROFILE_SPECIFIER = "";
305 | SWIFT_VERSION = 5.0;
306 | TARGETED_DEVICE_FAMILY = "1,2";
307 | };
308 | name = Debug;
309 | };
310 | 9497BC3820D701F900CCC791 /* Release */ = {
311 | isa = XCBuildConfiguration;
312 | buildSettings = {
313 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
314 | CODE_SIGN_STYLE = Manual;
315 | DEVELOPMENT_TEAM = "";
316 | INFOPLIST_FILE = OnboardExample/Info.plist;
317 | LD_RUNPATH_SEARCH_PATHS = (
318 | "$(inherited)",
319 | "@executable_path/Frameworks",
320 | );
321 | PRODUCT_BUNDLE_IDENTIFIER = com.onboardkit.OnboardExample;
322 | PRODUCT_NAME = "$(TARGET_NAME)";
323 | PROVISIONING_PROFILE_SPECIFIER = "";
324 | SWIFT_VERSION = 5.0;
325 | TARGETED_DEVICE_FAMILY = "1,2";
326 | };
327 | name = Release;
328 | };
329 | /* End XCBuildConfiguration section */
330 |
331 | /* Begin XCConfigurationList section */
332 | 9497BC1F20D701F800CCC791 /* Build configuration list for PBXProject "OnboardExample" */ = {
333 | isa = XCConfigurationList;
334 | buildConfigurations = (
335 | 9497BC3420D701F900CCC791 /* Debug */,
336 | 9497BC3520D701F900CCC791 /* Release */,
337 | );
338 | defaultConfigurationIsVisible = 0;
339 | defaultConfigurationName = Release;
340 | };
341 | 9497BC3620D701F900CCC791 /* Build configuration list for PBXNativeTarget "OnboardExample" */ = {
342 | isa = XCConfigurationList;
343 | buildConfigurations = (
344 | 9497BC3720D701F900CCC791 /* Debug */,
345 | 9497BC3820D701F900CCC791 /* Release */,
346 | );
347 | defaultConfigurationIsVisible = 0;
348 | defaultConfigurationName = Release;
349 | };
350 | /* End XCConfigurationList section */
351 | };
352 | rootObject = 9497BC1C20D701F800CCC791 /* Project object */;
353 | }
354 |
--------------------------------------------------------------------------------
/OnboardKit.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 9437E2AF1F238E7E00E294BE /* OnboardKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9437E2A51F238E7E00E294BE /* OnboardKit.framework */; };
11 | 9437E2C91F23920800E294BE /* OnboardViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9437E2C41F23920800E294BE /* OnboardViewController.swift */; };
12 | 9437E2CB1F23920800E294BE /* OnboardPageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9437E2C61F23920800E294BE /* OnboardPageViewController.swift */; };
13 | 9437E2CC1F23920800E294BE /* OnboardPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9437E2C71F23920800E294BE /* OnboardPage.swift */; };
14 | 9449158B1F23D4D300191E79 /* OnboardKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 9449158A1F23D4D300191E79 /* OnboardKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
15 | 94FF39BE217B237C005AA773 /* AppearanceConfigurationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94FF39BD217B237C005AA773 /* AppearanceConfigurationTests.swift */; };
16 | /* End PBXBuildFile section */
17 |
18 | /* Begin PBXContainerItemProxy section */
19 | 9437E2B01F238E7E00E294BE /* PBXContainerItemProxy */ = {
20 | isa = PBXContainerItemProxy;
21 | containerPortal = 9437E29C1F238E7E00E294BE /* Project object */;
22 | proxyType = 1;
23 | remoteGlobalIDString = 9437E2A41F238E7E00E294BE;
24 | remoteInfo = OnboardKit;
25 | };
26 | /* End PBXContainerItemProxy section */
27 |
28 | /* Begin PBXFileReference section */
29 | 9416058D22843B270028102B /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; };
30 | 9437E2A51F238E7E00E294BE /* OnboardKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = OnboardKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
31 | 9437E2AE1F238E7E00E294BE /* OnboardKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OnboardKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
32 | 9437E2B51F238E7E00E294BE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
33 | 9437E2C11F2391F700E294BE /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
34 | 9437E2C41F23920800E294BE /* OnboardViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnboardViewController.swift; sourceTree = ""; };
35 | 9437E2C61F23920800E294BE /* OnboardPageViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnboardPageViewController.swift; sourceTree = ""; };
36 | 9437E2C71F23920800E294BE /* OnboardPage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnboardPage.swift; sourceTree = ""; };
37 | 9449158A1F23D4D300191E79 /* OnboardKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OnboardKit.h; sourceTree = ""; };
38 | 94FF39BD217B237C005AA773 /* AppearanceConfigurationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppearanceConfigurationTests.swift; sourceTree = ""; };
39 | /* End PBXFileReference section */
40 |
41 | /* Begin PBXFrameworksBuildPhase section */
42 | 9437E2A11F238E7E00E294BE /* Frameworks */ = {
43 | isa = PBXFrameworksBuildPhase;
44 | buildActionMask = 2147483647;
45 | files = (
46 | );
47 | runOnlyForDeploymentPostprocessing = 0;
48 | };
49 | 9437E2AB1F238E7E00E294BE /* Frameworks */ = {
50 | isa = PBXFrameworksBuildPhase;
51 | buildActionMask = 2147483647;
52 | files = (
53 | 9437E2AF1F238E7E00E294BE /* OnboardKit.framework in Frameworks */,
54 | );
55 | runOnlyForDeploymentPostprocessing = 0;
56 | };
57 | /* End PBXFrameworksBuildPhase section */
58 |
59 | /* Begin PBXGroup section */
60 | 9437E29B1F238E7E00E294BE = {
61 | isa = PBXGroup;
62 | children = (
63 | 9416058D22843B270028102B /* README.md */,
64 | 9437E2A71F238E7E00E294BE /* OnboardKit */,
65 | 9437E2BF1F23913600E294BE /* Metadata */,
66 | 9437E2B21F238E7E00E294BE /* OnboardKitTests */,
67 | 9437E2A61F238E7E00E294BE /* Products */,
68 | );
69 | sourceTree = "";
70 | };
71 | 9437E2A61F238E7E00E294BE /* Products */ = {
72 | isa = PBXGroup;
73 | children = (
74 | 9437E2A51F238E7E00E294BE /* OnboardKit.framework */,
75 | 9437E2AE1F238E7E00E294BE /* OnboardKitTests.xctest */,
76 | );
77 | name = Products;
78 | sourceTree = "";
79 | };
80 | 9437E2A71F238E7E00E294BE /* OnboardKit */ = {
81 | isa = PBXGroup;
82 | children = (
83 | 9437E2C41F23920800E294BE /* OnboardViewController.swift */,
84 | 9437E2C61F23920800E294BE /* OnboardPageViewController.swift */,
85 | 9437E2C71F23920800E294BE /* OnboardPage.swift */,
86 | );
87 | path = OnboardKit;
88 | sourceTree = "";
89 | };
90 | 9437E2B21F238E7E00E294BE /* OnboardKitTests */ = {
91 | isa = PBXGroup;
92 | children = (
93 | 94FF39BD217B237C005AA773 /* AppearanceConfigurationTests.swift */,
94 | 9437E2B51F238E7E00E294BE /* Info.plist */,
95 | );
96 | path = OnboardKitTests;
97 | sourceTree = "";
98 | };
99 | 9437E2BF1F23913600E294BE /* Metadata */ = {
100 | isa = PBXGroup;
101 | children = (
102 | 9449158A1F23D4D300191E79 /* OnboardKit.h */,
103 | 9437E2C11F2391F700E294BE /* Info.plist */,
104 | );
105 | path = Metadata;
106 | sourceTree = "";
107 | };
108 | /* End PBXGroup section */
109 |
110 | /* Begin PBXHeadersBuildPhase section */
111 | 9437E2A21F238E7E00E294BE /* Headers */ = {
112 | isa = PBXHeadersBuildPhase;
113 | buildActionMask = 2147483647;
114 | files = (
115 | 9449158B1F23D4D300191E79 /* OnboardKit.h in Headers */,
116 | );
117 | runOnlyForDeploymentPostprocessing = 0;
118 | };
119 | /* End PBXHeadersBuildPhase section */
120 |
121 | /* Begin PBXNativeTarget section */
122 | 9437E2A41F238E7E00E294BE /* OnboardKit */ = {
123 | isa = PBXNativeTarget;
124 | buildConfigurationList = 9437E2B91F238E7E00E294BE /* Build configuration list for PBXNativeTarget "OnboardKit" */;
125 | buildPhases = (
126 | 9437E2A01F238E7E00E294BE /* Sources */,
127 | 9437E2A11F238E7E00E294BE /* Frameworks */,
128 | 9437E2A21F238E7E00E294BE /* Headers */,
129 | 9437E2A31F238E7E00E294BE /* Resources */,
130 | 94938724201F1F2400EF9415 /* Swift Lint */,
131 | );
132 | buildRules = (
133 | );
134 | dependencies = (
135 | );
136 | name = OnboardKit;
137 | productName = OnboardKit;
138 | productReference = 9437E2A51F238E7E00E294BE /* OnboardKit.framework */;
139 | productType = "com.apple.product-type.framework";
140 | };
141 | 9437E2AD1F238E7E00E294BE /* OnboardKitTests */ = {
142 | isa = PBXNativeTarget;
143 | buildConfigurationList = 9437E2BC1F238E7E00E294BE /* Build configuration list for PBXNativeTarget "OnboardKitTests" */;
144 | buildPhases = (
145 | 9437E2AA1F238E7E00E294BE /* Sources */,
146 | 9437E2AB1F238E7E00E294BE /* Frameworks */,
147 | 9437E2AC1F238E7E00E294BE /* Resources */,
148 | );
149 | buildRules = (
150 | );
151 | dependencies = (
152 | 9437E2B11F238E7E00E294BE /* PBXTargetDependency */,
153 | );
154 | name = OnboardKitTests;
155 | productName = OnboardKitTests;
156 | productReference = 9437E2AE1F238E7E00E294BE /* OnboardKitTests.xctest */;
157 | productType = "com.apple.product-type.bundle.unit-test";
158 | };
159 | /* End PBXNativeTarget section */
160 |
161 | /* Begin PBXProject section */
162 | 9437E29C1F238E7E00E294BE /* Project object */ = {
163 | isa = PBXProject;
164 | attributes = {
165 | LastSwiftUpdateCheck = 0830;
166 | LastUpgradeCheck = 1020;
167 | ORGANIZATIONNAME = "Nikola Kirev";
168 | TargetAttributes = {
169 | 9437E2A41F238E7E00E294BE = {
170 | CreatedOnToolsVersion = 8.3.3;
171 | LastSwiftMigration = 1020;
172 | ProvisioningStyle = Manual;
173 | };
174 | 9437E2AD1F238E7E00E294BE = {
175 | CreatedOnToolsVersion = 8.3.3;
176 | DevelopmentTeam = 5Z8M29P3V9;
177 | LastSwiftMigration = 1020;
178 | ProvisioningStyle = Manual;
179 | };
180 | };
181 | };
182 | buildConfigurationList = 9437E29F1F238E7E00E294BE /* Build configuration list for PBXProject "OnboardKit" */;
183 | compatibilityVersion = "Xcode 3.2";
184 | developmentRegion = en;
185 | hasScannedForEncodings = 0;
186 | knownRegions = (
187 | en,
188 | Base,
189 | );
190 | mainGroup = 9437E29B1F238E7E00E294BE;
191 | productRefGroup = 9437E2A61F238E7E00E294BE /* Products */;
192 | projectDirPath = "";
193 | projectRoot = "";
194 | targets = (
195 | 9437E2A41F238E7E00E294BE /* OnboardKit */,
196 | 9437E2AD1F238E7E00E294BE /* OnboardKitTests */,
197 | );
198 | };
199 | /* End PBXProject section */
200 |
201 | /* Begin PBXResourcesBuildPhase section */
202 | 9437E2A31F238E7E00E294BE /* Resources */ = {
203 | isa = PBXResourcesBuildPhase;
204 | buildActionMask = 2147483647;
205 | files = (
206 | );
207 | runOnlyForDeploymentPostprocessing = 0;
208 | };
209 | 9437E2AC1F238E7E00E294BE /* Resources */ = {
210 | isa = PBXResourcesBuildPhase;
211 | buildActionMask = 2147483647;
212 | files = (
213 | );
214 | runOnlyForDeploymentPostprocessing = 0;
215 | };
216 | /* End PBXResourcesBuildPhase section */
217 |
218 | /* Begin PBXShellScriptBuildPhase section */
219 | 94938724201F1F2400EF9415 /* Swift Lint */ = {
220 | isa = PBXShellScriptBuildPhase;
221 | buildActionMask = 2147483647;
222 | files = (
223 | );
224 | inputPaths = (
225 | );
226 | name = "Swift Lint";
227 | outputPaths = (
228 | );
229 | runOnlyForDeploymentPostprocessing = 0;
230 | shellPath = /bin/sh;
231 | shellScript = "if which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n";
232 | };
233 | /* End PBXShellScriptBuildPhase section */
234 |
235 | /* Begin PBXSourcesBuildPhase section */
236 | 9437E2A01F238E7E00E294BE /* Sources */ = {
237 | isa = PBXSourcesBuildPhase;
238 | buildActionMask = 2147483647;
239 | files = (
240 | 9437E2CC1F23920800E294BE /* OnboardPage.swift in Sources */,
241 | 9437E2CB1F23920800E294BE /* OnboardPageViewController.swift in Sources */,
242 | 9437E2C91F23920800E294BE /* OnboardViewController.swift in Sources */,
243 | );
244 | runOnlyForDeploymentPostprocessing = 0;
245 | };
246 | 9437E2AA1F238E7E00E294BE /* Sources */ = {
247 | isa = PBXSourcesBuildPhase;
248 | buildActionMask = 2147483647;
249 | files = (
250 | 94FF39BE217B237C005AA773 /* AppearanceConfigurationTests.swift in Sources */,
251 | );
252 | runOnlyForDeploymentPostprocessing = 0;
253 | };
254 | /* End PBXSourcesBuildPhase section */
255 |
256 | /* Begin PBXTargetDependency section */
257 | 9437E2B11F238E7E00E294BE /* PBXTargetDependency */ = {
258 | isa = PBXTargetDependency;
259 | target = 9437E2A41F238E7E00E294BE /* OnboardKit */;
260 | targetProxy = 9437E2B01F238E7E00E294BE /* PBXContainerItemProxy */;
261 | };
262 | /* End PBXTargetDependency section */
263 |
264 | /* Begin XCBuildConfiguration section */
265 | 9437E2B71F238E7E00E294BE /* Debug */ = {
266 | isa = XCBuildConfiguration;
267 | buildSettings = {
268 | ALWAYS_SEARCH_USER_PATHS = NO;
269 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
270 | CLANG_ANALYZER_NONNULL = YES;
271 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
272 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
273 | CLANG_CXX_LIBRARY = "libc++";
274 | CLANG_ENABLE_MODULES = YES;
275 | CLANG_ENABLE_OBJC_ARC = YES;
276 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
277 | CLANG_WARN_BOOL_CONVERSION = YES;
278 | CLANG_WARN_COMMA = YES;
279 | CLANG_WARN_CONSTANT_CONVERSION = YES;
280 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
281 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
282 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
283 | CLANG_WARN_EMPTY_BODY = YES;
284 | CLANG_WARN_ENUM_CONVERSION = YES;
285 | CLANG_WARN_INFINITE_RECURSION = YES;
286 | CLANG_WARN_INT_CONVERSION = YES;
287 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
288 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
289 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
290 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
291 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
292 | CLANG_WARN_STRICT_PROTOTYPES = YES;
293 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
294 | CLANG_WARN_UNREACHABLE_CODE = YES;
295 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
296 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
297 | COPY_PHASE_STRIP = NO;
298 | CURRENT_PROJECT_VERSION = 1;
299 | DEBUG_INFORMATION_FORMAT = dwarf;
300 | ENABLE_STRICT_OBJC_MSGSEND = YES;
301 | ENABLE_TESTABILITY = YES;
302 | GCC_C_LANGUAGE_STANDARD = gnu99;
303 | GCC_DYNAMIC_NO_PIC = NO;
304 | GCC_NO_COMMON_BLOCKS = YES;
305 | GCC_OPTIMIZATION_LEVEL = 0;
306 | GCC_PREPROCESSOR_DEFINITIONS = (
307 | "DEBUG=1",
308 | "$(inherited)",
309 | );
310 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
311 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
312 | GCC_WARN_UNDECLARED_SELECTOR = YES;
313 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
314 | GCC_WARN_UNUSED_FUNCTION = YES;
315 | GCC_WARN_UNUSED_VARIABLE = YES;
316 | IPHONEOS_DEPLOYMENT_TARGET = 11.0;
317 | MTL_ENABLE_DEBUG_INFO = YES;
318 | ONLY_ACTIVE_ARCH = YES;
319 | SDKROOT = iphoneos;
320 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
321 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
322 | TARGETED_DEVICE_FAMILY = "1,2";
323 | VERSIONING_SYSTEM = "apple-generic";
324 | VERSION_INFO_PREFIX = "";
325 | };
326 | name = Debug;
327 | };
328 | 9437E2B81F238E7E00E294BE /* Release */ = {
329 | isa = XCBuildConfiguration;
330 | buildSettings = {
331 | ALWAYS_SEARCH_USER_PATHS = NO;
332 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
333 | CLANG_ANALYZER_NONNULL = YES;
334 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
335 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
336 | CLANG_CXX_LIBRARY = "libc++";
337 | CLANG_ENABLE_MODULES = YES;
338 | CLANG_ENABLE_OBJC_ARC = YES;
339 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
340 | CLANG_WARN_BOOL_CONVERSION = YES;
341 | CLANG_WARN_COMMA = YES;
342 | CLANG_WARN_CONSTANT_CONVERSION = YES;
343 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
344 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
345 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
346 | CLANG_WARN_EMPTY_BODY = YES;
347 | CLANG_WARN_ENUM_CONVERSION = YES;
348 | CLANG_WARN_INFINITE_RECURSION = YES;
349 | CLANG_WARN_INT_CONVERSION = YES;
350 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
351 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
352 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
353 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
354 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
355 | CLANG_WARN_STRICT_PROTOTYPES = YES;
356 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
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 = NO;
361 | CURRENT_PROJECT_VERSION = 1;
362 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
363 | ENABLE_NS_ASSERTIONS = NO;
364 | ENABLE_STRICT_OBJC_MSGSEND = YES;
365 | GCC_C_LANGUAGE_STANDARD = gnu99;
366 | GCC_NO_COMMON_BLOCKS = YES;
367 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
368 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
369 | GCC_WARN_UNDECLARED_SELECTOR = YES;
370 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
371 | GCC_WARN_UNUSED_FUNCTION = YES;
372 | GCC_WARN_UNUSED_VARIABLE = YES;
373 | IPHONEOS_DEPLOYMENT_TARGET = 11.0;
374 | MTL_ENABLE_DEBUG_INFO = NO;
375 | SDKROOT = iphoneos;
376 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
377 | TARGETED_DEVICE_FAMILY = "1,2";
378 | VALIDATE_PRODUCT = YES;
379 | VERSIONING_SYSTEM = "apple-generic";
380 | VERSION_INFO_PREFIX = "";
381 | };
382 | name = Release;
383 | };
384 | 9437E2BA1F238E7E00E294BE /* Debug */ = {
385 | isa = XCBuildConfiguration;
386 | buildSettings = {
387 | CLANG_ENABLE_MODULES = YES;
388 | CODE_SIGN_IDENTITY = "";
389 | CODE_SIGN_STYLE = Manual;
390 | DEFINES_MODULE = YES;
391 | DEVELOPMENT_TEAM = "";
392 | DYLIB_COMPATIBILITY_VERSION = 1;
393 | DYLIB_CURRENT_VERSION = 1;
394 | DYLIB_INSTALL_NAME_BASE = "@rpath";
395 | INFOPLIST_FILE = "$(SRCROOT)/Metadata/Info.plist";
396 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
397 | IPHONEOS_DEPLOYMENT_TARGET = 11.0;
398 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
399 | PRODUCT_BUNDLE_IDENTIFIER = com.nikolakirev.OnboardKit;
400 | PRODUCT_NAME = "$(TARGET_NAME)";
401 | PROVISIONING_PROFILE_SPECIFIER = "";
402 | SKIP_INSTALL = YES;
403 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
404 | SWIFT_VERSION = 5.0;
405 | };
406 | name = Debug;
407 | };
408 | 9437E2BB1F238E7E00E294BE /* Release */ = {
409 | isa = XCBuildConfiguration;
410 | buildSettings = {
411 | CLANG_ENABLE_MODULES = YES;
412 | CODE_SIGN_IDENTITY = "";
413 | CODE_SIGN_STYLE = Manual;
414 | DEFINES_MODULE = YES;
415 | DEVELOPMENT_TEAM = "";
416 | DYLIB_COMPATIBILITY_VERSION = 1;
417 | DYLIB_CURRENT_VERSION = 1;
418 | DYLIB_INSTALL_NAME_BASE = "@rpath";
419 | INFOPLIST_FILE = "$(SRCROOT)/Metadata/Info.plist";
420 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
421 | IPHONEOS_DEPLOYMENT_TARGET = 11.0;
422 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
423 | PRODUCT_BUNDLE_IDENTIFIER = com.nikolakirev.OnboardKit;
424 | PRODUCT_NAME = "$(TARGET_NAME)";
425 | PROVISIONING_PROFILE_SPECIFIER = "";
426 | SKIP_INSTALL = YES;
427 | SWIFT_VERSION = 5.0;
428 | };
429 | name = Release;
430 | };
431 | 9437E2BD1F238E7E00E294BE /* Debug */ = {
432 | isa = XCBuildConfiguration;
433 | buildSettings = {
434 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
435 | CODE_SIGN_STYLE = Manual;
436 | DEVELOPMENT_TEAM = 5Z8M29P3V9;
437 | INFOPLIST_FILE = OnboardKitTests/Info.plist;
438 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
439 | PRODUCT_BUNDLE_IDENTIFIER = com.nikolakirev.OnboardKitTests;
440 | PRODUCT_NAME = "$(TARGET_NAME)";
441 | PROVISIONING_PROFILE_SPECIFIER = "";
442 | SWIFT_VERSION = 5.0;
443 | };
444 | name = Debug;
445 | };
446 | 9437E2BE1F238E7E00E294BE /* Release */ = {
447 | isa = XCBuildConfiguration;
448 | buildSettings = {
449 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
450 | CODE_SIGN_STYLE = Manual;
451 | DEVELOPMENT_TEAM = 5Z8M29P3V9;
452 | INFOPLIST_FILE = OnboardKitTests/Info.plist;
453 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
454 | PRODUCT_BUNDLE_IDENTIFIER = com.nikolakirev.OnboardKitTests;
455 | PRODUCT_NAME = "$(TARGET_NAME)";
456 | PROVISIONING_PROFILE_SPECIFIER = "";
457 | SWIFT_VERSION = 5.0;
458 | };
459 | name = Release;
460 | };
461 | /* End XCBuildConfiguration section */
462 |
463 | /* Begin XCConfigurationList section */
464 | 9437E29F1F238E7E00E294BE /* Build configuration list for PBXProject "OnboardKit" */ = {
465 | isa = XCConfigurationList;
466 | buildConfigurations = (
467 | 9437E2B71F238E7E00E294BE /* Debug */,
468 | 9437E2B81F238E7E00E294BE /* Release */,
469 | );
470 | defaultConfigurationIsVisible = 0;
471 | defaultConfigurationName = Release;
472 | };
473 | 9437E2B91F238E7E00E294BE /* Build configuration list for PBXNativeTarget "OnboardKit" */ = {
474 | isa = XCConfigurationList;
475 | buildConfigurations = (
476 | 9437E2BA1F238E7E00E294BE /* Debug */,
477 | 9437E2BB1F238E7E00E294BE /* Release */,
478 | );
479 | defaultConfigurationIsVisible = 0;
480 | defaultConfigurationName = Release;
481 | };
482 | 9437E2BC1F238E7E00E294BE /* Build configuration list for PBXNativeTarget "OnboardKitTests" */ = {
483 | isa = XCConfigurationList;
484 | buildConfigurations = (
485 | 9437E2BD1F238E7E00E294BE /* Debug */,
486 | 9437E2BE1F238E7E00E294BE /* Release */,
487 | );
488 | defaultConfigurationIsVisible = 0;
489 | defaultConfigurationName = Release;
490 | };
491 | /* End XCConfigurationList section */
492 | };
493 | rootObject = 9437E29C1F238E7E00E294BE /* Project object */;
494 | }
495 |
--------------------------------------------------------------------------------