diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100755 index 0000000..cd18561 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,21 @@ +Copyright (c) 2014 Michael Amaral + +MIT LICENSE + +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: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +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 NONINFRINGEMENT. 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. diff --git a/Onboard.xcodeproj/project.pbxproj b/Onboard.xcodeproj/project.pbxproj new file mode 100644 index 0000000..7a89d8a --- /dev/null +++ b/Onboard.xcodeproj/project.pbxproj @@ -0,0 +1,488 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 273D50AF19A1A34F00E38DB2 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 273D50AE19A1A34F00E38DB2 /* Foundation.framework */; }; + 273D50B119A1A34F00E38DB2 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 273D50B019A1A34F00E38DB2 /* CoreGraphics.framework */; }; + 273D50B319A1A34F00E38DB2 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 273D50B219A1A34F00E38DB2 /* UIKit.framework */; }; + 273D50B919A1A34F00E38DB2 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 273D50B719A1A34F00E38DB2 /* InfoPlist.strings */; }; + 273D50BB19A1A34F00E38DB2 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 273D50BA19A1A34F00E38DB2 /* main.m */; }; + 273D50BF19A1A34F00E38DB2 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 273D50BE19A1A34F00E38DB2 /* AppDelegate.m */; }; + 273D50C119A1A34F00E38DB2 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 273D50C019A1A34F00E38DB2 /* Images.xcassets */; }; + 273D50C819A1A34F00E38DB2 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 273D50C719A1A34F00E38DB2 /* XCTest.framework */; }; + 273D50C919A1A34F00E38DB2 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 273D50AE19A1A34F00E38DB2 /* Foundation.framework */; }; + 273D50CA19A1A34F00E38DB2 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 273D50B219A1A34F00E38DB2 /* UIKit.framework */; }; + 273D50D219A1A34F00E38DB2 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 273D50D019A1A34F00E38DB2 /* InfoPlist.strings */; }; + 273D50D419A1A34F00E38DB2 /* OnboardTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 273D50D319A1A34F00E38DB2 /* OnboardTests.m */; }; + 273D50DF19A1A49C00E38DB2 /* OnboardingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 273D50DE19A1A49C00E38DB2 /* OnboardingViewController.m */; }; + 273D50E219A1A4BF00E38DB2 /* OnboardingContentViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 273D50E119A1A4BF00E38DB2 /* OnboardingContentViewController.m */; }; + 2789AD6219A2D95E002117FE /* street.png in Resources */ = {isa = PBXBuildFile; fileRef = 2789AD6119A2D95E002117FE /* street.png */; }; + 2789AD6E19A2DE53002117FE /* blue.png in Resources */ = {isa = PBXBuildFile; fileRef = 2789AD6B19A2DE53002117FE /* blue.png */; }; + 2789AD6F19A2DE53002117FE /* red.png in Resources */ = {isa = PBXBuildFile; fileRef = 2789AD6C19A2DE53002117FE /* red.png */; }; + 2789AD7019A2DE53002117FE /* yellow.png in Resources */ = {isa = PBXBuildFile; fileRef = 2789AD6D19A2DE53002117FE /* yellow.png */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 273D50CB19A1A34F00E38DB2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 273D50A319A1A34F00E38DB2 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 273D50AA19A1A34F00E38DB2; + remoteInfo = Onboard; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 273D50AB19A1A34F00E38DB2 /* Onboard.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Onboard.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 273D50AE19A1A34F00E38DB2 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 273D50B019A1A34F00E38DB2 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 273D50B219A1A34F00E38DB2 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 273D50B619A1A34F00E38DB2 /* Onboard-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Onboard-Info.plist"; sourceTree = ""; }; + 273D50B819A1A34F00E38DB2 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; + 273D50BA19A1A34F00E38DB2 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 273D50BC19A1A34F00E38DB2 /* Onboard-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Onboard-Prefix.pch"; sourceTree = ""; }; + 273D50BD19A1A34F00E38DB2 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 273D50BE19A1A34F00E38DB2 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 273D50C019A1A34F00E38DB2 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 273D50C619A1A34F00E38DB2 /* OnboardTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OnboardTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 273D50C719A1A34F00E38DB2 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; + 273D50CF19A1A34F00E38DB2 /* OnboardTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "OnboardTests-Info.plist"; sourceTree = ""; }; + 273D50D119A1A34F00E38DB2 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; + 273D50D319A1A34F00E38DB2 /* OnboardTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OnboardTests.m; sourceTree = ""; }; + 273D50DD19A1A49C00E38DB2 /* OnboardingViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OnboardingViewController.h; sourceTree = ""; }; + 273D50DE19A1A49C00E38DB2 /* OnboardingViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OnboardingViewController.m; sourceTree = ""; }; + 273D50E019A1A4BF00E38DB2 /* OnboardingContentViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OnboardingContentViewController.h; sourceTree = ""; }; + 273D50E119A1A4BF00E38DB2 /* OnboardingContentViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OnboardingContentViewController.m; sourceTree = ""; }; + 2789AD6119A2D95E002117FE /* street.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = street.png; sourceTree = ""; }; + 2789AD6B19A2DE53002117FE /* blue.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = blue.png; sourceTree = ""; }; + 2789AD6C19A2DE53002117FE /* red.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = red.png; sourceTree = ""; }; + 2789AD6D19A2DE53002117FE /* yellow.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = yellow.png; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 273D50A819A1A34F00E38DB2 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 273D50B119A1A34F00E38DB2 /* CoreGraphics.framework in Frameworks */, + 273D50B319A1A34F00E38DB2 /* UIKit.framework in Frameworks */, + 273D50AF19A1A34F00E38DB2 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 273D50C319A1A34F00E38DB2 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 273D50C819A1A34F00E38DB2 /* XCTest.framework in Frameworks */, + 273D50CA19A1A34F00E38DB2 /* UIKit.framework in Frameworks */, + 273D50C919A1A34F00E38DB2 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 273D50A219A1A34F00E38DB2 = { + isa = PBXGroup; + children = ( + 273D50B419A1A34F00E38DB2 /* Onboard */, + 273D50CD19A1A34F00E38DB2 /* OnboardTests */, + 273D50AD19A1A34F00E38DB2 /* Frameworks */, + 273D50AC19A1A34F00E38DB2 /* Products */, + ); + sourceTree = ""; + }; + 273D50AC19A1A34F00E38DB2 /* Products */ = { + isa = PBXGroup; + children = ( + 273D50AB19A1A34F00E38DB2 /* Onboard.app */, + 273D50C619A1A34F00E38DB2 /* OnboardTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 273D50AD19A1A34F00E38DB2 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 273D50AE19A1A34F00E38DB2 /* Foundation.framework */, + 273D50B019A1A34F00E38DB2 /* CoreGraphics.framework */, + 273D50B219A1A34F00E38DB2 /* UIKit.framework */, + 273D50C719A1A34F00E38DB2 /* XCTest.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 273D50B419A1A34F00E38DB2 /* Onboard */ = { + isa = PBXGroup; + children = ( + 273D50BD19A1A34F00E38DB2 /* AppDelegate.h */, + 273D50BE19A1A34F00E38DB2 /* AppDelegate.m */, + 273D50DD19A1A49C00E38DB2 /* OnboardingViewController.h */, + 273D50DE19A1A49C00E38DB2 /* OnboardingViewController.m */, + 273D50E019A1A4BF00E38DB2 /* OnboardingContentViewController.h */, + 273D50E119A1A4BF00E38DB2 /* OnboardingContentViewController.m */, + 2789AD6B19A2DE53002117FE /* blue.png */, + 2789AD6C19A2DE53002117FE /* red.png */, + 2789AD6D19A2DE53002117FE /* yellow.png */, + 2789AD6119A2D95E002117FE /* street.png */, + 273D50C019A1A34F00E38DB2 /* Images.xcassets */, + 273D50B519A1A34F00E38DB2 /* Supporting Files */, + ); + path = Onboard; + sourceTree = ""; + }; + 273D50B519A1A34F00E38DB2 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 273D50B619A1A34F00E38DB2 /* Onboard-Info.plist */, + 273D50B719A1A34F00E38DB2 /* InfoPlist.strings */, + 273D50BA19A1A34F00E38DB2 /* main.m */, + 273D50BC19A1A34F00E38DB2 /* Onboard-Prefix.pch */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 273D50CD19A1A34F00E38DB2 /* OnboardTests */ = { + isa = PBXGroup; + children = ( + 273D50D319A1A34F00E38DB2 /* OnboardTests.m */, + 273D50CE19A1A34F00E38DB2 /* Supporting Files */, + ); + path = OnboardTests; + sourceTree = ""; + }; + 273D50CE19A1A34F00E38DB2 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 273D50CF19A1A34F00E38DB2 /* OnboardTests-Info.plist */, + 273D50D019A1A34F00E38DB2 /* InfoPlist.strings */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 273D50AA19A1A34F00E38DB2 /* Onboard */ = { + isa = PBXNativeTarget; + buildConfigurationList = 273D50D719A1A34F00E38DB2 /* Build configuration list for PBXNativeTarget "Onboard" */; + buildPhases = ( + 273D50A719A1A34F00E38DB2 /* Sources */, + 273D50A819A1A34F00E38DB2 /* Frameworks */, + 273D50A919A1A34F00E38DB2 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Onboard; + productName = Onboard; + productReference = 273D50AB19A1A34F00E38DB2 /* Onboard.app */; + productType = "com.apple.product-type.application"; + }; + 273D50C519A1A34F00E38DB2 /* OnboardTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 273D50DA19A1A34F00E38DB2 /* Build configuration list for PBXNativeTarget "OnboardTests" */; + buildPhases = ( + 273D50C219A1A34F00E38DB2 /* Sources */, + 273D50C319A1A34F00E38DB2 /* Frameworks */, + 273D50C419A1A34F00E38DB2 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 273D50CC19A1A34F00E38DB2 /* PBXTargetDependency */, + ); + name = OnboardTests; + productName = OnboardTests; + productReference = 273D50C619A1A34F00E38DB2 /* OnboardTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 273D50A319A1A34F00E38DB2 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0500; + ORGANIZATIONNAME = "Mike Amaral"; + TargetAttributes = { + 273D50C519A1A34F00E38DB2 = { + TestTargetID = 273D50AA19A1A34F00E38DB2; + }; + }; + }; + buildConfigurationList = 273D50A619A1A34F00E38DB2 /* Build configuration list for PBXProject "Onboard" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 273D50A219A1A34F00E38DB2; + productRefGroup = 273D50AC19A1A34F00E38DB2 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 273D50AA19A1A34F00E38DB2 /* Onboard */, + 273D50C519A1A34F00E38DB2 /* OnboardTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 273D50A919A1A34F00E38DB2 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 273D50B919A1A34F00E38DB2 /* InfoPlist.strings in Resources */, + 2789AD7019A2DE53002117FE /* yellow.png in Resources */, + 273D50C119A1A34F00E38DB2 /* Images.xcassets in Resources */, + 2789AD6219A2D95E002117FE /* street.png in Resources */, + 2789AD6F19A2DE53002117FE /* red.png in Resources */, + 2789AD6E19A2DE53002117FE /* blue.png in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 273D50C419A1A34F00E38DB2 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 273D50D219A1A34F00E38DB2 /* InfoPlist.strings in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 273D50A719A1A34F00E38DB2 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 273D50DF19A1A49C00E38DB2 /* OnboardingViewController.m in Sources */, + 273D50BF19A1A34F00E38DB2 /* AppDelegate.m in Sources */, + 273D50BB19A1A34F00E38DB2 /* main.m in Sources */, + 273D50E219A1A4BF00E38DB2 /* OnboardingContentViewController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 273D50C219A1A34F00E38DB2 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 273D50D419A1A34F00E38DB2 /* OnboardTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 273D50CC19A1A34F00E38DB2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 273D50AA19A1A34F00E38DB2 /* Onboard */; + targetProxy = 273D50CB19A1A34F00E38DB2 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 273D50B719A1A34F00E38DB2 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 273D50B819A1A34F00E38DB2 /* en */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; + 273D50D019A1A34F00E38DB2 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 273D50D119A1A34F00E38DB2 /* en */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 273D50D519A1A34F00E38DB2 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 273D50D619A1A34F00E38DB2 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = YES; + ENABLE_NS_ASSERTIONS = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 273D50D819A1A34F00E38DB2 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "Onboard/Onboard-Prefix.pch"; + INFOPLIST_FILE = "Onboard/Onboard-Info.plist"; + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = app; + }; + name = Debug; + }; + 273D50D919A1A34F00E38DB2 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "Onboard/Onboard-Prefix.pch"; + INFOPLIST_FILE = "Onboard/Onboard-Info.plist"; + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = app; + }; + name = Release; + }; + 273D50DB19A1A34F00E38DB2 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; + BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/Onboard.app/Onboard"; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + "$(DEVELOPER_FRAMEWORKS_DIR)", + ); + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "Onboard/Onboard-Prefix.pch"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = "OnboardTests/OnboardTests-Info.plist"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUNDLE_LOADER)"; + WRAPPER_EXTENSION = xctest; + }; + name = Debug; + }; + 273D50DC19A1A34F00E38DB2 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; + BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/Onboard.app/Onboard"; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + "$(DEVELOPER_FRAMEWORKS_DIR)", + ); + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "Onboard/Onboard-Prefix.pch"; + INFOPLIST_FILE = "OnboardTests/OnboardTests-Info.plist"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUNDLE_LOADER)"; + WRAPPER_EXTENSION = xctest; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 273D50A619A1A34F00E38DB2 /* Build configuration list for PBXProject "Onboard" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 273D50D519A1A34F00E38DB2 /* Debug */, + 273D50D619A1A34F00E38DB2 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 273D50D719A1A34F00E38DB2 /* Build configuration list for PBXNativeTarget "Onboard" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 273D50D819A1A34F00E38DB2 /* Debug */, + 273D50D919A1A34F00E38DB2 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 273D50DA19A1A34F00E38DB2 /* Build configuration list for PBXNativeTarget "OnboardTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 273D50DB19A1A34F00E38DB2 /* Debug */, + 273D50DC19A1A34F00E38DB2 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 273D50A319A1A34F00E38DB2 /* Project object */; +} diff --git a/Onboard.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Onboard.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..f5f98bb --- /dev/null +++ b/Onboard.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Onboard.xcodeproj/project.xcworkspace/xcuserdata/mike.xcuserdatad/UserInterfaceState.xcuserstate b/Onboard.xcodeproj/project.xcworkspace/xcuserdata/mike.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..1916ecb Binary files /dev/null and b/Onboard.xcodeproj/project.xcworkspace/xcuserdata/mike.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/Onboard.xcodeproj/xcuserdata/mike.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/Onboard.xcodeproj/xcuserdata/mike.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 0000000..ceae9ec --- /dev/null +++ b/Onboard.xcodeproj/xcuserdata/mike.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,23 @@ + + + + + + + + + diff --git a/Onboard.xcodeproj/xcuserdata/mike.xcuserdatad/xcschemes/Onboard.xcscheme b/Onboard.xcodeproj/xcuserdata/mike.xcuserdatad/xcschemes/Onboard.xcscheme new file mode 100644 index 0000000..16de34a --- /dev/null +++ b/Onboard.xcodeproj/xcuserdata/mike.xcuserdatad/xcschemes/Onboard.xcscheme @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Onboard.xcodeproj/xcuserdata/mike.xcuserdatad/xcschemes/xcschememanagement.plist b/Onboard.xcodeproj/xcuserdata/mike.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..d03a6b2 --- /dev/null +++ b/Onboard.xcodeproj/xcuserdata/mike.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,27 @@ + + + + + SchemeUserState + + Onboard.xcscheme + + orderHint + 0 + + + SuppressBuildableAutocreation + + 273D50AA19A1A34F00E38DB2 + + primary + + + 273D50C519A1A34F00E38DB2 + + primary + + + + + diff --git a/Onboard/AppDelegate.h b/Onboard/AppDelegate.h new file mode 100644 index 0000000..1621d02 --- /dev/null +++ b/Onboard/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// Onboard +// +// Created by Mike on 8/17/14. +// Copyright (c) 2014 Mike Amaral. All rights reserved. +// + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + +@end diff --git a/Onboard/AppDelegate.m b/Onboard/AppDelegate.m new file mode 100644 index 0000000..be4d8b5 --- /dev/null +++ b/Onboard/AppDelegate.m @@ -0,0 +1,44 @@ +// +// AppDelegate.m +// Onboard +// +// Created by Mike on 8/17/14. +// Copyright (c) 2014 Mike Amaral. All rights reserved. +// + +#import "AppDelegate.h" +#import "OnboardingViewController.h" +#import "OnboardingContentViewController.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + self.window.backgroundColor = [UIColor whiteColor]; + [self.window makeKeyAndVisible]; + + UIViewController *mainVC = [UIViewController new]; + mainVC.title = @"Main Application"; + UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:mainVC]; + self.window.rootViewController = nc; + + OnboardingContentViewController *firstPage = [[OnboardingContentViewController alloc] initWithTitle:@"What A Beautiful Photo" body:@"This city background image is so beautiful." image:[UIImage imageNamed:@"blue"] buttonText:@"Enable Location Services" action:^{ + [[[UIAlertView alloc] initWithTitle:nil message:@"Here you can prompt users for various application permissions." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show]; + }]; + + OnboardingContentViewController *secondPage = [[OnboardingContentViewController alloc] initWithTitle:@"I'm so sorry" body:@"I can't get over the nice blurry background photo." image:[UIImage imageNamed:@"red"] buttonText:@"Connect With Facebook" action:^{ + [[[UIAlertView alloc] initWithTitle:nil message:@"Prompt users to do other cool things on startup." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show]; + }]; + + OnboardingContentViewController *thirdPage = [[OnboardingContentViewController alloc] initWithTitle:@"Seriously Though" body:@"Kudos to the photographer." image:[UIImage imageNamed:@"yellow"] buttonText:@"Get Started" action:^{ + [nc dismissViewControllerAnimated:YES completion:nil]; + }]; + + OnboardingViewController *onboardingVC = [[OnboardingViewController alloc] initWithBackgroundImage:[UIImage imageNamed:@"street"] contents:@[firstPage, secondPage, thirdPage]]; + + [nc presentViewController:onboardingVC animated:YES completion:nil]; + + return YES; +} + +@end \ No newline at end of file diff --git a/Onboard/Images.xcassets/AppIcon.appiconset/Contents.json b/Onboard/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..91bf9c1 --- /dev/null +++ b/Onboard/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,53 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Onboard/Images.xcassets/LaunchImage.launchimage/Contents.json b/Onboard/Images.xcassets/LaunchImage.launchimage/Contents.json new file mode 100644 index 0000000..6f870a4 --- /dev/null +++ b/Onboard/Images.xcassets/LaunchImage.launchimage/Contents.json @@ -0,0 +1,51 @@ +{ + "images" : [ + { + "orientation" : "portrait", + "idiom" : "iphone", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "scale" : "2x" + }, + { + "orientation" : "portrait", + "idiom" : "iphone", + "subtype" : "retina4", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "scale" : "2x" + }, + { + "orientation" : "portrait", + "idiom" : "ipad", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "scale" : "1x" + }, + { + "orientation" : "landscape", + "idiom" : "ipad", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "scale" : "1x" + }, + { + "orientation" : "portrait", + "idiom" : "ipad", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "scale" : "2x" + }, + { + "orientation" : "landscape", + "idiom" : "ipad", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Onboard/Onboard-Info.plist b/Onboard/Onboard-Info.plist new file mode 100644 index 0000000..bf44ae7 --- /dev/null +++ b/Onboard/Onboard-Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + com.MikeAmaral.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Onboard/Onboard-Prefix.pch b/Onboard/Onboard-Prefix.pch new file mode 100644 index 0000000..743435c --- /dev/null +++ b/Onboard/Onboard-Prefix.pch @@ -0,0 +1,16 @@ +// +// Prefix header +// +// The contents of this file are implicitly included at the beginning of every source file. +// + +#import + +#ifndef __IPHONE_3_0 +#warning "This project uses features only available in iOS SDK 3.0 and later." +#endif + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/Onboard/OnboardingContentViewController.h b/Onboard/OnboardingContentViewController.h new file mode 100644 index 0000000..6f3e445 --- /dev/null +++ b/Onboard/OnboardingContentViewController.h @@ -0,0 +1,21 @@ +// +// OnboardingContentViewController.h +// Onboard +// +// Created by Mike on 8/17/14. +// Copyright (c) 2014 Mike Amaral. All rights reserved. +// + +#import + +@interface OnboardingContentViewController : UIViewController { + NSString *_titleText; + NSString *_body; + UIImage *_image; + NSString *_buttonText; + dispatch_block_t _actionHandler; +} + +- (id)initWithTitle:(NSString *)title body:(NSString *)body image:(UIImage *)image buttonText:(NSString *)buttonText action:(dispatch_block_t)action; + +@end diff --git a/Onboard/OnboardingContentViewController.m b/Onboard/OnboardingContentViewController.m new file mode 100644 index 0000000..7e3c980 --- /dev/null +++ b/Onboard/OnboardingContentViewController.m @@ -0,0 +1,84 @@ +// +// OnboardingContentViewController.m +// Onboard +// +// Created by Mike on 8/17/14. +// Copyright (c) 2014 Mike Amaral. All rights reserved. +// + +#import "OnboardingContentViewController.h" + +@interface OnboardingContentViewController () + +@end + +@implementation OnboardingContentViewController + +- (id)initWithTitle:(NSString *)title body:(NSString *)body image:(UIImage *)image buttonText:(NSString *)buttonText action:(dispatch_block_t)action { + self = [super init]; + + _titleText = title; + _body = body; + _image = image; + _buttonText = buttonText; + _actionHandler = action ?: ^{}; + + return self; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + + [self generateView]; +} + +- (void)generateView { + self.view.backgroundColor = [UIColor clearColor]; + + CGFloat viewWidth = CGRectGetWidth(self.view.frame); + CGFloat horizontalCenter = viewWidth / 2; + CGFloat labelWidth = viewWidth * 0.9; + CGFloat padding = 20; + + UIImageView *imageView = [[UIImageView alloc] initWithImage:_image]; + [imageView setFrame:CGRectMake((viewWidth / 2) - (100 / 2), 4 * padding , 100, 100)]; + [self.view addSubview:imageView]; + + UILabel *mainTextLabel = [[UILabel alloc] initWithFrame:CGRectMake(padding, CGRectGetMaxY(imageView.frame) + padding, labelWidth, 0)]; + mainTextLabel.text = _titleText; + mainTextLabel.textColor = [UIColor whiteColor]; + mainTextLabel.font = [UIFont fontWithName:@"Helvetica-Light" size:38]; + mainTextLabel.numberOfLines = 0; + mainTextLabel.textAlignment = NSTextAlignmentCenter; + [mainTextLabel sizeToFit]; + mainTextLabel.center = CGPointMake(horizontalCenter, mainTextLabel.center.y); + [self.view addSubview:mainTextLabel]; + + UILabel *subTextLabel = [[UILabel alloc] initWithFrame:CGRectMake(padding, CGRectGetMaxY(mainTextLabel.frame) + padding, labelWidth, 0)]; + subTextLabel.text = _body; + subTextLabel.textColor = [UIColor whiteColor]; + subTextLabel.font = [UIFont fontWithName:@"Helvetica-Light" size:28]; + subTextLabel.numberOfLines = 0; + subTextLabel.textAlignment = NSTextAlignmentCenter; + [subTextLabel sizeToFit]; + subTextLabel.center = CGPointMake(horizontalCenter, subTextLabel.center.y); + [self.view addSubview:subTextLabel]; + + // create the action button + if (_buttonText) { + UIButton *actionButton = [[UIButton alloc] initWithFrame:CGRectMake((CGRectGetMaxX(self.view.frame) / 2) - (labelWidth / 2), CGRectGetMaxY(self.view.frame) - 100 - padding, labelWidth, 50)]; + actionButton.titleLabel.font = [UIFont systemFontOfSize:24]; + [actionButton setTitle:_buttonText forState:UIControlStateNormal]; + [actionButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + [actionButton addTarget:self action:@selector(handleButtonPressed) forControlEvents:UIControlEventTouchUpInside]; + [self.view addSubview:actionButton]; + } +} + +#pragma mark - action button callback + +- (void)handleButtonPressed { + _actionHandler(); +} + +@end diff --git a/Onboard/OnboardingViewController.h b/Onboard/OnboardingViewController.h new file mode 100644 index 0000000..8eb2ac8 --- /dev/null +++ b/Onboard/OnboardingViewController.h @@ -0,0 +1,20 @@ +// +// OnboardingViewController.h +// Onboard +// +// Created by Mike on 8/17/14. +// Copyright (c) 2014 Mike Amaral. All rights reserved. +// + +#import + +@interface OnboardingViewController : UIViewController { + UIImage *_backgroundImage; + UIPageViewController *_pageVC; + UIPageControl *_pageControl; + NSArray *_viewControllers; +} + +- (id)initWithBackgroundImage:(UIImage *)backgroundImage contents:(NSArray *)contents; + +@end diff --git a/Onboard/OnboardingViewController.m b/Onboard/OnboardingViewController.m new file mode 100644 index 0000000..83ce533 --- /dev/null +++ b/Onboard/OnboardingViewController.m @@ -0,0 +1,106 @@ +// +// OnboardingViewController.m +// Onboard +// +// Created by Mike on 8/17/14. +// Copyright (c) 2014 Mike Amaral. All rights reserved. +// + +#import "OnboardingViewController.h" +#import "OnboardingContentViewController.h" + +static CGFloat const kPageControlHeight = 35; + +@implementation OnboardingViewController + +- (id)initWithBackgroundImage:(UIImage *)backgroundImage contents:(NSArray *)contents { + self = [super init]; + + _backgroundImage = backgroundImage; + _viewControllers = contents; + + return self; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + + [self generateView]; +} + +- (void)generateView { + _pageVC = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil]; + _pageVC.view.frame = self.view.frame; + _pageVC.view.backgroundColor = [UIColor whiteColor]; + _pageVC.delegate = self; + _pageVC.dataSource = self; + + UIImageView *backgroundImageView = [[UIImageView alloc] initWithFrame:self.view.bounds]; + backgroundImageView.contentMode = UIViewContentModeScaleAspectFill; + [backgroundImageView setImage:_backgroundImage]; + [self.view addSubview:backgroundImageView]; + + // this view will sit between the image and the buttons that sit on top to darken it a bit + UIView *backgroundMaskView = [[UIView alloc] initWithFrame:_pageVC.view.frame]; + backgroundMaskView.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.6]; + [_pageVC.view addSubview:backgroundMaskView]; + + [_pageVC setViewControllers:@[[_viewControllers firstObject]] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil]; + _pageVC.view.backgroundColor = [UIColor clearColor]; + [self addChildViewController:_pageVC]; + [self.view addSubview:_pageVC.view]; + [_pageVC didMoveToParentViewController:self]; + [_pageVC.view sendSubviewToBack:backgroundMaskView]; + [_pageVC.view sendSubviewToBack:backgroundImageView]; + + _pageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(self.view.frame) - kPageControlHeight, self.view.frame.size.width, kPageControlHeight)]; + _pageControl.numberOfPages = _viewControllers.count; + [self.view addSubview:_pageControl]; +} + + +#pragma mark - Page view controller data source + +- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController { + if (viewController == [_viewControllers lastObject]) { + return nil; + } + else { + NSInteger nextPageIndex = [_viewControllers indexOfObject:viewController] + 1; + return _viewControllers[nextPageIndex]; + } +} + +- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController { + if (viewController == [_viewControllers firstObject]) { + return nil; + } + else { + NSInteger priorPageIndex = [_viewControllers indexOfObject:viewController] - 1; + return _viewControllers[priorPageIndex]; + } +} + + +#pragma mark - Page view controller delegate + +- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed { + // if we haven't completed animating yet, we don't want to do anything because it could be cancelled + if (!completed) { + return; + } + + // get the view controller we are moving towards, then get the index, then set it as the current page + // for the page control dots + UIViewController *viewController = [pageViewController.viewControllers lastObject]; + NSInteger newIndex = [_viewControllers indexOfObject:viewController]; + [_pageControl setCurrentPage:newIndex]; +} + +- (void)moveToPageForViewController:(UIViewController *)viewController { + [_pageVC setViewControllers:@[viewController] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil]; + [_pageControl setCurrentPage:[_viewControllers indexOfObject:viewController]]; +} + + +@end diff --git a/Onboard/blue.png b/Onboard/blue.png new file mode 100644 index 0000000..0acbf14 Binary files /dev/null and b/Onboard/blue.png differ diff --git a/Onboard/en.lproj/InfoPlist.strings b/Onboard/en.lproj/InfoPlist.strings new file mode 100644 index 0000000..477b28f --- /dev/null +++ b/Onboard/en.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/Onboard/main.m b/Onboard/main.m new file mode 100644 index 0000000..9be3bc5 --- /dev/null +++ b/Onboard/main.m @@ -0,0 +1,18 @@ +// +// main.m +// Onboard +// +// Created by Mike on 8/17/14. +// Copyright (c) 2014 Mike Amaral. All rights reserved. +// + +#import + +#import "AppDelegate.h" + +int main(int argc, char * argv[]) +{ + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/Onboard/red.png b/Onboard/red.png new file mode 100644 index 0000000..7c51d58 Binary files /dev/null and b/Onboard/red.png differ diff --git a/Onboard/street.png b/Onboard/street.png new file mode 100644 index 0000000..1773dc5 Binary files /dev/null and b/Onboard/street.png differ diff --git a/Onboard/yellow.png b/Onboard/yellow.png new file mode 100644 index 0000000..4e27f06 Binary files /dev/null and b/Onboard/yellow.png differ diff --git a/OnboardTests/OnboardTests-Info.plist b/OnboardTests/OnboardTests-Info.plist new file mode 100644 index 0000000..1668f5f --- /dev/null +++ b/OnboardTests/OnboardTests-Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + com.MikeAmaral.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/OnboardTests/OnboardTests.m b/OnboardTests/OnboardTests.m new file mode 100644 index 0000000..566e563 --- /dev/null +++ b/OnboardTests/OnboardTests.m @@ -0,0 +1,34 @@ +// +// OnboardTests.m +// OnboardTests +// +// Created by Mike on 8/17/14. +// Copyright (c) 2014 Mike Amaral. All rights reserved. +// + +#import + +@interface OnboardTests : XCTestCase + +@end + +@implementation OnboardTests + +- (void)setUp +{ + [super setUp]; + // Put setup code here. This method is called before the invocation of each test method in the class. +} + +- (void)tearDown +{ + // Put teardown code here. This method is called after the invocation of each test method in the class. + [super tearDown]; +} + +- (void)testExample +{ + XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); +} + +@end diff --git a/OnboardTests/en.lproj/InfoPlist.strings b/OnboardTests/en.lproj/InfoPlist.strings new file mode 100644 index 0000000..477b28f --- /dev/null +++ b/OnboardTests/en.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/README.md b/README.md new file mode 100644 index 0000000..4ed98f2 --- /dev/null +++ b/README.md @@ -0,0 +1,43 @@ +Onboard +================== + +Onboard provides developers with a quick and easy means to create a beautiful, engaging, and useful onboarding experience. + + +Usage +===== + +Drop the OnboardingViewController and OnboardingContentViewController header and implementation files into your project, import them into your AppDelegate, and you're ready to create an awesome onboarding experience for your users! + +Create individual pages by creating an OnboardingContentViewController, providing it a title, body, image, text for an action button, and within the action block + +```js +OnboardingContentViewController *firstPage = [[OnboardingContentViewController alloc] initWithTitle:@"Page Title" body:@"Page body goes here." image:[UIImage imageNamed:@"icon"] buttonText:@"Text For Button" action:^{ + // do something here when users press the button, like ask for location services permissions, register for push notifications, connect to social media, or finish the onboarding process +}]; + +``` + +Then create the OnboardingViewController by providing a background image and an array of OnboardingContentViewControllers you just created. You can then present the view modally and get the onboarding process started! + +```js +OnboardingViewController *onboardingVC = [[OnboardingViewController alloc] initWithBackgroundImage:[UIImage imageNamed:@"background"] contents:@[firstPage, secondPage, thirdPage]]; + +``` + +With only a few lines of code you have an beautiful, end-to-end onboarding process that will get your users excited to user your awesome applications. + + +![demo](onboard_demo.gif) + + +Community +===== + +Questions, comments, issues, and pull requests welcomed!! + + +License +===== + +This project is made available under the MIT license. See LICENSE.txt for details. diff --git a/gitignore.txt b/gitignore.txt new file mode 100644 index 0000000..443a64b --- /dev/null +++ b/gitignore.txt @@ -0,0 +1,8 @@ +#Xcode +*.pbuser +*.mode1v3 +*.mode2v3 +*.perspectivev3 +*.xcuserstate +project.xcworkspace/ +xcuserdata/ \ No newline at end of file diff --git a/onboard_demo.gif b/onboard_demo.gif new file mode 100644 index 0000000..f3597ae Binary files /dev/null and b/onboard_demo.gif differ