├── .gitignore ├── Demo ├── Objective-C │ ├── IntroductionView.xcodeproj │ │ └── project.pbxproj │ ├── IntroductionView │ │ ├── AppDelegate.h │ │ ├── AppDelegate.m │ │ ├── Base.lproj │ │ │ └── LaunchScreen.xib │ │ ├── Images.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ ├── bg_bar.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── bg_mycenter_topbar@2x.png │ │ │ ├── img_index_01bg.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── img_index_01bg@2x.png │ │ │ ├── img_index_01txt.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── img_index_01txt@2x.png │ │ │ ├── img_index_02bg.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── img_index_02bg@2x.png │ │ │ ├── img_index_02txt.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── img_index_02txt@2x.png │ │ │ ├── img_index_03bg.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── img_index_03bg@2x.png │ │ │ └── img_index_03txt.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── img_index_03txt@2x.png │ │ ├── Info.plist │ │ ├── ViewController.h │ │ ├── ViewController.m │ │ ├── intro_video.mp4 │ │ └── main.m │ └── IntroductionViewTests │ │ ├── Info.plist │ │ └── IntroductionViewTests.m └── Swift │ ├── IntroductionView.xcodeproj │ └── project.pbxproj │ ├── IntroductionView │ ├── AppDelegate.swift │ ├── Base.lproj │ │ └── LaunchScreen.xib │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ ├── bg_bar.imageset │ │ │ ├── Contents.json │ │ │ └── bg_mycenter_topbar@2x.png │ │ ├── img_index_01bg.imageset │ │ │ ├── Contents.json │ │ │ └── img_index_01bg@2x.png │ │ ├── img_index_01txt.imageset │ │ │ ├── Contents.json │ │ │ └── img_index_01txt@2x.png │ │ ├── img_index_02bg.imageset │ │ │ ├── Contents.json │ │ │ └── img_index_02bg@2x.png │ │ ├── img_index_02txt.imageset │ │ │ ├── Contents.json │ │ │ └── img_index_02txt@2x.png │ │ ├── img_index_03bg.imageset │ │ │ ├── Contents.json │ │ │ └── img_index_03bg@2x.png │ │ └── img_index_03txt.imageset │ │ │ ├── Contents.json │ │ │ └── img_index_03txt@2x.png │ ├── Info.plist │ ├── IntroductionView-Bridging-Header.h │ └── intro_video.mp4 │ └── IntroductionViewTests │ ├── Info.plist │ └── IntroductionViewTests.swift ├── LICENSE.txt ├── Library ├── ZWIntroductionView.h ├── ZWIntroductionView.m ├── ZWIntroductionViewController.h └── ZWIntroductionViewController.m ├── README.markdown ├── ZWIntroductionViewController.podspec.json ├── demo.png ├── screenshot.gif ├── simple.gif └── video.gif /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | .DS_Store 3 | Build/ 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | *.xcworkspace 13 | !default.xcworkspace 14 | xcuserdata 15 | profile 16 | *.moved-aside 17 | DerivedData 18 | # Pods 19 | Pods/ 20 | # Others 21 | Rollout-ios-SDK/ 22 | -------------------------------------------------------------------------------- /Demo/Objective-C/IntroductionView.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 59D336DF1A91D23B0089837F /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 59D336DE1A91D23B0089837F /* main.m */; }; 11 | 59D336E21A91D23B0089837F /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 59D336E11A91D23B0089837F /* AppDelegate.m */; }; 12 | 59D336E51A91D23B0089837F /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 59D336E41A91D23B0089837F /* ViewController.m */; }; 13 | 59D336EA1A91D23B0089837F /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 59D336E91A91D23B0089837F /* Images.xcassets */; }; 14 | 59D336ED1A91D23B0089837F /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 59D336EB1A91D23B0089837F /* LaunchScreen.xib */; }; 15 | 59D336F91A91D23B0089837F /* IntroductionViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 59D336F81A91D23B0089837F /* IntroductionViewTests.m */; }; 16 | 59D337051A91D2DC0089837F /* ZWIntroductionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 59D337041A91D2DC0089837F /* ZWIntroductionViewController.m */; }; 17 | 9516056D1D7D39AE007016EB /* intro_video.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = 9516056C1D7D39AE007016EB /* intro_video.mp4 */; }; 18 | 952658651E4D8AAB00726779 /* ZWIntroductionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 952658641E4D8AAB00726779 /* ZWIntroductionView.m */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXContainerItemProxy section */ 22 | 59D336F31A91D23B0089837F /* PBXContainerItemProxy */ = { 23 | isa = PBXContainerItemProxy; 24 | containerPortal = 59D336D11A91D23B0089837F /* Project object */; 25 | proxyType = 1; 26 | remoteGlobalIDString = 59D336D81A91D23B0089837F; 27 | remoteInfo = IntroductionView; 28 | }; 29 | /* End PBXContainerItemProxy section */ 30 | 31 | /* Begin PBXFileReference section */ 32 | 59D336D91A91D23B0089837F /* IntroductionView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = IntroductionView.app; sourceTree = BUILT_PRODUCTS_DIR; }; 33 | 59D336DD1A91D23B0089837F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 34 | 59D336DE1A91D23B0089837F /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 35 | 59D336E01A91D23B0089837F /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 36 | 59D336E11A91D23B0089837F /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 37 | 59D336E31A91D23B0089837F /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 38 | 59D336E41A91D23B0089837F /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 39 | 59D336E91A91D23B0089837F /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 40 | 59D336EC1A91D23B0089837F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 41 | 59D336F21A91D23B0089837F /* IntroductionViewTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = IntroductionViewTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 42 | 59D336F71A91D23B0089837F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 43 | 59D336F81A91D23B0089837F /* IntroductionViewTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IntroductionViewTests.m; sourceTree = ""; }; 44 | 59D337031A91D2DC0089837F /* ZWIntroductionViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZWIntroductionViewController.h; sourceTree = ""; }; 45 | 59D337041A91D2DC0089837F /* ZWIntroductionViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZWIntroductionViewController.m; sourceTree = ""; }; 46 | 9516056C1D7D39AE007016EB /* intro_video.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = intro_video.mp4; sourceTree = ""; }; 47 | 952658631E4D8AAB00726779 /* ZWIntroductionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZWIntroductionView.h; sourceTree = ""; }; 48 | 952658641E4D8AAB00726779 /* ZWIntroductionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZWIntroductionView.m; sourceTree = ""; }; 49 | /* End PBXFileReference section */ 50 | 51 | /* Begin PBXFrameworksBuildPhase section */ 52 | 59D336D61A91D23B0089837F /* Frameworks */ = { 53 | isa = PBXFrameworksBuildPhase; 54 | buildActionMask = 2147483647; 55 | files = ( 56 | ); 57 | runOnlyForDeploymentPostprocessing = 0; 58 | }; 59 | 59D336EF1A91D23B0089837F /* Frameworks */ = { 60 | isa = PBXFrameworksBuildPhase; 61 | buildActionMask = 2147483647; 62 | files = ( 63 | ); 64 | runOnlyForDeploymentPostprocessing = 0; 65 | }; 66 | /* End PBXFrameworksBuildPhase section */ 67 | 68 | /* Begin PBXGroup section */ 69 | 59D336D01A91D23B0089837F = { 70 | isa = PBXGroup; 71 | children = ( 72 | 59D337021A91D2DC0089837F /* Library */, 73 | 59D336DB1A91D23B0089837F /* IntroductionView */, 74 | 59D336F51A91D23B0089837F /* IntroductionViewTests */, 75 | 59D336DA1A91D23B0089837F /* Products */, 76 | ); 77 | sourceTree = ""; 78 | }; 79 | 59D336DA1A91D23B0089837F /* Products */ = { 80 | isa = PBXGroup; 81 | children = ( 82 | 59D336D91A91D23B0089837F /* IntroductionView.app */, 83 | 59D336F21A91D23B0089837F /* IntroductionViewTests.xctest */, 84 | ); 85 | name = Products; 86 | sourceTree = ""; 87 | }; 88 | 59D336DB1A91D23B0089837F /* IntroductionView */ = { 89 | isa = PBXGroup; 90 | children = ( 91 | 9516056C1D7D39AE007016EB /* intro_video.mp4 */, 92 | 59D336E01A91D23B0089837F /* AppDelegate.h */, 93 | 59D336E11A91D23B0089837F /* AppDelegate.m */, 94 | 59D336E31A91D23B0089837F /* ViewController.h */, 95 | 59D336E41A91D23B0089837F /* ViewController.m */, 96 | 59D336E91A91D23B0089837F /* Images.xcassets */, 97 | 59D336EB1A91D23B0089837F /* LaunchScreen.xib */, 98 | 59D336DC1A91D23B0089837F /* Supporting Files */, 99 | ); 100 | path = IntroductionView; 101 | sourceTree = ""; 102 | }; 103 | 59D336DC1A91D23B0089837F /* Supporting Files */ = { 104 | isa = PBXGroup; 105 | children = ( 106 | 59D336DD1A91D23B0089837F /* Info.plist */, 107 | 59D336DE1A91D23B0089837F /* main.m */, 108 | ); 109 | name = "Supporting Files"; 110 | sourceTree = ""; 111 | }; 112 | 59D336F51A91D23B0089837F /* IntroductionViewTests */ = { 113 | isa = PBXGroup; 114 | children = ( 115 | 59D336F81A91D23B0089837F /* IntroductionViewTests.m */, 116 | 59D336F61A91D23B0089837F /* Supporting Files */, 117 | ); 118 | path = IntroductionViewTests; 119 | sourceTree = ""; 120 | }; 121 | 59D336F61A91D23B0089837F /* Supporting Files */ = { 122 | isa = PBXGroup; 123 | children = ( 124 | 59D336F71A91D23B0089837F /* Info.plist */, 125 | ); 126 | name = "Supporting Files"; 127 | sourceTree = ""; 128 | }; 129 | 59D337021A91D2DC0089837F /* Library */ = { 130 | isa = PBXGroup; 131 | children = ( 132 | 59D337031A91D2DC0089837F /* ZWIntroductionViewController.h */, 133 | 59D337041A91D2DC0089837F /* ZWIntroductionViewController.m */, 134 | 952658631E4D8AAB00726779 /* ZWIntroductionView.h */, 135 | 952658641E4D8AAB00726779 /* ZWIntroductionView.m */, 136 | ); 137 | name = Library; 138 | path = ../../Library; 139 | sourceTree = ""; 140 | }; 141 | /* End PBXGroup section */ 142 | 143 | /* Begin PBXNativeTarget section */ 144 | 59D336D81A91D23B0089837F /* IntroductionView */ = { 145 | isa = PBXNativeTarget; 146 | buildConfigurationList = 59D336FC1A91D23B0089837F /* Build configuration list for PBXNativeTarget "IntroductionView" */; 147 | buildPhases = ( 148 | 59D336D51A91D23B0089837F /* Sources */, 149 | 59D336D61A91D23B0089837F /* Frameworks */, 150 | 59D336D71A91D23B0089837F /* Resources */, 151 | ); 152 | buildRules = ( 153 | ); 154 | dependencies = ( 155 | ); 156 | name = IntroductionView; 157 | productName = IntroductionView; 158 | productReference = 59D336D91A91D23B0089837F /* IntroductionView.app */; 159 | productType = "com.apple.product-type.application"; 160 | }; 161 | 59D336F11A91D23B0089837F /* IntroductionViewTests */ = { 162 | isa = PBXNativeTarget; 163 | buildConfigurationList = 59D336FF1A91D23B0089837F /* Build configuration list for PBXNativeTarget "IntroductionViewTests" */; 164 | buildPhases = ( 165 | 59D336EE1A91D23B0089837F /* Sources */, 166 | 59D336EF1A91D23B0089837F /* Frameworks */, 167 | 59D336F01A91D23B0089837F /* Resources */, 168 | ); 169 | buildRules = ( 170 | ); 171 | dependencies = ( 172 | 59D336F41A91D23B0089837F /* PBXTargetDependency */, 173 | ); 174 | name = IntroductionViewTests; 175 | productName = IntroductionViewTests; 176 | productReference = 59D336F21A91D23B0089837F /* IntroductionViewTests.xctest */; 177 | productType = "com.apple.product-type.bundle.unit-test"; 178 | }; 179 | /* End PBXNativeTarget section */ 180 | 181 | /* Begin PBXProject section */ 182 | 59D336D11A91D23B0089837F /* Project object */ = { 183 | isa = PBXProject; 184 | attributes = { 185 | LastUpgradeCheck = 0610; 186 | ORGANIZATIONNAME = square; 187 | TargetAttributes = { 188 | 59D336D81A91D23B0089837F = { 189 | CreatedOnToolsVersion = 6.1.1; 190 | }; 191 | 59D336F11A91D23B0089837F = { 192 | CreatedOnToolsVersion = 6.1.1; 193 | TestTargetID = 59D336D81A91D23B0089837F; 194 | }; 195 | }; 196 | }; 197 | buildConfigurationList = 59D336D41A91D23B0089837F /* Build configuration list for PBXProject "IntroductionView" */; 198 | compatibilityVersion = "Xcode 3.2"; 199 | developmentRegion = English; 200 | hasScannedForEncodings = 0; 201 | knownRegions = ( 202 | en, 203 | Base, 204 | ); 205 | mainGroup = 59D336D01A91D23B0089837F; 206 | productRefGroup = 59D336DA1A91D23B0089837F /* Products */; 207 | projectDirPath = ""; 208 | projectRoot = ""; 209 | targets = ( 210 | 59D336D81A91D23B0089837F /* IntroductionView */, 211 | 59D336F11A91D23B0089837F /* IntroductionViewTests */, 212 | ); 213 | }; 214 | /* End PBXProject section */ 215 | 216 | /* Begin PBXResourcesBuildPhase section */ 217 | 59D336D71A91D23B0089837F /* Resources */ = { 218 | isa = PBXResourcesBuildPhase; 219 | buildActionMask = 2147483647; 220 | files = ( 221 | 59D336ED1A91D23B0089837F /* LaunchScreen.xib in Resources */, 222 | 9516056D1D7D39AE007016EB /* intro_video.mp4 in Resources */, 223 | 59D336EA1A91D23B0089837F /* Images.xcassets in Resources */, 224 | ); 225 | runOnlyForDeploymentPostprocessing = 0; 226 | }; 227 | 59D336F01A91D23B0089837F /* Resources */ = { 228 | isa = PBXResourcesBuildPhase; 229 | buildActionMask = 2147483647; 230 | files = ( 231 | ); 232 | runOnlyForDeploymentPostprocessing = 0; 233 | }; 234 | /* End PBXResourcesBuildPhase section */ 235 | 236 | /* Begin PBXSourcesBuildPhase section */ 237 | 59D336D51A91D23B0089837F /* Sources */ = { 238 | isa = PBXSourcesBuildPhase; 239 | buildActionMask = 2147483647; 240 | files = ( 241 | 59D336E51A91D23B0089837F /* ViewController.m in Sources */, 242 | 59D336E21A91D23B0089837F /* AppDelegate.m in Sources */, 243 | 59D336DF1A91D23B0089837F /* main.m in Sources */, 244 | 59D337051A91D2DC0089837F /* ZWIntroductionViewController.m in Sources */, 245 | 952658651E4D8AAB00726779 /* ZWIntroductionView.m in Sources */, 246 | ); 247 | runOnlyForDeploymentPostprocessing = 0; 248 | }; 249 | 59D336EE1A91D23B0089837F /* Sources */ = { 250 | isa = PBXSourcesBuildPhase; 251 | buildActionMask = 2147483647; 252 | files = ( 253 | 59D336F91A91D23B0089837F /* IntroductionViewTests.m in Sources */, 254 | ); 255 | runOnlyForDeploymentPostprocessing = 0; 256 | }; 257 | /* End PBXSourcesBuildPhase section */ 258 | 259 | /* Begin PBXTargetDependency section */ 260 | 59D336F41A91D23B0089837F /* PBXTargetDependency */ = { 261 | isa = PBXTargetDependency; 262 | target = 59D336D81A91D23B0089837F /* IntroductionView */; 263 | targetProxy = 59D336F31A91D23B0089837F /* PBXContainerItemProxy */; 264 | }; 265 | /* End PBXTargetDependency section */ 266 | 267 | /* Begin PBXVariantGroup section */ 268 | 59D336EB1A91D23B0089837F /* LaunchScreen.xib */ = { 269 | isa = PBXVariantGroup; 270 | children = ( 271 | 59D336EC1A91D23B0089837F /* Base */, 272 | ); 273 | name = LaunchScreen.xib; 274 | sourceTree = ""; 275 | }; 276 | /* End PBXVariantGroup section */ 277 | 278 | /* Begin XCBuildConfiguration section */ 279 | 59D336FA1A91D23B0089837F /* Debug */ = { 280 | isa = XCBuildConfiguration; 281 | buildSettings = { 282 | ALWAYS_SEARCH_USER_PATHS = NO; 283 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 284 | CLANG_CXX_LIBRARY = "libc++"; 285 | CLANG_ENABLE_MODULES = YES; 286 | CLANG_ENABLE_OBJC_ARC = YES; 287 | CLANG_WARN_BOOL_CONVERSION = YES; 288 | CLANG_WARN_CONSTANT_CONVERSION = YES; 289 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 290 | CLANG_WARN_EMPTY_BODY = YES; 291 | CLANG_WARN_ENUM_CONVERSION = YES; 292 | CLANG_WARN_INT_CONVERSION = YES; 293 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 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 | ENABLE_STRICT_OBJC_MSGSEND = YES; 299 | GCC_C_LANGUAGE_STANDARD = gnu99; 300 | GCC_DYNAMIC_NO_PIC = NO; 301 | GCC_OPTIMIZATION_LEVEL = 0; 302 | GCC_PREPROCESSOR_DEFINITIONS = ( 303 | "DEBUG=1", 304 | "$(inherited)", 305 | ); 306 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 307 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 308 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 309 | GCC_WARN_UNDECLARED_SELECTOR = YES; 310 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 311 | GCC_WARN_UNUSED_FUNCTION = YES; 312 | GCC_WARN_UNUSED_VARIABLE = YES; 313 | IPHONEOS_DEPLOYMENT_TARGET = 8.1; 314 | MTL_ENABLE_DEBUG_INFO = YES; 315 | ONLY_ACTIVE_ARCH = YES; 316 | SDKROOT = iphoneos; 317 | TARGETED_DEVICE_FAMILY = "1,2"; 318 | }; 319 | name = Debug; 320 | }; 321 | 59D336FB1A91D23B0089837F /* Release */ = { 322 | isa = XCBuildConfiguration; 323 | buildSettings = { 324 | ALWAYS_SEARCH_USER_PATHS = NO; 325 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 326 | CLANG_CXX_LIBRARY = "libc++"; 327 | CLANG_ENABLE_MODULES = YES; 328 | CLANG_ENABLE_OBJC_ARC = YES; 329 | CLANG_WARN_BOOL_CONVERSION = YES; 330 | CLANG_WARN_CONSTANT_CONVERSION = YES; 331 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 332 | CLANG_WARN_EMPTY_BODY = YES; 333 | CLANG_WARN_ENUM_CONVERSION = YES; 334 | CLANG_WARN_INT_CONVERSION = YES; 335 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 336 | CLANG_WARN_UNREACHABLE_CODE = YES; 337 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 338 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 339 | COPY_PHASE_STRIP = YES; 340 | ENABLE_NS_ASSERTIONS = NO; 341 | ENABLE_STRICT_OBJC_MSGSEND = YES; 342 | GCC_C_LANGUAGE_STANDARD = gnu99; 343 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 344 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 345 | GCC_WARN_UNDECLARED_SELECTOR = YES; 346 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 347 | GCC_WARN_UNUSED_FUNCTION = YES; 348 | GCC_WARN_UNUSED_VARIABLE = YES; 349 | IPHONEOS_DEPLOYMENT_TARGET = 8.1; 350 | MTL_ENABLE_DEBUG_INFO = NO; 351 | SDKROOT = iphoneos; 352 | TARGETED_DEVICE_FAMILY = "1,2"; 353 | VALIDATE_PRODUCT = YES; 354 | }; 355 | name = Release; 356 | }; 357 | 59D336FD1A91D23B0089837F /* Debug */ = { 358 | isa = XCBuildConfiguration; 359 | buildSettings = { 360 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 361 | INFOPLIST_FILE = IntroductionView/Info.plist; 362 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 363 | PRODUCT_NAME = "$(TARGET_NAME)"; 364 | }; 365 | name = Debug; 366 | }; 367 | 59D336FE1A91D23B0089837F /* Release */ = { 368 | isa = XCBuildConfiguration; 369 | buildSettings = { 370 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 371 | INFOPLIST_FILE = IntroductionView/Info.plist; 372 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 373 | PRODUCT_NAME = "$(TARGET_NAME)"; 374 | }; 375 | name = Release; 376 | }; 377 | 59D337001A91D23B0089837F /* Debug */ = { 378 | isa = XCBuildConfiguration; 379 | buildSettings = { 380 | BUNDLE_LOADER = "$(TEST_HOST)"; 381 | FRAMEWORK_SEARCH_PATHS = ( 382 | "$(SDKROOT)/Developer/Library/Frameworks", 383 | "$(inherited)", 384 | ); 385 | GCC_PREPROCESSOR_DEFINITIONS = ( 386 | "DEBUG=1", 387 | "$(inherited)", 388 | ); 389 | INFOPLIST_FILE = IntroductionViewTests/Info.plist; 390 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 391 | PRODUCT_NAME = "$(TARGET_NAME)"; 392 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/IntroductionView.app/IntroductionView"; 393 | }; 394 | name = Debug; 395 | }; 396 | 59D337011A91D23B0089837F /* Release */ = { 397 | isa = XCBuildConfiguration; 398 | buildSettings = { 399 | BUNDLE_LOADER = "$(TEST_HOST)"; 400 | FRAMEWORK_SEARCH_PATHS = ( 401 | "$(SDKROOT)/Developer/Library/Frameworks", 402 | "$(inherited)", 403 | ); 404 | INFOPLIST_FILE = IntroductionViewTests/Info.plist; 405 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 406 | PRODUCT_NAME = "$(TARGET_NAME)"; 407 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/IntroductionView.app/IntroductionView"; 408 | }; 409 | name = Release; 410 | }; 411 | /* End XCBuildConfiguration section */ 412 | 413 | /* Begin XCConfigurationList section */ 414 | 59D336D41A91D23B0089837F /* Build configuration list for PBXProject "IntroductionView" */ = { 415 | isa = XCConfigurationList; 416 | buildConfigurations = ( 417 | 59D336FA1A91D23B0089837F /* Debug */, 418 | 59D336FB1A91D23B0089837F /* Release */, 419 | ); 420 | defaultConfigurationIsVisible = 0; 421 | defaultConfigurationName = Release; 422 | }; 423 | 59D336FC1A91D23B0089837F /* Build configuration list for PBXNativeTarget "IntroductionView" */ = { 424 | isa = XCConfigurationList; 425 | buildConfigurations = ( 426 | 59D336FD1A91D23B0089837F /* Debug */, 427 | 59D336FE1A91D23B0089837F /* Release */, 428 | ); 429 | defaultConfigurationIsVisible = 0; 430 | defaultConfigurationName = Release; 431 | }; 432 | 59D336FF1A91D23B0089837F /* Build configuration list for PBXNativeTarget "IntroductionViewTests" */ = { 433 | isa = XCConfigurationList; 434 | buildConfigurations = ( 435 | 59D337001A91D23B0089837F /* Debug */, 436 | 59D337011A91D23B0089837F /* Release */, 437 | ); 438 | defaultConfigurationIsVisible = 0; 439 | defaultConfigurationName = Release; 440 | }; 441 | /* End XCConfigurationList section */ 442 | }; 443 | rootObject = 59D336D11A91D23B0089837F /* Project object */; 444 | } 445 | -------------------------------------------------------------------------------- /Demo/Objective-C/IntroductionView/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // IntroductionView 4 | // 5 | // Created by square on 15/2/16. 6 | // Copyright (c) 2015年 square. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /Demo/Objective-C/IntroductionView/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // IntroductionView 4 | // 5 | // Created by square on 15/2/16. 6 | // Copyright (c) 2015年 square. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "ZWIntroductionViewController.h" 11 | #import "ViewController.h" 12 | 13 | @interface AppDelegate () 14 | 15 | @property (nonatomic, strong) ZWIntroductionView *introductionView; 16 | 17 | @property (nonatomic, strong) NSArray *coverImageNames; 18 | 19 | @property (nonatomic, strong) NSArray *backgroundImageNames; 20 | 21 | @property (nonatomic, strong) NSArray *coverTitles; 22 | 23 | @property (nonatomic, strong) NSURL *videoURL; 24 | 25 | @end 26 | 27 | @implementation AppDelegate 28 | 29 | 30 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 31 | 32 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 33 | self.window.backgroundColor = [UIColor whiteColor]; 34 | ViewController *vc = [[ViewController alloc] init]; 35 | self.window.rootViewController = vc; 36 | [_window makeKeyAndVisible]; 37 | 38 | // data source 39 | self.coverImageNames = @[@"img_index_01txt", @"img_index_02txt", @"img_index_03txt"]; 40 | self.backgroundImageNames = @[@"img_index_01bg", @"img_index_02bg", @"img_index_03bg"]; 41 | self.coverTitles = @[@"MAKE THE WORLD", @"THE BETTER PLACE"]; 42 | 43 | NSString *filePath = [[NSBundle mainBundle] pathForResource:@"intro_video" ofType:@"mp4"]; 44 | self.videoURL = [NSURL fileURLWithPath:filePath]; 45 | 46 | // Added Introduction View 47 | 48 | // self.introductionView = [self simpleIntroductionView]; 49 | 50 | // self.introductionView = [self coverImagesIntroductionView]; 51 | 52 | // self.introductionView = [self customButtonIntroductionView]; 53 | 54 | self.introductionView = [self videoIntroductionView]; 55 | 56 | // self.introductionView = [self advanceIntroductionView]; 57 | 58 | 59 | [self.window addSubview:self.introductionView]; 60 | 61 | __weak AppDelegate *weakSelf = self; 62 | self.introductionView.didSelectedEnter = ^() { 63 | [weakSelf.introductionView removeFromSuperview]; 64 | weakSelf.introductionView = nil; 65 | }; 66 | 67 | return YES; 68 | } 69 | 70 | // Example 1 : Simple 71 | - (ZWIntroductionView *)simpleIntroductionView 72 | { 73 | ZWIntroductionView *vc = [[ZWIntroductionView alloc] initWithCoverImageNames:self.backgroundImageNames]; 74 | return vc; 75 | } 76 | 77 | // Example 2 : Cover Images 78 | - (ZWIntroductionView *)coverImagesIntroductionView 79 | { 80 | ZWIntroductionView *vc = [[ZWIntroductionView alloc] initWithCoverImageNames:self.coverImageNames backgroundImageNames:self.backgroundImageNames]; 81 | return vc; 82 | } 83 | 84 | // Example 3 : Custom Button 85 | - (ZWIntroductionView *)customButtonIntroductionView 86 | { 87 | UIButton *enterButton = [UIButton new]; 88 | [enterButton setBackgroundImage:[UIImage imageNamed:@"bg_bar"] forState:UIControlStateNormal]; 89 | [enterButton setTitle:@"Login" forState:UIControlStateNormal]; 90 | ZWIntroductionView *vc = [[ZWIntroductionView alloc] initWithCoverImageNames:self.coverImageNames backgroundImageNames:self.backgroundImageNames button:enterButton]; 91 | return vc; 92 | } 93 | 94 | // Example 4 : Video 95 | - (ZWIntroductionView *)videoIntroductionView 96 | { 97 | ZWIntroductionView *vc = [[ZWIntroductionView alloc] initWithVideo:self.videoURL volume:0.7]; 98 | vc.coverImageNames = self.coverImageNames; 99 | vc.autoScrolling = YES; 100 | return vc; 101 | } 102 | 103 | // Example 5 : Advance 104 | - (ZWIntroductionView *)advanceIntroductionView 105 | { 106 | UIButton *loginButton = [[UIButton alloc] initWithFrame:CGRectMake(3, self.window.frame.size.height - 60, self.window.frame.size.width - 6, 50)]; 107 | loginButton.backgroundColor = [UIColor colorWithWhite:1 alpha:0.5]; 108 | [loginButton setTitle:@"Login" forState:UIControlStateNormal]; 109 | 110 | ZWIntroductionView *vc = [[ZWIntroductionView alloc] initWithVideo:self.videoURL volume:0.7]; 111 | vc.coverImageNames = self.coverImageNames; 112 | vc.autoScrolling = YES; 113 | vc.hiddenEnterButton = YES; 114 | vc.pageControlOffset = CGPointMake(0, -100); 115 | vc.labelAttributes = @{ NSFontAttributeName : [UIFont fontWithName:@"Arial-BoldMT" size:28.0], 116 | NSForegroundColorAttributeName : [UIColor whiteColor] }; 117 | vc.coverView = loginButton; 118 | 119 | vc.coverTitles = self.coverTitles; 120 | 121 | return vc; 122 | } 123 | @end 124 | -------------------------------------------------------------------------------- /Demo/Objective-C/IntroductionView/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Demo/Objective-C/IntroductionView/Images.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 | "info" : { 90 | "version" : 1, 91 | "author" : "xcode" 92 | } 93 | } -------------------------------------------------------------------------------- /Demo/Objective-C/IntroductionView/Images.xcassets/bg_bar.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "bg_mycenter_topbar@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Demo/Objective-C/IntroductionView/Images.xcassets/bg_bar.imageset/bg_mycenter_topbar@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/squarezw/ZWIntroductionViewController/b476ebe0b3eb335bb8a761b087b1d2c540b4508b/Demo/Objective-C/IntroductionView/Images.xcassets/bg_bar.imageset/bg_mycenter_topbar@2x.png -------------------------------------------------------------------------------- /Demo/Objective-C/IntroductionView/Images.xcassets/img_index_01bg.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "img_index_01bg@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Demo/Objective-C/IntroductionView/Images.xcassets/img_index_01bg.imageset/img_index_01bg@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/squarezw/ZWIntroductionViewController/b476ebe0b3eb335bb8a761b087b1d2c540b4508b/Demo/Objective-C/IntroductionView/Images.xcassets/img_index_01bg.imageset/img_index_01bg@2x.png -------------------------------------------------------------------------------- /Demo/Objective-C/IntroductionView/Images.xcassets/img_index_01txt.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "img_index_01txt@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Demo/Objective-C/IntroductionView/Images.xcassets/img_index_01txt.imageset/img_index_01txt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/squarezw/ZWIntroductionViewController/b476ebe0b3eb335bb8a761b087b1d2c540b4508b/Demo/Objective-C/IntroductionView/Images.xcassets/img_index_01txt.imageset/img_index_01txt@2x.png -------------------------------------------------------------------------------- /Demo/Objective-C/IntroductionView/Images.xcassets/img_index_02bg.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "img_index_02bg@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Demo/Objective-C/IntroductionView/Images.xcassets/img_index_02bg.imageset/img_index_02bg@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/squarezw/ZWIntroductionViewController/b476ebe0b3eb335bb8a761b087b1d2c540b4508b/Demo/Objective-C/IntroductionView/Images.xcassets/img_index_02bg.imageset/img_index_02bg@2x.png -------------------------------------------------------------------------------- /Demo/Objective-C/IntroductionView/Images.xcassets/img_index_02txt.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "img_index_02txt@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Demo/Objective-C/IntroductionView/Images.xcassets/img_index_02txt.imageset/img_index_02txt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/squarezw/ZWIntroductionViewController/b476ebe0b3eb335bb8a761b087b1d2c540b4508b/Demo/Objective-C/IntroductionView/Images.xcassets/img_index_02txt.imageset/img_index_02txt@2x.png -------------------------------------------------------------------------------- /Demo/Objective-C/IntroductionView/Images.xcassets/img_index_03bg.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "img_index_03bg@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Demo/Objective-C/IntroductionView/Images.xcassets/img_index_03bg.imageset/img_index_03bg@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/squarezw/ZWIntroductionViewController/b476ebe0b3eb335bb8a761b087b1d2c540b4508b/Demo/Objective-C/IntroductionView/Images.xcassets/img_index_03bg.imageset/img_index_03bg@2x.png -------------------------------------------------------------------------------- /Demo/Objective-C/IntroductionView/Images.xcassets/img_index_03txt.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "img_index_03txt@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Demo/Objective-C/IntroductionView/Images.xcassets/img_index_03txt.imageset/img_index_03txt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/squarezw/ZWIntroductionViewController/b476ebe0b3eb335bb8a761b087b1d2c540b4508b/Demo/Objective-C/IntroductionView/Images.xcassets/img_index_03txt.imageset/img_index_03txt@2x.png -------------------------------------------------------------------------------- /Demo/Objective-C/IntroductionView/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | square.ydio.com.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 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 | -------------------------------------------------------------------------------- /Demo/Objective-C/IntroductionView/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // IntroductionView 4 | // 5 | // Created by square on 15/2/16. 6 | // Copyright (c) 2015年 square. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /Demo/Objective-C/IntroductionView/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // IntroductionView 4 | // 5 | // Created by square on 15/2/16. 6 | // Copyright (c) 2015年 square. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | 11 | @interface ViewController () 12 | 13 | @end 14 | 15 | @implementation ViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | self.view.backgroundColor = [UIColor blackColor]; 20 | } 21 | 22 | - (void)didReceiveMemoryWarning { 23 | [super didReceiveMemoryWarning]; 24 | // Dispose of any resources that can be recreated. 25 | } 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /Demo/Objective-C/IntroductionView/intro_video.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/squarezw/ZWIntroductionViewController/b476ebe0b3eb335bb8a761b087b1d2c540b4508b/Demo/Objective-C/IntroductionView/intro_video.mp4 -------------------------------------------------------------------------------- /Demo/Objective-C/IntroductionView/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // IntroductionView 4 | // 5 | // Created by square on 15/2/16. 6 | // Copyright (c) 2015年 square. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Demo/Objective-C/IntroductionViewTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | square.ydio.com.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Demo/Objective-C/IntroductionViewTests/IntroductionViewTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // IntroductionViewTests.m 3 | // IntroductionViewTests 4 | // 5 | // Created by square on 15/2/16. 6 | // Copyright (c) 2015年 square. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface IntroductionViewTests : XCTestCase 13 | 14 | @end 15 | 16 | @implementation IntroductionViewTests 17 | 18 | - (void)setUp { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown { 24 | // Put teardown code here. This method is called after the invocation of each test method in the class. 25 | [super tearDown]; 26 | } 27 | 28 | - (void)testExample { 29 | // This is an example of a functional test case. 30 | XCTAssert(YES, @"Pass"); 31 | } 32 | 33 | - (void)testPerformanceExample { 34 | // This is an example of a performance test case. 35 | [self measureBlock:^{ 36 | // Put the code you want to measure the time of here. 37 | }]; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /Demo/Swift/IntroductionView.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 59B33E371AB6A0DF00E44832 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 59B33E361AB6A0DF00E44832 /* AppDelegate.swift */; }; 11 | 59B33E3E1AB6A0DF00E44832 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 59B33E3D1AB6A0DF00E44832 /* Images.xcassets */; }; 12 | 59B33E411AB6A0DF00E44832 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 59B33E3F1AB6A0DF00E44832 /* LaunchScreen.xib */; }; 13 | 59B33E4D1AB6A0DF00E44832 /* IntroductionViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 59B33E4C1AB6A0DF00E44832 /* IntroductionViewTests.swift */; }; 14 | 59B33E591AB6A11100E44832 /* ZWIntroductionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 59B33E581AB6A11100E44832 /* ZWIntroductionViewController.m */; }; 15 | 9516056F1D7D8298007016EB /* intro_video.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = 9516056E1D7D8298007016EB /* intro_video.mp4 */; }; 16 | 95A9DC901E4DAFC400814F88 /* ZWIntroductionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 95A9DC8F1E4DAFC400814F88 /* ZWIntroductionView.m */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXContainerItemProxy section */ 20 | 59B33E471AB6A0DF00E44832 /* PBXContainerItemProxy */ = { 21 | isa = PBXContainerItemProxy; 22 | containerPortal = 59B33E291AB6A0DF00E44832 /* Project object */; 23 | proxyType = 1; 24 | remoteGlobalIDString = 59B33E301AB6A0DF00E44832; 25 | remoteInfo = IntroductionView; 26 | }; 27 | /* End PBXContainerItemProxy section */ 28 | 29 | /* Begin PBXFileReference section */ 30 | 59B33E311AB6A0DF00E44832 /* IntroductionView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = IntroductionView.app; sourceTree = BUILT_PRODUCTS_DIR; }; 31 | 59B33E351AB6A0DF00E44832 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 32 | 59B33E361AB6A0DF00E44832 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 33 | 59B33E3D1AB6A0DF00E44832 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 34 | 59B33E401AB6A0DF00E44832 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 35 | 59B33E461AB6A0DF00E44832 /* IntroductionViewTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = IntroductionViewTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 36 | 59B33E4B1AB6A0DF00E44832 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 37 | 59B33E4C1AB6A0DF00E44832 /* IntroductionViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntroductionViewTests.swift; sourceTree = ""; }; 38 | 59B33E571AB6A11100E44832 /* ZWIntroductionViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZWIntroductionViewController.h; sourceTree = ""; }; 39 | 59B33E581AB6A11100E44832 /* ZWIntroductionViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZWIntroductionViewController.m; sourceTree = ""; }; 40 | 59B33E5A1AB6A13400E44832 /* IntroductionView-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "IntroductionView-Bridging-Header.h"; sourceTree = ""; }; 41 | 9516056E1D7D8298007016EB /* intro_video.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = intro_video.mp4; sourceTree = ""; }; 42 | 95A9DC8E1E4DAFC400814F88 /* ZWIntroductionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZWIntroductionView.h; sourceTree = ""; }; 43 | 95A9DC8F1E4DAFC400814F88 /* ZWIntroductionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZWIntroductionView.m; sourceTree = ""; }; 44 | /* End PBXFileReference section */ 45 | 46 | /* Begin PBXFrameworksBuildPhase section */ 47 | 59B33E2E1AB6A0DF00E44832 /* Frameworks */ = { 48 | isa = PBXFrameworksBuildPhase; 49 | buildActionMask = 2147483647; 50 | files = ( 51 | ); 52 | runOnlyForDeploymentPostprocessing = 0; 53 | }; 54 | 59B33E431AB6A0DF00E44832 /* Frameworks */ = { 55 | isa = PBXFrameworksBuildPhase; 56 | buildActionMask = 2147483647; 57 | files = ( 58 | ); 59 | runOnlyForDeploymentPostprocessing = 0; 60 | }; 61 | /* End PBXFrameworksBuildPhase section */ 62 | 63 | /* Begin PBXGroup section */ 64 | 59B33E281AB6A0DF00E44832 = { 65 | isa = PBXGroup; 66 | children = ( 67 | 59B33E331AB6A0DF00E44832 /* IntroductionView */, 68 | 59B33E491AB6A0DF00E44832 /* IntroductionViewTests */, 69 | 59B33E321AB6A0DF00E44832 /* Products */, 70 | ); 71 | sourceTree = ""; 72 | }; 73 | 59B33E321AB6A0DF00E44832 /* Products */ = { 74 | isa = PBXGroup; 75 | children = ( 76 | 59B33E311AB6A0DF00E44832 /* IntroductionView.app */, 77 | 59B33E461AB6A0DF00E44832 /* IntroductionViewTests.xctest */, 78 | ); 79 | name = Products; 80 | sourceTree = ""; 81 | }; 82 | 59B33E331AB6A0DF00E44832 /* IntroductionView */ = { 83 | isa = PBXGroup; 84 | children = ( 85 | 59B33E561AB6A11100E44832 /* Library */, 86 | 59B33E361AB6A0DF00E44832 /* AppDelegate.swift */, 87 | 59B33E3D1AB6A0DF00E44832 /* Images.xcassets */, 88 | 59B33E3F1AB6A0DF00E44832 /* LaunchScreen.xib */, 89 | 59B33E341AB6A0DF00E44832 /* Supporting Files */, 90 | 59B33E5A1AB6A13400E44832 /* IntroductionView-Bridging-Header.h */, 91 | ); 92 | path = IntroductionView; 93 | sourceTree = ""; 94 | }; 95 | 59B33E341AB6A0DF00E44832 /* Supporting Files */ = { 96 | isa = PBXGroup; 97 | children = ( 98 | 9516056E1D7D8298007016EB /* intro_video.mp4 */, 99 | 59B33E351AB6A0DF00E44832 /* Info.plist */, 100 | ); 101 | name = "Supporting Files"; 102 | sourceTree = ""; 103 | }; 104 | 59B33E491AB6A0DF00E44832 /* IntroductionViewTests */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | 59B33E4C1AB6A0DF00E44832 /* IntroductionViewTests.swift */, 108 | 59B33E4A1AB6A0DF00E44832 /* Supporting Files */, 109 | ); 110 | path = IntroductionViewTests; 111 | sourceTree = ""; 112 | }; 113 | 59B33E4A1AB6A0DF00E44832 /* Supporting Files */ = { 114 | isa = PBXGroup; 115 | children = ( 116 | 59B33E4B1AB6A0DF00E44832 /* Info.plist */, 117 | ); 118 | name = "Supporting Files"; 119 | sourceTree = ""; 120 | }; 121 | 59B33E561AB6A11100E44832 /* Library */ = { 122 | isa = PBXGroup; 123 | children = ( 124 | 95A9DC8E1E4DAFC400814F88 /* ZWIntroductionView.h */, 125 | 95A9DC8F1E4DAFC400814F88 /* ZWIntroductionView.m */, 126 | 59B33E571AB6A11100E44832 /* ZWIntroductionViewController.h */, 127 | 59B33E581AB6A11100E44832 /* ZWIntroductionViewController.m */, 128 | ); 129 | name = Library; 130 | path = ../../../Library; 131 | sourceTree = ""; 132 | }; 133 | /* End PBXGroup section */ 134 | 135 | /* Begin PBXNativeTarget section */ 136 | 59B33E301AB6A0DF00E44832 /* IntroductionView */ = { 137 | isa = PBXNativeTarget; 138 | buildConfigurationList = 59B33E501AB6A0DF00E44832 /* Build configuration list for PBXNativeTarget "IntroductionView" */; 139 | buildPhases = ( 140 | 59B33E2D1AB6A0DF00E44832 /* Sources */, 141 | 59B33E2E1AB6A0DF00E44832 /* Frameworks */, 142 | 59B33E2F1AB6A0DF00E44832 /* Resources */, 143 | ); 144 | buildRules = ( 145 | ); 146 | dependencies = ( 147 | ); 148 | name = IntroductionView; 149 | productName = IntroductionView; 150 | productReference = 59B33E311AB6A0DF00E44832 /* IntroductionView.app */; 151 | productType = "com.apple.product-type.application"; 152 | }; 153 | 59B33E451AB6A0DF00E44832 /* IntroductionViewTests */ = { 154 | isa = PBXNativeTarget; 155 | buildConfigurationList = 59B33E531AB6A0DF00E44832 /* Build configuration list for PBXNativeTarget "IntroductionViewTests" */; 156 | buildPhases = ( 157 | 59B33E421AB6A0DF00E44832 /* Sources */, 158 | 59B33E431AB6A0DF00E44832 /* Frameworks */, 159 | 59B33E441AB6A0DF00E44832 /* Resources */, 160 | ); 161 | buildRules = ( 162 | ); 163 | dependencies = ( 164 | 59B33E481AB6A0DF00E44832 /* PBXTargetDependency */, 165 | ); 166 | name = IntroductionViewTests; 167 | productName = IntroductionViewTests; 168 | productReference = 59B33E461AB6A0DF00E44832 /* IntroductionViewTests.xctest */; 169 | productType = "com.apple.product-type.bundle.unit-test"; 170 | }; 171 | /* End PBXNativeTarget section */ 172 | 173 | /* Begin PBXProject section */ 174 | 59B33E291AB6A0DF00E44832 /* Project object */ = { 175 | isa = PBXProject; 176 | attributes = { 177 | LastSwiftUpdateCheck = 0730; 178 | LastUpgradeCheck = 0610; 179 | ORGANIZATIONNAME = square; 180 | TargetAttributes = { 181 | 59B33E301AB6A0DF00E44832 = { 182 | CreatedOnToolsVersion = 6.1.1; 183 | LastSwiftMigration = 0830; 184 | }; 185 | 59B33E451AB6A0DF00E44832 = { 186 | CreatedOnToolsVersion = 6.1.1; 187 | LastSwiftMigration = 0830; 188 | TestTargetID = 59B33E301AB6A0DF00E44832; 189 | }; 190 | }; 191 | }; 192 | buildConfigurationList = 59B33E2C1AB6A0DF00E44832 /* Build configuration list for PBXProject "IntroductionView" */; 193 | compatibilityVersion = "Xcode 3.2"; 194 | developmentRegion = English; 195 | hasScannedForEncodings = 0; 196 | knownRegions = ( 197 | en, 198 | Base, 199 | ); 200 | mainGroup = 59B33E281AB6A0DF00E44832; 201 | productRefGroup = 59B33E321AB6A0DF00E44832 /* Products */; 202 | projectDirPath = ""; 203 | projectRoot = ""; 204 | targets = ( 205 | 59B33E301AB6A0DF00E44832 /* IntroductionView */, 206 | 59B33E451AB6A0DF00E44832 /* IntroductionViewTests */, 207 | ); 208 | }; 209 | /* End PBXProject section */ 210 | 211 | /* Begin PBXResourcesBuildPhase section */ 212 | 59B33E2F1AB6A0DF00E44832 /* Resources */ = { 213 | isa = PBXResourcesBuildPhase; 214 | buildActionMask = 2147483647; 215 | files = ( 216 | 59B33E411AB6A0DF00E44832 /* LaunchScreen.xib in Resources */, 217 | 9516056F1D7D8298007016EB /* intro_video.mp4 in Resources */, 218 | 59B33E3E1AB6A0DF00E44832 /* Images.xcassets in Resources */, 219 | ); 220 | runOnlyForDeploymentPostprocessing = 0; 221 | }; 222 | 59B33E441AB6A0DF00E44832 /* Resources */ = { 223 | isa = PBXResourcesBuildPhase; 224 | buildActionMask = 2147483647; 225 | files = ( 226 | ); 227 | runOnlyForDeploymentPostprocessing = 0; 228 | }; 229 | /* End PBXResourcesBuildPhase section */ 230 | 231 | /* Begin PBXSourcesBuildPhase section */ 232 | 59B33E2D1AB6A0DF00E44832 /* Sources */ = { 233 | isa = PBXSourcesBuildPhase; 234 | buildActionMask = 2147483647; 235 | files = ( 236 | 95A9DC901E4DAFC400814F88 /* ZWIntroductionView.m in Sources */, 237 | 59B33E371AB6A0DF00E44832 /* AppDelegate.swift in Sources */, 238 | 59B33E591AB6A11100E44832 /* ZWIntroductionViewController.m in Sources */, 239 | ); 240 | runOnlyForDeploymentPostprocessing = 0; 241 | }; 242 | 59B33E421AB6A0DF00E44832 /* Sources */ = { 243 | isa = PBXSourcesBuildPhase; 244 | buildActionMask = 2147483647; 245 | files = ( 246 | 59B33E4D1AB6A0DF00E44832 /* IntroductionViewTests.swift in Sources */, 247 | ); 248 | runOnlyForDeploymentPostprocessing = 0; 249 | }; 250 | /* End PBXSourcesBuildPhase section */ 251 | 252 | /* Begin PBXTargetDependency section */ 253 | 59B33E481AB6A0DF00E44832 /* PBXTargetDependency */ = { 254 | isa = PBXTargetDependency; 255 | target = 59B33E301AB6A0DF00E44832 /* IntroductionView */; 256 | targetProxy = 59B33E471AB6A0DF00E44832 /* PBXContainerItemProxy */; 257 | }; 258 | /* End PBXTargetDependency section */ 259 | 260 | /* Begin PBXVariantGroup section */ 261 | 59B33E3F1AB6A0DF00E44832 /* LaunchScreen.xib */ = { 262 | isa = PBXVariantGroup; 263 | children = ( 264 | 59B33E401AB6A0DF00E44832 /* Base */, 265 | ); 266 | name = LaunchScreen.xib; 267 | sourceTree = ""; 268 | }; 269 | /* End PBXVariantGroup section */ 270 | 271 | /* Begin XCBuildConfiguration section */ 272 | 59B33E4E1AB6A0DF00E44832 /* Debug */ = { 273 | isa = XCBuildConfiguration; 274 | buildSettings = { 275 | ALWAYS_SEARCH_USER_PATHS = NO; 276 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 277 | CLANG_CXX_LIBRARY = "libc++"; 278 | CLANG_ENABLE_MODULES = YES; 279 | CLANG_ENABLE_OBJC_ARC = YES; 280 | CLANG_WARN_BOOL_CONVERSION = YES; 281 | CLANG_WARN_CONSTANT_CONVERSION = YES; 282 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 283 | CLANG_WARN_EMPTY_BODY = YES; 284 | CLANG_WARN_ENUM_CONVERSION = YES; 285 | CLANG_WARN_INT_CONVERSION = YES; 286 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 287 | CLANG_WARN_UNREACHABLE_CODE = YES; 288 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 289 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 290 | COPY_PHASE_STRIP = NO; 291 | ENABLE_STRICT_OBJC_MSGSEND = YES; 292 | GCC_C_LANGUAGE_STANDARD = gnu99; 293 | GCC_DYNAMIC_NO_PIC = NO; 294 | GCC_OPTIMIZATION_LEVEL = 0; 295 | GCC_PREPROCESSOR_DEFINITIONS = ( 296 | "DEBUG=1", 297 | "$(inherited)", 298 | ); 299 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 300 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 301 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 302 | GCC_WARN_UNDECLARED_SELECTOR = YES; 303 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 304 | GCC_WARN_UNUSED_FUNCTION = YES; 305 | GCC_WARN_UNUSED_VARIABLE = YES; 306 | IPHONEOS_DEPLOYMENT_TARGET = 8.1; 307 | MTL_ENABLE_DEBUG_INFO = YES; 308 | ONLY_ACTIVE_ARCH = YES; 309 | SDKROOT = iphoneos; 310 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 311 | }; 312 | name = Debug; 313 | }; 314 | 59B33E4F1AB6A0DF00E44832 /* Release */ = { 315 | isa = XCBuildConfiguration; 316 | buildSettings = { 317 | ALWAYS_SEARCH_USER_PATHS = NO; 318 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 319 | CLANG_CXX_LIBRARY = "libc++"; 320 | CLANG_ENABLE_MODULES = YES; 321 | CLANG_ENABLE_OBJC_ARC = YES; 322 | CLANG_WARN_BOOL_CONVERSION = YES; 323 | CLANG_WARN_CONSTANT_CONVERSION = YES; 324 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 325 | CLANG_WARN_EMPTY_BODY = YES; 326 | CLANG_WARN_ENUM_CONVERSION = YES; 327 | CLANG_WARN_INT_CONVERSION = YES; 328 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 329 | CLANG_WARN_UNREACHABLE_CODE = YES; 330 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 331 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 332 | COPY_PHASE_STRIP = YES; 333 | ENABLE_NS_ASSERTIONS = NO; 334 | ENABLE_STRICT_OBJC_MSGSEND = YES; 335 | GCC_C_LANGUAGE_STANDARD = gnu99; 336 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 337 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 338 | GCC_WARN_UNDECLARED_SELECTOR = YES; 339 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 340 | GCC_WARN_UNUSED_FUNCTION = YES; 341 | GCC_WARN_UNUSED_VARIABLE = YES; 342 | IPHONEOS_DEPLOYMENT_TARGET = 8.1; 343 | MTL_ENABLE_DEBUG_INFO = NO; 344 | SDKROOT = iphoneos; 345 | VALIDATE_PRODUCT = YES; 346 | }; 347 | name = Release; 348 | }; 349 | 59B33E511AB6A0DF00E44832 /* Debug */ = { 350 | isa = XCBuildConfiguration; 351 | buildSettings = { 352 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 353 | INFOPLIST_FILE = IntroductionView/Info.plist; 354 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 355 | PRODUCT_NAME = "$(TARGET_NAME)"; 356 | SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/IntroductionView/IntroductionView-Bridging-Header.h"; 357 | SWIFT_VERSION = 3.0; 358 | }; 359 | name = Debug; 360 | }; 361 | 59B33E521AB6A0DF00E44832 /* Release */ = { 362 | isa = XCBuildConfiguration; 363 | buildSettings = { 364 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 365 | INFOPLIST_FILE = IntroductionView/Info.plist; 366 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 367 | PRODUCT_NAME = "$(TARGET_NAME)"; 368 | SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/IntroductionView/IntroductionView-Bridging-Header.h"; 369 | SWIFT_VERSION = 3.0; 370 | }; 371 | name = Release; 372 | }; 373 | 59B33E541AB6A0DF00E44832 /* Debug */ = { 374 | isa = XCBuildConfiguration; 375 | buildSettings = { 376 | BUNDLE_LOADER = "$(TEST_HOST)"; 377 | FRAMEWORK_SEARCH_PATHS = ( 378 | "$(SDKROOT)/Developer/Library/Frameworks", 379 | "$(inherited)", 380 | ); 381 | GCC_PREPROCESSOR_DEFINITIONS = ( 382 | "DEBUG=1", 383 | "$(inherited)", 384 | ); 385 | INFOPLIST_FILE = IntroductionViewTests/Info.plist; 386 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 387 | PRODUCT_NAME = "$(TARGET_NAME)"; 388 | SWIFT_VERSION = 3.0; 389 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/IntroductionView.app/IntroductionView"; 390 | }; 391 | name = Debug; 392 | }; 393 | 59B33E551AB6A0DF00E44832 /* Release */ = { 394 | isa = XCBuildConfiguration; 395 | buildSettings = { 396 | BUNDLE_LOADER = "$(TEST_HOST)"; 397 | FRAMEWORK_SEARCH_PATHS = ( 398 | "$(SDKROOT)/Developer/Library/Frameworks", 399 | "$(inherited)", 400 | ); 401 | INFOPLIST_FILE = IntroductionViewTests/Info.plist; 402 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 403 | PRODUCT_NAME = "$(TARGET_NAME)"; 404 | SWIFT_VERSION = 3.0; 405 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/IntroductionView.app/IntroductionView"; 406 | }; 407 | name = Release; 408 | }; 409 | /* End XCBuildConfiguration section */ 410 | 411 | /* Begin XCConfigurationList section */ 412 | 59B33E2C1AB6A0DF00E44832 /* Build configuration list for PBXProject "IntroductionView" */ = { 413 | isa = XCConfigurationList; 414 | buildConfigurations = ( 415 | 59B33E4E1AB6A0DF00E44832 /* Debug */, 416 | 59B33E4F1AB6A0DF00E44832 /* Release */, 417 | ); 418 | defaultConfigurationIsVisible = 0; 419 | defaultConfigurationName = Release; 420 | }; 421 | 59B33E501AB6A0DF00E44832 /* Build configuration list for PBXNativeTarget "IntroductionView" */ = { 422 | isa = XCConfigurationList; 423 | buildConfigurations = ( 424 | 59B33E511AB6A0DF00E44832 /* Debug */, 425 | 59B33E521AB6A0DF00E44832 /* Release */, 426 | ); 427 | defaultConfigurationIsVisible = 0; 428 | defaultConfigurationName = Release; 429 | }; 430 | 59B33E531AB6A0DF00E44832 /* Build configuration list for PBXNativeTarget "IntroductionViewTests" */ = { 431 | isa = XCConfigurationList; 432 | buildConfigurations = ( 433 | 59B33E541AB6A0DF00E44832 /* Debug */, 434 | 59B33E551AB6A0DF00E44832 /* Release */, 435 | ); 436 | defaultConfigurationIsVisible = 0; 437 | defaultConfigurationName = Release; 438 | }; 439 | /* End XCConfigurationList section */ 440 | }; 441 | rootObject = 59B33E291AB6A0DF00E44832 /* Project object */; 442 | } 443 | -------------------------------------------------------------------------------- /Demo/Swift/IntroductionView/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // IntroductionView 4 | // 5 | // Created by square on 15/3/16. 6 | // Copyright (c) 2015年 square. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | var introductionView: ZWIntroductionView! 16 | var viewController: UIViewController? 17 | 18 | var coverImageNames: [String]? 19 | var backgroundImageNames: [String]? 20 | var coverTitles: [String]? 21 | var videoURL: URL? 22 | 23 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 24 | self.window = UIWindow() 25 | self.window?.makeKeyAndVisible() 26 | 27 | // You could add a empty View Controoler like this one or build a 28 | // ZWIntroductionViewController as Welcome page. 29 | // if you used ZWIntroductionViewController class, pls have a look 30 | // ZWIntroductionViewController API, most of them are same with below 31 | // initialized method of ZWIntroductionView 32 | self.window?.rootViewController = UIViewController() 33 | 34 | // data source 35 | self.coverImageNames = ["img_index_01txt","img_index_02txt", "img_index_03txt"] 36 | self.backgroundImageNames = ["img_index_01bg","img_index_02bg", "img_index_03bg"] 37 | self.coverTitles = ["MAKE THE WORLD", "THE BETTER PLACE"] 38 | 39 | let filePath = Bundle.main.path(forResource: "intro_video", ofType: "mp4") 40 | self.videoURL = URL(fileURLWithPath: filePath!) 41 | 42 | // Added Introduction View 43 | 44 | // self.introductionView = self.simpleIntroductionView() 45 | 46 | // self.introductionView = self.coverImagesIntroductionView() 47 | 48 | // self.introductionView = self.customButtonIntroductionView() 49 | 50 | // self.introductionView = self.videoIntroductionView(); 51 | 52 | self.introductionView = self.advanceIntroductionView(); 53 | 54 | self.window?.addSubview(self.introductionView) 55 | 56 | self.introductionView.didSelectedEnter = { 57 | self.introductionView!.removeFromSuperview() 58 | self.introductionView = nil; 59 | // enter main view , write your code ... 60 | // self.window.rootViewController = your root view controller 61 | } 62 | 63 | return true 64 | } 65 | 66 | // Example 1 : Simple 67 | func simpleIntroductionView() -> ZWIntroductionView { 68 | let vc = ZWIntroductionView(coverImageNames: self.backgroundImageNames)! 69 | return vc 70 | } 71 | 72 | // Example 2 : Cover Images 73 | func coverImagesIntroductionView() -> ZWIntroductionView { 74 | let vc = ZWIntroductionView(coverImageNames: self.coverImageNames, backgroundImageNames: self.backgroundImageNames)! 75 | return vc 76 | } 77 | 78 | // Example 3 : Custom Button 79 | func customButtonIntroductionView() -> ZWIntroductionView { 80 | let enterButton = UIButton() 81 | enterButton.setBackgroundImage(UIImage(named: "bg_bar"), for: UIControlState()) 82 | enterButton.setTitle("Login", for: UIControlState()) 83 | let vc = ZWIntroductionView(coverImageNames: self.coverImageNames, backgroundImageNames: self.backgroundImageNames, button: enterButton)! 84 | return vc 85 | } 86 | 87 | // Example 4 : Video 88 | func videoIntroductionView() -> ZWIntroductionView { 89 | let vc = ZWIntroductionView(video: self.videoURL)! 90 | vc.coverImageNames = self.coverImageNames 91 | vc.autoScrolling = true 92 | return vc 93 | } 94 | 95 | // Example 5 : Advance 96 | func advanceIntroductionView() -> ZWIntroductionView { 97 | let loginButton = UIButton(frame: CGRect(x: 3, y: self.window!.frame.size.height - 60, width: self.window!.frame.size.width - 6, height: 50)) 98 | loginButton.backgroundColor = UIColor.init(white: 1, alpha: 0.5) 99 | loginButton.setTitle("Login", for: UIControlState()) 100 | // loginButton.addTarget(self, action: #selector(<#the function that could close welcome page#>), for: .touchUpInside) 101 | let vc = ZWIntroductionView(video: self.videoURL, volume: 0.7)! 102 | vc.coverImageNames = self.coverImageNames 103 | vc.autoScrolling = true 104 | vc.hiddenEnterButton = true 105 | vc.pageControlOffset = CGPoint(x: 0, y: -100) 106 | vc.labelAttributes = [NSFontAttributeName: UIFont(name: "Arial-BoldMT", size: 28.0)!, 107 | NSForegroundColorAttributeName: UIColor.white] 108 | vc.coverView = loginButton 109 | 110 | vc.coverTitles = self.coverTitles 111 | 112 | return vc 113 | } 114 | 115 | } 116 | 117 | -------------------------------------------------------------------------------- /Demo/Swift/IntroductionView/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Demo/Swift/IntroductionView/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /Demo/Swift/IntroductionView/Images.xcassets/bg_bar.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "bg_mycenter_topbar@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Demo/Swift/IntroductionView/Images.xcassets/bg_bar.imageset/bg_mycenter_topbar@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/squarezw/ZWIntroductionViewController/b476ebe0b3eb335bb8a761b087b1d2c540b4508b/Demo/Swift/IntroductionView/Images.xcassets/bg_bar.imageset/bg_mycenter_topbar@2x.png -------------------------------------------------------------------------------- /Demo/Swift/IntroductionView/Images.xcassets/img_index_01bg.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "img_index_01bg@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Demo/Swift/IntroductionView/Images.xcassets/img_index_01bg.imageset/img_index_01bg@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/squarezw/ZWIntroductionViewController/b476ebe0b3eb335bb8a761b087b1d2c540b4508b/Demo/Swift/IntroductionView/Images.xcassets/img_index_01bg.imageset/img_index_01bg@2x.png -------------------------------------------------------------------------------- /Demo/Swift/IntroductionView/Images.xcassets/img_index_01txt.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "img_index_01txt@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Demo/Swift/IntroductionView/Images.xcassets/img_index_01txt.imageset/img_index_01txt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/squarezw/ZWIntroductionViewController/b476ebe0b3eb335bb8a761b087b1d2c540b4508b/Demo/Swift/IntroductionView/Images.xcassets/img_index_01txt.imageset/img_index_01txt@2x.png -------------------------------------------------------------------------------- /Demo/Swift/IntroductionView/Images.xcassets/img_index_02bg.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "img_index_02bg@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Demo/Swift/IntroductionView/Images.xcassets/img_index_02bg.imageset/img_index_02bg@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/squarezw/ZWIntroductionViewController/b476ebe0b3eb335bb8a761b087b1d2c540b4508b/Demo/Swift/IntroductionView/Images.xcassets/img_index_02bg.imageset/img_index_02bg@2x.png -------------------------------------------------------------------------------- /Demo/Swift/IntroductionView/Images.xcassets/img_index_02txt.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "img_index_02txt@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Demo/Swift/IntroductionView/Images.xcassets/img_index_02txt.imageset/img_index_02txt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/squarezw/ZWIntroductionViewController/b476ebe0b3eb335bb8a761b087b1d2c540b4508b/Demo/Swift/IntroductionView/Images.xcassets/img_index_02txt.imageset/img_index_02txt@2x.png -------------------------------------------------------------------------------- /Demo/Swift/IntroductionView/Images.xcassets/img_index_03bg.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "img_index_03bg@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Demo/Swift/IntroductionView/Images.xcassets/img_index_03bg.imageset/img_index_03bg@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/squarezw/ZWIntroductionViewController/b476ebe0b3eb335bb8a761b087b1d2c540b4508b/Demo/Swift/IntroductionView/Images.xcassets/img_index_03bg.imageset/img_index_03bg@2x.png -------------------------------------------------------------------------------- /Demo/Swift/IntroductionView/Images.xcassets/img_index_03txt.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "img_index_03txt@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Demo/Swift/IntroductionView/Images.xcassets/img_index_03txt.imageset/img_index_03txt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/squarezw/ZWIntroductionViewController/b476ebe0b3eb335bb8a761b087b1d2c540b4508b/Demo/Swift/IntroductionView/Images.xcassets/img_index_03txt.imageset/img_index_03txt@2x.png -------------------------------------------------------------------------------- /Demo/Swift/IntroductionView/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | square.ydio.com.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Demo/Swift/IntroductionView/IntroductionView-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // IntroductionView-Bridging-Header.h 3 | // IntroductionView 4 | // 5 | // Created by square on 15/3/16. 6 | // Copyright (c) 2015年 square. All rights reserved. 7 | // 8 | 9 | #import "ZWIntroductionViewController.h" 10 | -------------------------------------------------------------------------------- /Demo/Swift/IntroductionView/intro_video.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/squarezw/ZWIntroductionViewController/b476ebe0b3eb335bb8a761b087b1d2c540b4508b/Demo/Swift/IntroductionView/intro_video.mp4 -------------------------------------------------------------------------------- /Demo/Swift/IntroductionViewTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | square.ydio.com.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Demo/Swift/IntroductionViewTests/IntroductionViewTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IntroductionViewTests.swift 3 | // IntroductionViewTests 4 | // 5 | // Created by square on 15/3/16. 6 | // Copyright (c) 2015年 square. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import XCTest 11 | 12 | class IntroductionViewTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | XCTAssert(true, "Pass") 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measure() { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Square 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /Library/ZWIntroductionView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZWIntroductionView.h 3 | // IntroductionView 4 | // 5 | // Created by Jesse on 10/02/2017. 6 | // Copyright © 2017 square. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | typedef void (^ZWIntroductionSelectedEnter)(); 13 | 14 | @interface ZWIntroductionView : UIView 15 | 16 | @property (nonatomic, strong) UIScrollView *pagingScrollView; 17 | @property (nonatomic, strong) UIButton *enterButton; 18 | @property (nonatomic, assign) BOOL hiddenEnterButton; // default is NO 19 | @property (nonatomic, assign) BOOL autoScrolling; // default is NO 20 | @property (nonatomic, assign) BOOL autoLoopPlayVideo; // default is YES 21 | 22 | @property (nonatomic, copy) ZWIntroductionSelectedEnter didSelectedEnter; 23 | 24 | @property (nonatomic, strong) UIView *coverView; // default is nil 25 | 26 | @property (nonatomic, assign) CGPoint pageControlOffset; // default is {0,-30} 27 | 28 | /** 29 | @[@"image1", @"image2"] 30 | */ 31 | @property (nonatomic, strong) NSArray *backgroundImageNames; 32 | 33 | /** 34 | @[@"coverImage1", @"coverImage2"] 35 | */ 36 | @property (nonatomic, strong) NSArray *coverImageNames; 37 | 38 | /** 39 | @[@"make the world", @"the better place"] 40 | */ 41 | @property (nonatomic, strong) NSArray *coverTitles; 42 | @property (nonatomic, strong) NSDictionary *labelAttributes; 43 | 44 | // video volume 45 | @property (nonatomic) float volume; 46 | 47 | - (id)initWithCoverImageNames:(NSArray*)coverNames; 48 | 49 | - (id)initWithCoverImageNames:(NSArray*)coverNames backgroundImageNames:(NSArray*)bgNames; 50 | 51 | - (id)initWithCoverImageNames:(NSArray*)coverNames backgroundImageNames:(NSArray*)bgNames button:(UIButton*)button; 52 | 53 | // default volume is 0 54 | - (id)initWithVideo:(NSURL*)videoURL; 55 | 56 | - (id)initWithVideo:(NSURL*)videoURL volume:(float)volume; 57 | 58 | @end 59 | 60 | -------------------------------------------------------------------------------- /Library/ZWIntroductionView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZWIntroductionView.m 3 | // IntroductionView 4 | // 5 | // Created by Jesse on 10/02/2017. 6 | // Copyright © 2017 square. All rights reserved. 7 | // 8 | 9 | #import "ZWIntroductionView.h" 10 | 11 | @interface ZWIntroductionView () 12 | 13 | @property (nonatomic, strong) NSArray *backgroundViews; 14 | @property (nonatomic, strong) NSArray *scrollViewPages; 15 | @property (nonatomic, strong) UIPageControl *pageControl; 16 | @property (nonatomic, assign) NSInteger centerPageIndex; 17 | 18 | @property (nonatomic) NSURL *videoURL; 19 | @property (nonatomic) AVPlayer *player; 20 | @property (nonatomic) NSTimer *timer; 21 | 22 | @property (nonatomic, strong) AVPlayerLayer *playerLayer; 23 | 24 | @end 25 | 26 | @implementation ZWIntroductionView 27 | 28 | @synthesize pageControlOffset = _pageControlOffset; 29 | 30 | - (void)dealloc 31 | { 32 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 33 | [self.player pause]; 34 | self.player = nil; 35 | [self stopTimer]; 36 | } 37 | 38 | - (void)stopTimer 39 | { 40 | [self.timer invalidate]; 41 | self.timer = nil; 42 | } 43 | 44 | - (void)startTimer 45 | { 46 | if (self.autoScrolling) { 47 | self.timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(onTimer) userInfo:nil repeats:YES]; 48 | } 49 | } 50 | 51 | - (id)initWithCoverImageNames:(NSArray *)coverNames 52 | { 53 | return [self initWithCoverImageNames:coverNames backgroundImageNames:nil button:nil]; 54 | } 55 | 56 | - (id)initWithCoverImageNames:(NSArray *)coverNames backgroundImageNames:(NSArray *)bgNames 57 | { 58 | return [self initWithCoverImageNames:coverNames backgroundImageNames:bgNames button:nil]; 59 | } 60 | 61 | - (id)initWithCoverImageNames:(NSArray *)coverNames backgroundImageNames:(NSArray *)bgNames button:(UIButton *)button 62 | { 63 | if (self = [super init]) { 64 | self.coverImageNames = coverNames; 65 | self.backgroundImageNames = bgNames; 66 | self.enterButton = button; 67 | [self initSelf]; 68 | } 69 | return self; 70 | } 71 | 72 | - (id)initWithVideo:(NSURL *)videoURL 73 | { 74 | return [self initWithVideo:videoURL volume:0]; 75 | } 76 | 77 | - (id)initWithVideo:(NSURL *)videoURL volume:(float)volume 78 | { 79 | if (self = [super init]) { 80 | self.videoURL = videoURL; 81 | self.volume = volume; 82 | [self initSelf]; 83 | } 84 | return self; 85 | } 86 | 87 | - (void)initSelf 88 | { 89 | self.hiddenEnterButton = NO; 90 | self.autoScrolling = NO; 91 | self.autoLoopPlayVideo = YES; 92 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil]; 93 | 94 | [self buildSubviews]; 95 | } 96 | 97 | - (void)applicationWillEnterForeground:(id)sender 98 | { 99 | [self.player play]; 100 | } 101 | 102 | - (void)setCoverView:(UIView *)coverView { 103 | _coverView = coverView; 104 | [self addSubview:coverView]; 105 | } 106 | 107 | #pragma mark - View lifecycle 108 | 109 | - (void)willMoveToSuperview:(UIView *)newSuperview 110 | { 111 | [super willMoveToSuperview:newSuperview]; 112 | self.frame = newSuperview.frame; 113 | } 114 | 115 | - (void)setFrame:(CGRect)frame 116 | { 117 | [super setFrame:frame]; 118 | 119 | if (CGRectEqualToRect(self.bounds, self.pagingScrollView.frame)) { 120 | return; 121 | } 122 | 123 | self.playerLayer.frame = self.layer.bounds; 124 | self.pagingScrollView.frame = self.bounds; 125 | self.pageControl.frame = [self frameOfPageControl]; 126 | self.enterButton.frame = [self frameOfEnterButton]; 127 | 128 | [self reloadPages]; 129 | } 130 | 131 | - (void)buildSubviews { 132 | [self addVideo]; 133 | 134 | [self addBackgroundViews]; 135 | 136 | self.pagingScrollView = [[UIScrollView alloc] init]; 137 | self.pagingScrollView.delegate = self; 138 | self.pagingScrollView.pagingEnabled = YES; 139 | self.pagingScrollView.showsHorizontalScrollIndicator = NO; 140 | 141 | [self addSubview:self.pagingScrollView]; 142 | 143 | self.pageControl = [[UIPageControl alloc] init]; 144 | self.pageControl.pageIndicatorTintColor = [UIColor grayColor]; 145 | [self addSubview:self.pageControl]; 146 | 147 | if (!self.enterButton) { 148 | self.enterButton = [UIButton new]; 149 | [self.enterButton setTitle:NSLocalizedString(@"Enter", nil) forState:UIControlStateNormal]; 150 | self.enterButton.layer.borderWidth = 0.5; 151 | self.enterButton.layer.borderColor = [UIColor whiteColor].CGColor; 152 | self.enterButton.hidden = self.hiddenEnterButton; 153 | } 154 | 155 | [self.enterButton addTarget:self action:@selector(enter:) forControlEvents:UIControlEventTouchUpInside]; 156 | self.enterButton.alpha = 0; 157 | [self addSubview:self.enterButton]; 158 | 159 | [self addSubview:self.coverView]; 160 | 161 | [self startTimer]; 162 | } 163 | 164 | - (void)onTimer 165 | { 166 | CGRect frame = self.pagingScrollView.frame; 167 | frame.origin.x = frame.size.width * (self.pageControl.currentPage + 1); 168 | frame.origin.y = 0; 169 | if (frame.origin.x >= self.pagingScrollView.contentSize.width) { 170 | frame.origin.x = 0; 171 | } 172 | [self.pagingScrollView scrollRectToVisible:frame animated:YES]; 173 | } 174 | 175 | - (void)addBackgroundViews 176 | { 177 | CGRect frame = self.bounds; 178 | NSMutableArray *tmpArray = [NSMutableArray new]; 179 | [[[[self backgroundImageNames] reverseObjectEnumerator] allObjects] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 180 | UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:obj]]; 181 | imageView.frame = frame; 182 | imageView.tag = idx + 1; 183 | [tmpArray addObject:imageView]; 184 | [self addSubview:imageView]; 185 | }]; 186 | 187 | self.backgroundViews = [[tmpArray reverseObjectEnumerator] allObjects]; 188 | } 189 | 190 | #pragma mark - Video 191 | 192 | - (void)addVideo 193 | { 194 | if (!self.videoURL) { 195 | return; 196 | } 197 | 198 | AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:self.videoURL]; 199 | 200 | self.player = [AVPlayer playerWithPlayerItem:playerItem]; 201 | self.player.volume = self.volume; 202 | 203 | self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player]; 204 | self.playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; 205 | self.playerLayer.frame = self.layer.bounds; 206 | [self.layer addSublayer:self.playerLayer]; 207 | 208 | [self.player play]; 209 | 210 | [[NSNotificationCenter defaultCenter] addObserver:self 211 | selector:@selector(moviePlayDidEnd:) 212 | name:AVPlayerItemDidPlayToEndTimeNotification 213 | object:self.player.currentItem]; 214 | } 215 | 216 | - (void)moviePlayDidEnd:(NSNotification*)notification{ 217 | if (self.autoLoopPlayVideo) { 218 | // loop movie 219 | AVPlayerItem *item = [notification object]; 220 | [item seekToTime:kCMTimeZero]; 221 | [self.player play]; 222 | } else { 223 | [self enter:nil]; 224 | } 225 | } 226 | 227 | 228 | #pragma mark - load items 229 | 230 | - (void)reloadPages 231 | { 232 | self.pageControl.numberOfPages = [self numberOfPagesInPagingScrollView]; 233 | self.pagingScrollView.contentSize = [self contentSizeOfScrollView]; 234 | 235 | __block CGFloat x = 0; 236 | [[self scrollViewPages] enumerateObjectsUsingBlock:^(UIView *obj, NSUInteger idx, BOOL *stop) { 237 | obj.frame = CGRectOffset(obj.frame, x, 0); 238 | [self.pagingScrollView addSubview:obj]; 239 | 240 | x += obj.frame.size.width; 241 | }]; 242 | 243 | // fix enterButton can not presenting if ScrollView have only one page 244 | if (self.pageControl.numberOfPages == 1) { 245 | self.enterButton.alpha = 1; 246 | self.pageControl.alpha = 0; 247 | } 248 | 249 | // fix ScrollView can not scrolling if it have only one page 250 | if (self.pagingScrollView.contentSize.width == self.pagingScrollView.frame.size.width) { 251 | self.pagingScrollView.contentSize = CGSizeMake(self.pagingScrollView.contentSize.width + 1, self.pagingScrollView.contentSize.height); 252 | } 253 | 254 | [[self backgroundViews] enumerateObjectsUsingBlock:^(UIView *obj, NSUInteger idx, BOOL * _Nonnull stop) { 255 | obj.frame = CGRectMake(obj.frame.origin.x, obj.frame.origin.y, self.frame.size.width, self.frame.size.height); 256 | }]; 257 | } 258 | 259 | - (CGRect)frameOfPageControl 260 | { 261 | CGRect orgFrame = CGRectMake(0, self.bounds.size.height, self.bounds.size.width, 30); 262 | return CGRectOffset(orgFrame, self.pageControlOffset.x, self.pageControlOffset.y); 263 | } 264 | 265 | - (CGPoint)pageControlOffset 266 | { 267 | if (CGPointEqualToPoint(_pageControlOffset, CGPointZero)) { 268 | return CGPointMake(0, -30); 269 | } 270 | return _pageControlOffset; 271 | } 272 | 273 | - (CGRect)frameOfEnterButton 274 | { 275 | CGSize size = self.enterButton.bounds.size; 276 | if (CGSizeEqualToSize(size, CGSizeZero)) { 277 | size = CGSizeMake(self.frame.size.width * 0.6, 40); 278 | } 279 | return CGRectMake(self.frame.size.width / 2 - size.width / 2, self.pageControl.frame.origin.y - size.height, size.width, size.height); 280 | } 281 | 282 | #pragma mark - UIScrollViewDelegate 283 | 284 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView 285 | { 286 | NSInteger index = scrollView.contentOffset.x / self.frame.size.width; 287 | CGFloat alpha = 1 - ((scrollView.contentOffset.x - index * self.frame.size.width) / self.frame.size.width); 288 | 289 | if ([self.backgroundViews count] > index) { 290 | UIView *v = [self.backgroundViews objectAtIndex:index]; 291 | if (v) { 292 | [v setAlpha:alpha]; 293 | } 294 | } 295 | 296 | self.pageControl.currentPage = scrollView.contentOffset.x / (scrollView.contentSize.width / [self numberOfPagesInPagingScrollView]); 297 | 298 | [self pagingScrollViewDidChangePages:scrollView]; 299 | 300 | if (scrollView.isTracking) { 301 | [self stopTimer]; 302 | } else { 303 | if (!self.timer) { 304 | [self startTimer]; 305 | } 306 | } 307 | } 308 | 309 | - (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView 310 | { 311 | if ([scrollView.panGestureRecognizer translationInView:scrollView.superview].x < 0) { 312 | if (![self hasNext:self.pageControl]) { 313 | [self enter:nil]; 314 | } 315 | } 316 | } 317 | 318 | #pragma mark - UIScrollView & UIPageControl DataSource 319 | 320 | - (BOOL)hasNext:(UIPageControl*)pageControl 321 | { 322 | return pageControl.numberOfPages > pageControl.currentPage + 1; 323 | } 324 | 325 | - (BOOL)isLast:(UIPageControl*)pageControl 326 | { 327 | return pageControl.numberOfPages == pageControl.currentPage + 1; 328 | } 329 | 330 | - (NSInteger)numberOfPagesInPagingScrollView 331 | { 332 | if (self.coverTitles) { 333 | return self.coverTitles.count; 334 | } else { 335 | return self.coverImageNames.count; 336 | } 337 | } 338 | 339 | - (void)pagingScrollViewDidChangePages:(UIScrollView *)pagingScrollView 340 | { 341 | if (self.hiddenEnterButton) { 342 | return; 343 | } 344 | 345 | if ([self isLast:self.pageControl]) { 346 | if (self.pageControl.alpha == 1) { 347 | self.enterButton.alpha = 0; 348 | 349 | [UIView animateWithDuration:0.4 animations:^{ 350 | self.enterButton.alpha = 1; 351 | self.pageControl.alpha = 0; 352 | }]; 353 | } 354 | } else { 355 | if (self.pageControl.alpha == 0) { 356 | [UIView animateWithDuration:0.4 animations:^{ 357 | self.enterButton.alpha = 0; 358 | self.pageControl.alpha = 1; 359 | }]; 360 | } 361 | } 362 | } 363 | 364 | - (BOOL)hasEnterButtonInView:(UIView*)page 365 | { 366 | __block BOOL result = NO; 367 | [page.subviews enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 368 | if (obj && obj == self.enterButton) { 369 | result = YES; 370 | } 371 | }]; 372 | return result; 373 | } 374 | 375 | - (UIView*)pageViewWithImageName:(NSString*)name 376 | { 377 | UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:name]]; 378 | CGSize size = self.frame.size; 379 | imageView.frame = CGRectMake(self.bounds.origin.x, self.bounds.origin.y, size.width, size.height); 380 | return imageView; 381 | } 382 | 383 | - (UIView*)pageViewWithTitle:(NSString*)title 384 | { 385 | CGSize size = self.frame.size; 386 | CGRect rect; 387 | CGFloat height = 30; 388 | if ([[[UIDevice currentDevice] systemVersion] compare:@"7.0"] != NSOrderedAscending) { 389 | CGSize size = [title sizeWithAttributes:self.labelAttributes]; 390 | height = size.height; 391 | } 392 | rect = CGRectMake(0, size.height + self.pageControlOffset.y - height, size.width, height); 393 | 394 | UILabel *label = [[UILabel alloc] initWithFrame:rect]; 395 | label.textAlignment = NSTextAlignmentCenter; 396 | label.attributedText = [[NSAttributedString alloc] initWithString:title attributes:self.labelAttributes]; 397 | return label; 398 | } 399 | 400 | - (NSArray*)scrollViewPages 401 | { 402 | if ([self numberOfPagesInPagingScrollView] == 0) { 403 | return nil; 404 | } 405 | 406 | if (_scrollViewPages) { 407 | return _scrollViewPages; 408 | } 409 | 410 | 411 | NSMutableArray *tmpArray = [NSMutableArray new]; 412 | 413 | if (self.coverTitles) { 414 | [self.coverTitles enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 415 | 416 | [tmpArray addObject:[self pageViewWithTitle:obj]]; 417 | 418 | }]; 419 | } else if (self.coverImageNames) { 420 | [self.coverImageNames enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 421 | 422 | [tmpArray addObject:[self pageViewWithImageName:obj]]; 423 | 424 | }]; 425 | } 426 | 427 | _scrollViewPages = tmpArray; 428 | 429 | return _scrollViewPages; 430 | } 431 | 432 | - (CGSize)contentSizeOfScrollView 433 | { 434 | UIView *view = [[self scrollViewPages] firstObject]; 435 | return CGSizeMake(view.frame.size.width * self.scrollViewPages.count, view.frame.size.height); 436 | } 437 | 438 | #pragma mark - Action 439 | 440 | - (void)enter:(id)object 441 | { 442 | [self stopTimer]; 443 | 444 | if (self.didSelectedEnter) { 445 | self.didSelectedEnter(); 446 | } 447 | } 448 | 449 | - (void)didReceiveMemoryWarning { 450 | // [super didReceiveMemoryWarning]; 451 | // Dispose of any resources that can be recreated. 452 | } 453 | 454 | @end 455 | 456 | -------------------------------------------------------------------------------- /Library/ZWIntroductionViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // LGIntroductionViewController.h 3 | // 4 | // Created by square on 15/1/21. 5 | // Copyright (c) 2015年 square. All rights reserved. 6 | // 7 | 8 | #import 9 | #import 10 | #import "ZWIntroductionView.h" 11 | 12 | typedef void (^DidSelectedEnter)(); 13 | 14 | // Warning: This class may not exist in the future - no promises . Using ZWIntroductionView to initialize 15 | @interface ZWIntroductionViewController : UIViewController 16 | 17 | @property (nonatomic, strong) ZWIntroductionView *introductionView; 18 | 19 | // !!!: Following properties has been forwarded to the introductionView; 20 | @property (nonatomic, strong) UIScrollView *pagingScrollView; 21 | @property (nonatomic, strong) UIButton *enterButton; 22 | @property (nonatomic, assign) BOOL hiddenEnterButton; // default is NO 23 | @property (nonatomic, assign) BOOL autoScrolling; // default is NO DEPRECATED_ATTRIBUTE 24 | @property (nonatomic, assign) BOOL autoLoopPlayVideo; // default is YES DEPRECATED_ATTRIBUTE 25 | 26 | @property (nonatomic, copy) DidSelectedEnter didSelectedEnter; 27 | 28 | @property (nonatomic, strong) UIView *coverView; // default is nil 29 | 30 | @property (nonatomic, assign) CGPoint pageControlOffset; // default is {0,-30} 31 | 32 | /** 33 | @[@"image1", @"image2"] 34 | */ 35 | @property (nonatomic, strong) NSArray *backgroundImageNames; 36 | 37 | /** 38 | @[@"coverImage1", @"coverImage2"] 39 | */ 40 | @property (nonatomic, strong) NSArray *coverImageNames; 41 | 42 | /** 43 | @[@"make the world", @"the better place"] 44 | */ 45 | @property (nonatomic, strong) NSArray *coverTitles; 46 | @property (nonatomic, strong) NSDictionary *labelAttributes; 47 | 48 | // video volume 49 | @property (nonatomic) float volume; 50 | 51 | // Warning: 52 | // !!!: Following methods has been forwarded to the introductionView; 53 | 54 | - (id)initWithCoverImageNames:(NSArray*)coverNames; 55 | 56 | - (id)initWithCoverImageNames:(NSArray*)coverNames backgroundImageNames:(NSArray*)bgNames; 57 | 58 | - (id)initWithCoverImageNames:(NSArray*)coverNames backgroundImageNames:(NSArray*)bgNames button:(UIButton*)button; 59 | 60 | // default volume is 0 61 | - (id)initWithVideo:(NSURL*)videoURL; 62 | 63 | - (id)initWithVideo:(NSURL*)videoURL volume:(float)volume; 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /Library/ZWIntroductionViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // LGIntroductionViewController.m 3 | // 4 | // Created by square on 15/1/21. 5 | // Copyright (c) 2015年 square. All rights reserved. 6 | // 7 | 8 | #import "ZWIntroductionViewController.h" 9 | 10 | @implementation ZWIntroductionViewController 11 | 12 | - (void)dealloc 13 | { 14 | [self.introductionView removeFromSuperview]; 15 | self.introductionView = nil; 16 | } 17 | 18 | // -- Properties 19 | 20 | - (UIScrollView *)pagingScrollView { 21 | return self.introductionView.pagingScrollView; 22 | } 23 | 24 | - (void)setPagingScrollView:(UIScrollView *)pagingScrollView 25 | { 26 | self.introductionView.pagingScrollView = pagingScrollView; 27 | } 28 | 29 | - (UIButton *)enterButton { 30 | return self.introductionView.enterButton; 31 | } 32 | 33 | - (void)setEnterButton:(UIButton *)enterButton { 34 | self.introductionView.enterButton = enterButton; 35 | } 36 | 37 | - (BOOL)hiddenEnterButton { 38 | return self.introductionView.hiddenEnterButton; 39 | } 40 | 41 | - (void)setHiddenEnterButton:(BOOL)hiddenEnterButton { 42 | self.introductionView.hiddenEnterButton = hiddenEnterButton; 43 | } 44 | 45 | - (BOOL)autoScrolling { 46 | return self.introductionView.autoScrolling; 47 | } 48 | 49 | - (void)setAutoScrolling:(BOOL)autoScrolling { 50 | self.introductionView.autoScrolling = autoScrolling; 51 | } 52 | 53 | - (BOOL)autoLoopPlayVideo { 54 | return self.introductionView.autoLoopPlayVideo; 55 | } 56 | 57 | - (void)setAutoLoopPlayVideo:(BOOL)autoLoopPlayVideo { 58 | self.introductionView.autoLoopPlayVideo = autoLoopPlayVideo; 59 | } 60 | 61 | - (UIView *)coverView { 62 | return self.introductionView.coverView; 63 | } 64 | 65 | - (void)setCoverView:(UIView *)coverView { 66 | self.introductionView.coverView = coverView; 67 | } 68 | 69 | - (CGPoint)pageControlOffset { 70 | return self.introductionView.pageControlOffset; 71 | } 72 | 73 | - (void)setPageControlOffset:(CGPoint)pageControlOffset { 74 | self.introductionView.pageControlOffset = pageControlOffset; 75 | } 76 | 77 | - (NSArray *)backgroundImageNames { 78 | return self.introductionView.backgroundImageNames; 79 | } 80 | 81 | - (void)setBackgroundImageNames:(NSArray *)backgroundImageNames { 82 | self.introductionView.backgroundImageNames = backgroundImageNames; 83 | } 84 | 85 | - (NSArray *)coverImageNames { 86 | return self.introductionView.coverImageNames; 87 | } 88 | 89 | - (void)setCoverImageNames:(NSArray *)coverImageNames { 90 | self.introductionView.coverImageNames = coverImageNames; 91 | } 92 | 93 | - (NSArray *)coverTitles { 94 | return self.introductionView.coverTitles; 95 | } 96 | 97 | - (void)setCoverTitles:(NSArray *)coverTitles { 98 | self.introductionView.coverTitles = coverTitles; 99 | } 100 | 101 | - (NSDictionary *)labelAttributes { 102 | return self.introductionView.labelAttributes; 103 | } 104 | 105 | - (void)setLabelAttributes:(NSDictionary *)labelAttributes { 106 | self.introductionView.labelAttributes = labelAttributes; 107 | } 108 | 109 | - (float)volume { 110 | return self.introductionView.volume; 111 | } 112 | 113 | - (void)setVolume:(float)volume { 114 | self.introductionView.volume = volume; 115 | } 116 | 117 | - (DidSelectedEnter)didSelectedEnter { 118 | return self.introductionView.didSelectedEnter; 119 | } 120 | 121 | - (void)setDidSelectedEnter:(DidSelectedEnter)didSelectedEnter 122 | { 123 | self.introductionView.didSelectedEnter = didSelectedEnter; 124 | } 125 | 126 | // View lifecycle 127 | - (void)viewDidLoad { 128 | [super viewDidLoad]; 129 | [self.view addSubview:self.introductionView]; 130 | self.introductionView.didSelectedEnter = self.didSelectedEnter; 131 | } 132 | 133 | - (id)initWithCoverImageNames:(NSArray*)coverNames 134 | { 135 | return [self initWithCoverImageNames:coverNames backgroundImageNames:nil button:nil]; 136 | } 137 | 138 | - (id)initWithCoverImageNames:(NSArray*)coverNames backgroundImageNames:(NSArray*)bgNames 139 | { 140 | return [self initWithCoverImageNames:coverNames backgroundImageNames:bgNames button:nil]; 141 | } 142 | 143 | - (id)initWithCoverImageNames:(NSArray*)coverNames backgroundImageNames:(NSArray*)bgNames button:(UIButton*)button 144 | { 145 | if (self = [super init]) { 146 | self.introductionView = [[ZWIntroductionView alloc ] initWithCoverImageNames:coverNames backgroundImageNames:bgNames button:button]; 147 | } 148 | return self; 149 | } 150 | 151 | - (id)initWithVideo:(NSURL*)videoURL 152 | { 153 | return [self initWithVideo:videoURL volume:0.0]; 154 | } 155 | 156 | - (id)initWithVideo:(NSURL*)videoURL volume:(float)volume 157 | { 158 | if (self = [super init]) { 159 | self.introductionView = [[ZWIntroductionView alloc ] initWithVideo:videoURL volume:volume]; 160 | } 161 | return self; 162 | } 163 | 164 | 165 | @end 166 | 167 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | What? 2 | ----- 3 | **Introduction View** 4 | 5 | It will display a fullscreen swipeable modal window to guide the user through a welcome screen / tutorial 6 | 7 | 8 | - Video 9 | 10 | ![Screenshot](https://github.com/squarezw/ZWIntroductionViewController/blob/master/video.gif) 11 | 12 | - Cover 13 | 14 | ![Screenshot](https://github.com/squarezw/ZWIntroductionViewController/blob/master/screenshot.gif) 15 | 16 | 17 | - Simple Version 18 | 19 | ![Sample application screenshot](https://github.com/squarezw/ZWIntroductionViewController/blob/master/simple.gif "Screenshot of sample application on iPhone") 20 | 21 | 22 | 23 | 24 | 25 | 26 | Usage? 27 | ---- 28 | 29 | ### Swift 30 | 31 | 32 | ``` 33 | // data source 34 | self.coverImageNames = ["img_index_01txt","img_index_02txt", "img_index_03txt"] 35 | self.backgroundImageNames = ["img_index_01bg","img_index_02bg", "img_index_03bg"] 36 | self.coverTitles = ["MAKE THE WORLD", "THE BETTER PLACE"] 37 | 38 | let filePath = NSBundle.mainBundle().pathForResource("intro_video", ofType: "mp4") 39 | self.videoURL = NSURL.fileURLWithPath(filePath!) 40 | 41 | // Added Introduction View 42 | 43 | // self.introductionView = self.simpleIntroductionView() 44 | 45 | // self.introductionView = self.coverImagesIntroductionView() 46 | 47 | // self.introductionView = self.customButtonIntroductionView() 48 | 49 | self.introductionView = self.videoIntroductionView(); 50 | 51 | // self.introductionView = self.advanceIntroductionView(); 52 | 53 | self.window?.addSubview(self.introductionView) 54 | 55 | self.introductionView!.didSelectedEnter = { 56 | self.introductionView!.removeFromSuperview() 57 | self.introductionView = nil; 58 | // enter main view , write your code ... 59 | } 60 | 61 | // Example 1 : Simple 62 | func simpleIntroductionView() -> ZWIntroductionView { 63 | let vc = ZWIntroductionView(coverImageNames: self.backgroundImageNames) 64 | return vc 65 | } 66 | 67 | // Example 2 : Cover Images 68 | func coverImagesIntroductionView() -> ZWIntroductionView { 69 | let vc = ZWIntroductionView(coverImageNames: self.coverImageNames, backgroundImageNames: self.backgroundImageNames) 70 | return vc 71 | } 72 | 73 | // Example 3 : Custom Button 74 | func customButtonIntroductionView() -> ZWIntroductionView { 75 | let enterButton = UIButton() 76 | enterButton.setBackgroundImage(UIImage(named: "bg_bar"), forState: .Normal) 77 | enterButton.setTitle("Login", forState: .Normal) 78 | let vc = ZWIntroductionView(coverImageNames: self.coverImageNames, backgroundImageNames: self.backgroundImageNames, button: enterButton) 79 | return vc 80 | } 81 | 82 | // Example 4 : Video 83 | func videoIntroductionView() -> ZWIntroductionView { 84 | let vc = ZWIntroductionView(video: self.videoURL) 85 | vc.coverImageNames = self.coverImageNames 86 | vc.autoScrolling = true 87 | return vc 88 | } 89 | 90 | // Example 5 : Advance 91 | func advanceIntroductionView() -> ZWIntroductionView { 92 | let loginButton = UIButton(frame: CGRectMake(3, self.window!.frame.size.height - 60, self.window!.frame.size.width - 6, 50)) 93 | loginButton.backgroundColor = UIColor.init(white: 1, alpha: 0.5) 94 | loginButton.setTitle("Login", forState: .Normal) 95 | let vc = ZWIntroductionView(video: self.videoURL, volume: 0.7) 96 | vc.coverImageNames = self.coverImageNames 97 | vc.autoScrolling = true 98 | vc.hiddenEnterButton = true 99 | vc.pageControlOffset = CGPointMake(0, -100) 100 | vc.labelAttributes = [NSFontAttributeName: UIFont(name: "Arial-BoldMT", size: 28.0)!, 101 | NSForegroundColorAttributeName: UIColor.whiteColor()] 102 | vc.coverView = loginButton 103 | 104 | vc.coverTitles = self.coverTitles 105 | 106 | return vc 107 | } 108 | 109 | ``` 110 | 111 | ### Objective-C 112 | 113 | ``` 114 | // data source 115 | 116 | self.coverImageNames = @[@"img_index_01txt", @"img_index_02txt", @"img_index_03txt"]; 117 | self.backgroundImageNames = @[@"img_index_01bg", @"img_index_02bg", @"img_index_03bg"]; 118 | self.coverTitles = @[@"MAKE THE WORLD", @"THE BETTER PLACE"]; 119 | 120 | NSString *filePath = [[NSBundle mainBundle] pathForResource:@"intro_video" ofType:@"mp4"]; 121 | self.videoURL = [NSURL fileURLWithPath:filePath]; 122 | 123 | // Added Introduction View 124 | 125 | // self.introductionView = [self simpleIntroductionView]; 126 | 127 | // self.introductionView = [self coverImagesIntroductionView]; 128 | 129 | // self.introductionView = [self customButtonIntroductionView]; 130 | 131 | self.introductionView = [self videoIntroductionView]; 132 | 133 | // self.introductionView = [self advanceIntroductionView]; 134 | 135 | 136 | [self.window addSubview:self.introductionView]; 137 | 138 | __weak AppDelegate *weakSelf = self; 139 | self.introductionView.didSelectedEnter = ^() { 140 | [weakSelf.introductionView removeFromSuperview]; 141 | weakSelf.introductionView = nil; 142 | }; 143 | ``` 144 | 145 | > Take a look at the Example project to see how to use customization using more 146 | 147 | Installation? 148 | ------------- 149 | 150 | This project includes a `podspec` for usage with [CocoaPods](http://http://cocoapods.org/). Simply add 151 | 152 | pod 'ZWIntroductionViewController' 153 | 154 | to your `Podfile` and run `pod install`. 155 | 156 | Alternately, you can add all of the files contained in this project's `Library` directory to your Xcode project. If your project does not use ARC, you will need to enable ARC on these files. You can enabled ARC per-file by adding the -fobjc-arc flag, as described on [a common StackOverflow question](http://stackoverflow.com/questions/6646052/how-can-i-disable-arc-for-a-single-file-in-a-project). 157 | 158 | License 159 | ------- 160 | 161 | This project is licensed under the MIT license. All copyright rights are retained by myself. 162 | 163 | Copyright (c) 2015 Square 164 | 165 | Permission is hereby granted, free of charge, to any person obtaining a copy 166 | of this software and associated documentation files (the "Software"), to deal 167 | in the Software without restriction, including without limitation the rights 168 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 169 | copies of the Software, and to permit persons to whom the Software is 170 | furnished to do so, subject to the following conditions: 171 | 172 | The above copyright notice and this permission notice shall be included in 173 | all copies or substantial portions of the Software. 174 | 175 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 176 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 177 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 178 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 179 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 180 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 181 | THE SOFTWARE. 182 | -------------------------------------------------------------------------------- /ZWIntroductionViewController.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ZWIntroductionViewController", 3 | "version": "0.3.7", 4 | "summary": "A simple custom App tutorials and welcome video", 5 | "homepage": "https://github.com/squarezw/ZWIntroductionViewController", 6 | "license": { 7 | "type": "MIT", 8 | "file": "LICENSE.txt" 9 | }, 10 | "authors": { 11 | "square": "square.zhao.wei@gmail.com" 12 | }, 13 | "platforms": { 14 | "ios": "7.0" 15 | }, 16 | "source": { 17 | "git": "https://github.com/squarezw/ZWIntroductionViewController.git", 18 | "tag": "0.3.7" 19 | }, 20 | "source_files": "Library/*.{h,m}", 21 | "requires_arc": true 22 | } 23 | -------------------------------------------------------------------------------- /demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/squarezw/ZWIntroductionViewController/b476ebe0b3eb335bb8a761b087b1d2c540b4508b/demo.png -------------------------------------------------------------------------------- /screenshot.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/squarezw/ZWIntroductionViewController/b476ebe0b3eb335bb8a761b087b1d2c540b4508b/screenshot.gif -------------------------------------------------------------------------------- /simple.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/squarezw/ZWIntroductionViewController/b476ebe0b3eb335bb8a761b087b1d2c540b4508b/simple.gif -------------------------------------------------------------------------------- /video.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/squarezw/ZWIntroductionViewController/b476ebe0b3eb335bb8a761b087b1d2c540b4508b/video.gif --------------------------------------------------------------------------------