├── Examples ├── RGDynamicOnboard.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── RGDynamicOnboard.xccheckout ├── RGDynamicOnboard │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Base.lproj │ │ ├── LaunchScreen.xib │ │ └── Main.storyboard │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ ├── background.imageset │ │ │ ├── Contents.json │ │ │ └── background.png │ │ ├── firstImage.imageset │ │ │ ├── Contents.json │ │ │ └── firstImage.png │ │ ├── fourthImage.imageset │ │ │ ├── Contents.json │ │ │ └── fourthImage.png │ │ ├── mountain.imageset │ │ │ ├── Contents.json │ │ │ └── mountain.png │ │ ├── secondImage.imageset │ │ │ ├── Contents.json │ │ │ └── firstAnimation.png │ │ ├── thirdImage.imageset │ │ │ ├── Contents.json │ │ │ └── thirdImage.png │ │ └── welcomeImage.imageset │ │ │ ├── Contents.json │ │ │ └── welcomeImage.png │ ├── Info.plist │ ├── RGDynamicOnboard.h │ ├── RGDynamicOnboard.m │ ├── ViewController.h │ ├── ViewController.m │ └── main.m └── RGDynamicOnboardTests │ ├── Info.plist │ └── RGDynamicOnboardTests.m ├── README.md ├── RGDynamicOnboard.h ├── RGDynamicOnboard.m ├── RGDynamicOnboard.podspec └── Resources ├── AppFirst.gif ├── AppSecond.gif ├── Header.png ├── LICENSE.md └── background.png /Examples/RGDynamicOnboard.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | F62635671AB210E900E1EF4D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = F62635661AB210E900E1EF4D /* main.m */; }; 11 | F626356A1AB210E900E1EF4D /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = F62635691AB210E900E1EF4D /* AppDelegate.m */; }; 12 | F626356D1AB210E900E1EF4D /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F626356C1AB210E900E1EF4D /* ViewController.m */; }; 13 | F62635701AB210E900E1EF4D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F626356E1AB210E900E1EF4D /* Main.storyboard */; }; 14 | F62635721AB210E900E1EF4D /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F62635711AB210E900E1EF4D /* Images.xcassets */; }; 15 | F62635751AB210E900E1EF4D /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = F62635731AB210E900E1EF4D /* LaunchScreen.xib */; }; 16 | F62635811AB210E900E1EF4D /* RGDynamicOnboardTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F62635801AB210E900E1EF4D /* RGDynamicOnboardTests.m */; }; 17 | F626358C1AB213C200E1EF4D /* RGDynamicOnboard.m in Sources */ = {isa = PBXBuildFile; fileRef = F626358B1AB213C200E1EF4D /* RGDynamicOnboard.m */; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXContainerItemProxy section */ 21 | F626357B1AB210E900E1EF4D /* PBXContainerItemProxy */ = { 22 | isa = PBXContainerItemProxy; 23 | containerPortal = F62635591AB210E900E1EF4D /* Project object */; 24 | proxyType = 1; 25 | remoteGlobalIDString = F62635601AB210E900E1EF4D; 26 | remoteInfo = RGDynamicOnboard; 27 | }; 28 | /* End PBXContainerItemProxy section */ 29 | 30 | /* Begin PBXFileReference section */ 31 | F62635611AB210E900E1EF4D /* RGDynamicOnboard.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RGDynamicOnboard.app; sourceTree = BUILT_PRODUCTS_DIR; }; 32 | F62635651AB210E900E1EF4D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 33 | F62635661AB210E900E1EF4D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 34 | F62635681AB210E900E1EF4D /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 35 | F62635691AB210E900E1EF4D /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 36 | F626356B1AB210E900E1EF4D /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 37 | F626356C1AB210E900E1EF4D /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 38 | F626356F1AB210E900E1EF4D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 39 | F62635711AB210E900E1EF4D /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 40 | F62635741AB210E900E1EF4D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 41 | F626357A1AB210E900E1EF4D /* RGDynamicOnboardTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RGDynamicOnboardTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 42 | F626357F1AB210E900E1EF4D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 43 | F62635801AB210E900E1EF4D /* RGDynamicOnboardTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RGDynamicOnboardTests.m; sourceTree = ""; }; 44 | F626358A1AB213C200E1EF4D /* RGDynamicOnboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RGDynamicOnboard.h; sourceTree = ""; }; 45 | F626358B1AB213C200E1EF4D /* RGDynamicOnboard.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RGDynamicOnboard.m; sourceTree = ""; }; 46 | /* End PBXFileReference section */ 47 | 48 | /* Begin PBXFrameworksBuildPhase section */ 49 | F626355E1AB210E900E1EF4D /* Frameworks */ = { 50 | isa = PBXFrameworksBuildPhase; 51 | buildActionMask = 2147483647; 52 | files = ( 53 | ); 54 | runOnlyForDeploymentPostprocessing = 0; 55 | }; 56 | F62635771AB210E900E1EF4D /* Frameworks */ = { 57 | isa = PBXFrameworksBuildPhase; 58 | buildActionMask = 2147483647; 59 | files = ( 60 | ); 61 | runOnlyForDeploymentPostprocessing = 0; 62 | }; 63 | /* End PBXFrameworksBuildPhase section */ 64 | 65 | /* Begin PBXGroup section */ 66 | F62635581AB210E900E1EF4D = { 67 | isa = PBXGroup; 68 | children = ( 69 | F62635631AB210E900E1EF4D /* RGDynamicOnboard */, 70 | F626357D1AB210E900E1EF4D /* RGDynamicOnboardTests */, 71 | F62635621AB210E900E1EF4D /* Products */, 72 | ); 73 | sourceTree = ""; 74 | }; 75 | F62635621AB210E900E1EF4D /* Products */ = { 76 | isa = PBXGroup; 77 | children = ( 78 | F62635611AB210E900E1EF4D /* RGDynamicOnboard.app */, 79 | F626357A1AB210E900E1EF4D /* RGDynamicOnboardTests.xctest */, 80 | ); 81 | name = Products; 82 | sourceTree = ""; 83 | }; 84 | F62635631AB210E900E1EF4D /* RGDynamicOnboard */ = { 85 | isa = PBXGroup; 86 | children = ( 87 | F626356B1AB210E900E1EF4D /* ViewController.h */, 88 | F626356C1AB210E900E1EF4D /* ViewController.m */, 89 | F626358A1AB213C200E1EF4D /* RGDynamicOnboard.h */, 90 | F626358B1AB213C200E1EF4D /* RGDynamicOnboard.m */, 91 | F626356E1AB210E900E1EF4D /* Main.storyboard */, 92 | F62635711AB210E900E1EF4D /* Images.xcassets */, 93 | F62635641AB210E900E1EF4D /* Supporting Files */, 94 | ); 95 | path = RGDynamicOnboard; 96 | sourceTree = ""; 97 | }; 98 | F62635641AB210E900E1EF4D /* Supporting Files */ = { 99 | isa = PBXGroup; 100 | children = ( 101 | F62635731AB210E900E1EF4D /* LaunchScreen.xib */, 102 | F62635681AB210E900E1EF4D /* AppDelegate.h */, 103 | F62635691AB210E900E1EF4D /* AppDelegate.m */, 104 | F62635651AB210E900E1EF4D /* Info.plist */, 105 | F62635661AB210E900E1EF4D /* main.m */, 106 | ); 107 | name = "Supporting Files"; 108 | sourceTree = ""; 109 | }; 110 | F626357D1AB210E900E1EF4D /* RGDynamicOnboardTests */ = { 111 | isa = PBXGroup; 112 | children = ( 113 | F62635801AB210E900E1EF4D /* RGDynamicOnboardTests.m */, 114 | F626357E1AB210E900E1EF4D /* Supporting Files */, 115 | ); 116 | path = RGDynamicOnboardTests; 117 | sourceTree = ""; 118 | }; 119 | F626357E1AB210E900E1EF4D /* Supporting Files */ = { 120 | isa = PBXGroup; 121 | children = ( 122 | F626357F1AB210E900E1EF4D /* Info.plist */, 123 | ); 124 | name = "Supporting Files"; 125 | sourceTree = ""; 126 | }; 127 | /* End PBXGroup section */ 128 | 129 | /* Begin PBXNativeTarget section */ 130 | F62635601AB210E900E1EF4D /* RGDynamicOnboard */ = { 131 | isa = PBXNativeTarget; 132 | buildConfigurationList = F62635841AB210E900E1EF4D /* Build configuration list for PBXNativeTarget "RGDynamicOnboard" */; 133 | buildPhases = ( 134 | F626355D1AB210E900E1EF4D /* Sources */, 135 | F626355E1AB210E900E1EF4D /* Frameworks */, 136 | F626355F1AB210E900E1EF4D /* Resources */, 137 | ); 138 | buildRules = ( 139 | ); 140 | dependencies = ( 141 | ); 142 | name = RGDynamicOnboard; 143 | productName = RGDynamicOnboard; 144 | productReference = F62635611AB210E900E1EF4D /* RGDynamicOnboard.app */; 145 | productType = "com.apple.product-type.application"; 146 | }; 147 | F62635791AB210E900E1EF4D /* RGDynamicOnboardTests */ = { 148 | isa = PBXNativeTarget; 149 | buildConfigurationList = F62635871AB210E900E1EF4D /* Build configuration list for PBXNativeTarget "RGDynamicOnboardTests" */; 150 | buildPhases = ( 151 | F62635761AB210E900E1EF4D /* Sources */, 152 | F62635771AB210E900E1EF4D /* Frameworks */, 153 | F62635781AB210E900E1EF4D /* Resources */, 154 | ); 155 | buildRules = ( 156 | ); 157 | dependencies = ( 158 | F626357C1AB210E900E1EF4D /* PBXTargetDependency */, 159 | ); 160 | name = RGDynamicOnboardTests; 161 | productName = RGDynamicOnboardTests; 162 | productReference = F626357A1AB210E900E1EF4D /* RGDynamicOnboardTests.xctest */; 163 | productType = "com.apple.product-type.bundle.unit-test"; 164 | }; 165 | /* End PBXNativeTarget section */ 166 | 167 | /* Begin PBXProject section */ 168 | F62635591AB210E900E1EF4D /* Project object */ = { 169 | isa = PBXProject; 170 | attributes = { 171 | LastUpgradeCheck = 0620; 172 | ORGANIZATIONNAME = "Ramon Gilabert"; 173 | TargetAttributes = { 174 | F62635601AB210E900E1EF4D = { 175 | CreatedOnToolsVersion = 6.2; 176 | }; 177 | F62635791AB210E900E1EF4D = { 178 | CreatedOnToolsVersion = 6.2; 179 | TestTargetID = F62635601AB210E900E1EF4D; 180 | }; 181 | }; 182 | }; 183 | buildConfigurationList = F626355C1AB210E900E1EF4D /* Build configuration list for PBXProject "RGDynamicOnboard" */; 184 | compatibilityVersion = "Xcode 3.2"; 185 | developmentRegion = English; 186 | hasScannedForEncodings = 0; 187 | knownRegions = ( 188 | en, 189 | Base, 190 | ); 191 | mainGroup = F62635581AB210E900E1EF4D; 192 | productRefGroup = F62635621AB210E900E1EF4D /* Products */; 193 | projectDirPath = ""; 194 | projectRoot = ""; 195 | targets = ( 196 | F62635601AB210E900E1EF4D /* RGDynamicOnboard */, 197 | F62635791AB210E900E1EF4D /* RGDynamicOnboardTests */, 198 | ); 199 | }; 200 | /* End PBXProject section */ 201 | 202 | /* Begin PBXResourcesBuildPhase section */ 203 | F626355F1AB210E900E1EF4D /* Resources */ = { 204 | isa = PBXResourcesBuildPhase; 205 | buildActionMask = 2147483647; 206 | files = ( 207 | F62635701AB210E900E1EF4D /* Main.storyboard in Resources */, 208 | F62635751AB210E900E1EF4D /* LaunchScreen.xib in Resources */, 209 | F62635721AB210E900E1EF4D /* Images.xcassets in Resources */, 210 | ); 211 | runOnlyForDeploymentPostprocessing = 0; 212 | }; 213 | F62635781AB210E900E1EF4D /* Resources */ = { 214 | isa = PBXResourcesBuildPhase; 215 | buildActionMask = 2147483647; 216 | files = ( 217 | ); 218 | runOnlyForDeploymentPostprocessing = 0; 219 | }; 220 | /* End PBXResourcesBuildPhase section */ 221 | 222 | /* Begin PBXSourcesBuildPhase section */ 223 | F626355D1AB210E900E1EF4D /* Sources */ = { 224 | isa = PBXSourcesBuildPhase; 225 | buildActionMask = 2147483647; 226 | files = ( 227 | F626358C1AB213C200E1EF4D /* RGDynamicOnboard.m in Sources */, 228 | F626356D1AB210E900E1EF4D /* ViewController.m in Sources */, 229 | F626356A1AB210E900E1EF4D /* AppDelegate.m in Sources */, 230 | F62635671AB210E900E1EF4D /* main.m in Sources */, 231 | ); 232 | runOnlyForDeploymentPostprocessing = 0; 233 | }; 234 | F62635761AB210E900E1EF4D /* Sources */ = { 235 | isa = PBXSourcesBuildPhase; 236 | buildActionMask = 2147483647; 237 | files = ( 238 | F62635811AB210E900E1EF4D /* RGDynamicOnboardTests.m in Sources */, 239 | ); 240 | runOnlyForDeploymentPostprocessing = 0; 241 | }; 242 | /* End PBXSourcesBuildPhase section */ 243 | 244 | /* Begin PBXTargetDependency section */ 245 | F626357C1AB210E900E1EF4D /* PBXTargetDependency */ = { 246 | isa = PBXTargetDependency; 247 | target = F62635601AB210E900E1EF4D /* RGDynamicOnboard */; 248 | targetProxy = F626357B1AB210E900E1EF4D /* PBXContainerItemProxy */; 249 | }; 250 | /* End PBXTargetDependency section */ 251 | 252 | /* Begin PBXVariantGroup section */ 253 | F626356E1AB210E900E1EF4D /* Main.storyboard */ = { 254 | isa = PBXVariantGroup; 255 | children = ( 256 | F626356F1AB210E900E1EF4D /* Base */, 257 | ); 258 | name = Main.storyboard; 259 | sourceTree = ""; 260 | }; 261 | F62635731AB210E900E1EF4D /* LaunchScreen.xib */ = { 262 | isa = PBXVariantGroup; 263 | children = ( 264 | F62635741AB210E900E1EF4D /* Base */, 265 | ); 266 | name = LaunchScreen.xib; 267 | sourceTree = ""; 268 | }; 269 | /* End PBXVariantGroup section */ 270 | 271 | /* Begin XCBuildConfiguration section */ 272 | F62635821AB210E900E1EF4D /* 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.2; 307 | MTL_ENABLE_DEBUG_INFO = YES; 308 | ONLY_ACTIVE_ARCH = YES; 309 | SDKROOT = iphoneos; 310 | }; 311 | name = Debug; 312 | }; 313 | F62635831AB210E900E1EF4D /* Release */ = { 314 | isa = XCBuildConfiguration; 315 | buildSettings = { 316 | ALWAYS_SEARCH_USER_PATHS = NO; 317 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 318 | CLANG_CXX_LIBRARY = "libc++"; 319 | CLANG_ENABLE_MODULES = YES; 320 | CLANG_ENABLE_OBJC_ARC = YES; 321 | CLANG_WARN_BOOL_CONVERSION = YES; 322 | CLANG_WARN_CONSTANT_CONVERSION = YES; 323 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 324 | CLANG_WARN_EMPTY_BODY = YES; 325 | CLANG_WARN_ENUM_CONVERSION = YES; 326 | CLANG_WARN_INT_CONVERSION = YES; 327 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 328 | CLANG_WARN_UNREACHABLE_CODE = YES; 329 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 330 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 331 | COPY_PHASE_STRIP = NO; 332 | ENABLE_NS_ASSERTIONS = NO; 333 | ENABLE_STRICT_OBJC_MSGSEND = YES; 334 | GCC_C_LANGUAGE_STANDARD = gnu99; 335 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 336 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 337 | GCC_WARN_UNDECLARED_SELECTOR = YES; 338 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 339 | GCC_WARN_UNUSED_FUNCTION = YES; 340 | GCC_WARN_UNUSED_VARIABLE = YES; 341 | IPHONEOS_DEPLOYMENT_TARGET = 8.2; 342 | MTL_ENABLE_DEBUG_INFO = NO; 343 | SDKROOT = iphoneos; 344 | VALIDATE_PRODUCT = YES; 345 | }; 346 | name = Release; 347 | }; 348 | F62635851AB210E900E1EF4D /* Debug */ = { 349 | isa = XCBuildConfiguration; 350 | buildSettings = { 351 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 352 | INFOPLIST_FILE = RGDynamicOnboard/Info.plist; 353 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 354 | PRODUCT_NAME = "$(TARGET_NAME)"; 355 | }; 356 | name = Debug; 357 | }; 358 | F62635861AB210E900E1EF4D /* Release */ = { 359 | isa = XCBuildConfiguration; 360 | buildSettings = { 361 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 362 | INFOPLIST_FILE = RGDynamicOnboard/Info.plist; 363 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 364 | PRODUCT_NAME = "$(TARGET_NAME)"; 365 | }; 366 | name = Release; 367 | }; 368 | F62635881AB210E900E1EF4D /* Debug */ = { 369 | isa = XCBuildConfiguration; 370 | buildSettings = { 371 | BUNDLE_LOADER = "$(TEST_HOST)"; 372 | FRAMEWORK_SEARCH_PATHS = ( 373 | "$(SDKROOT)/Developer/Library/Frameworks", 374 | "$(inherited)", 375 | ); 376 | GCC_PREPROCESSOR_DEFINITIONS = ( 377 | "DEBUG=1", 378 | "$(inherited)", 379 | ); 380 | INFOPLIST_FILE = RGDynamicOnboardTests/Info.plist; 381 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 382 | PRODUCT_NAME = "$(TARGET_NAME)"; 383 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/RGDynamicOnboard.app/RGDynamicOnboard"; 384 | }; 385 | name = Debug; 386 | }; 387 | F62635891AB210E900E1EF4D /* Release */ = { 388 | isa = XCBuildConfiguration; 389 | buildSettings = { 390 | BUNDLE_LOADER = "$(TEST_HOST)"; 391 | FRAMEWORK_SEARCH_PATHS = ( 392 | "$(SDKROOT)/Developer/Library/Frameworks", 393 | "$(inherited)", 394 | ); 395 | INFOPLIST_FILE = RGDynamicOnboardTests/Info.plist; 396 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 397 | PRODUCT_NAME = "$(TARGET_NAME)"; 398 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/RGDynamicOnboard.app/RGDynamicOnboard"; 399 | }; 400 | name = Release; 401 | }; 402 | /* End XCBuildConfiguration section */ 403 | 404 | /* Begin XCConfigurationList section */ 405 | F626355C1AB210E900E1EF4D /* Build configuration list for PBXProject "RGDynamicOnboard" */ = { 406 | isa = XCConfigurationList; 407 | buildConfigurations = ( 408 | F62635821AB210E900E1EF4D /* Debug */, 409 | F62635831AB210E900E1EF4D /* Release */, 410 | ); 411 | defaultConfigurationIsVisible = 0; 412 | defaultConfigurationName = Release; 413 | }; 414 | F62635841AB210E900E1EF4D /* Build configuration list for PBXNativeTarget "RGDynamicOnboard" */ = { 415 | isa = XCConfigurationList; 416 | buildConfigurations = ( 417 | F62635851AB210E900E1EF4D /* Debug */, 418 | F62635861AB210E900E1EF4D /* Release */, 419 | ); 420 | defaultConfigurationIsVisible = 0; 421 | defaultConfigurationName = Release; 422 | }; 423 | F62635871AB210E900E1EF4D /* Build configuration list for PBXNativeTarget "RGDynamicOnboardTests" */ = { 424 | isa = XCConfigurationList; 425 | buildConfigurations = ( 426 | F62635881AB210E900E1EF4D /* Debug */, 427 | F62635891AB210E900E1EF4D /* Release */, 428 | ); 429 | defaultConfigurationIsVisible = 0; 430 | defaultConfigurationName = Release; 431 | }; 432 | /* End XCConfigurationList section */ 433 | }; 434 | rootObject = F62635591AB210E900E1EF4D /* Project object */; 435 | } 436 | -------------------------------------------------------------------------------- /Examples/RGDynamicOnboard.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Examples/RGDynamicOnboard.xcodeproj/project.xcworkspace/xcshareddata/RGDynamicOnboard.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | 2EA3DE7F-DD9D-487D-BF56-9DF33CD8EB80 9 | IDESourceControlProjectName 10 | RGDynamicOnboard 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | AFD4C142060EF37CB696A6CBA6DF63F6D6657DD9 14 | https://github.com/RamonGilabert/RGDynamicOnboard.git 15 | 16 | IDESourceControlProjectPath 17 | Examples/RGDynamicOnboard.xcodeproj 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | AFD4C142060EF37CB696A6CBA6DF63F6D6657DD9 21 | ../../.. 22 | 23 | IDESourceControlProjectURL 24 | https://github.com/RamonGilabert/RGDynamicOnboard.git 25 | IDESourceControlProjectVersion 26 | 111 27 | IDESourceControlProjectWCCIdentifier 28 | AFD4C142060EF37CB696A6CBA6DF63F6D6657DD9 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | AFD4C142060EF37CB696A6CBA6DF63F6D6657DD9 36 | IDESourceControlWCCName 37 | RGDynamicOnboard 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Examples/RGDynamicOnboard/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface AppDelegate : UIResponder 4 | 5 | @property (strong, nonatomic) UIWindow *window; 6 | 7 | 8 | @end 9 | 10 | -------------------------------------------------------------------------------- /Examples/RGDynamicOnboard/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | @interface AppDelegate () 4 | 5 | @end 6 | 7 | @implementation AppDelegate 8 | 9 | 10 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOption 11 | { 12 | return YES; 13 | } 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Examples/RGDynamicOnboard/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 | -------------------------------------------------------------------------------- /Examples/RGDynamicOnboard/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Examples/RGDynamicOnboard/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 | } -------------------------------------------------------------------------------- /Examples/RGDynamicOnboard/Images.xcassets/background.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "background.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/RGDynamicOnboard/Images.xcassets/background.imageset/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonGilabert/RGDynamicOnboard/abb8ad876da3c997da5fb73e905b152ba667464c/Examples/RGDynamicOnboard/Images.xcassets/background.imageset/background.png -------------------------------------------------------------------------------- /Examples/RGDynamicOnboard/Images.xcassets/firstImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "firstImage.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/RGDynamicOnboard/Images.xcassets/firstImage.imageset/firstImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonGilabert/RGDynamicOnboard/abb8ad876da3c997da5fb73e905b152ba667464c/Examples/RGDynamicOnboard/Images.xcassets/firstImage.imageset/firstImage.png -------------------------------------------------------------------------------- /Examples/RGDynamicOnboard/Images.xcassets/fourthImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "fourthImage.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/RGDynamicOnboard/Images.xcassets/fourthImage.imageset/fourthImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonGilabert/RGDynamicOnboard/abb8ad876da3c997da5fb73e905b152ba667464c/Examples/RGDynamicOnboard/Images.xcassets/fourthImage.imageset/fourthImage.png -------------------------------------------------------------------------------- /Examples/RGDynamicOnboard/Images.xcassets/mountain.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "mountain.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/RGDynamicOnboard/Images.xcassets/mountain.imageset/mountain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonGilabert/RGDynamicOnboard/abb8ad876da3c997da5fb73e905b152ba667464c/Examples/RGDynamicOnboard/Images.xcassets/mountain.imageset/mountain.png -------------------------------------------------------------------------------- /Examples/RGDynamicOnboard/Images.xcassets/secondImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "firstAnimation.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/RGDynamicOnboard/Images.xcassets/secondImage.imageset/firstAnimation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonGilabert/RGDynamicOnboard/abb8ad876da3c997da5fb73e905b152ba667464c/Examples/RGDynamicOnboard/Images.xcassets/secondImage.imageset/firstAnimation.png -------------------------------------------------------------------------------- /Examples/RGDynamicOnboard/Images.xcassets/thirdImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "thirdImage.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/RGDynamicOnboard/Images.xcassets/thirdImage.imageset/thirdImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonGilabert/RGDynamicOnboard/abb8ad876da3c997da5fb73e905b152ba667464c/Examples/RGDynamicOnboard/Images.xcassets/thirdImage.imageset/thirdImage.png -------------------------------------------------------------------------------- /Examples/RGDynamicOnboard/Images.xcassets/welcomeImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "idiom" : "universal", 13 | "scale" : "3x", 14 | "filename" : "welcomeImage.png" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Examples/RGDynamicOnboard/Images.xcassets/welcomeImage.imageset/welcomeImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonGilabert/RGDynamicOnboard/abb8ad876da3c997da5fb73e905b152ba667464c/Examples/RGDynamicOnboard/Images.xcassets/welcomeImage.imageset/welcomeImage.png -------------------------------------------------------------------------------- /Examples/RGDynamicOnboard/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.ramongilabert.$(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 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /Examples/RGDynamicOnboard/RGDynamicOnboard.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface RGDynamicOnboard : UIScrollView 4 | 5 | @property (strong, nonatomic) UIColor *backgroundColorAllScrollView; 6 | @property (strong, nonatomic) UIColor *dismissButtonCornerColor; 7 | @property (strong, nonatomic) UIColor *dismissButtonFontColor; 8 | @property (strong, nonatomic) UIColor *dismissButtonBackgroundColor; 9 | 10 | - (instancetype)initFullscreenWithNumberOfSlides:(int)slides andPageControl:(BOOL)pageControl inView:(UIView *)view; 11 | 12 | - (void)addImage:(UIImage *)image andText:(NSString *)string toPageNumber:(int)page; 13 | - (void)applyAnimationNumber:(int)animation toGoFromPage:(int)page; 14 | 15 | - (void)addStaticImage:(UIImage *)image inPosition:(int)position; 16 | - (void)addStaticImage:(UIImage *)image inFrame:(CGRect)frame; 17 | - (void)addStaticImage:(UIImage *)image inPosition:(int)position fromPage:(int)firstPage toPage:(int)secondPage withAnimationAppearance:(int)animationOption; 18 | 19 | - (void)addText:(NSString *)string inPage:(int)page withFontColor:(UIColor *)color; 20 | - (void)addText:(NSString *)string inPage:(int)page withColor:(UIColor *)color; 21 | 22 | - (void)addBackgroundImage:(UIImage *)image; 23 | - (void)addBackgroundImage:(UIImage *)image withFrame:(CGRect)frame; 24 | - (void)addBackgroundImage:(UIImage *)image withX:(CGFloat)xValue withY:(CGFloat)yValue withAllWidthAndHeight:(CGFloat)height; 25 | 26 | - (void)addEditableStaticImage:(UIImage *)image inPage:(int)page inFrame:(CGRect)initialFrame andGoToFrame:(CGRect)secondFrame toPage:(int)pageToGo; 27 | - (void)image:(UIImage *)image toGoFromPage:(int)page toFrame:(CGRect)lastFrame; 28 | 29 | - (void)addImage:(UIImage *)image inFrame:(CGRect)frame inPage:(int)page withAnimation:(int)animation; 30 | - (void)addString:(NSString *)text inFrame:(CGRect)frame inPage:(int)page withAnimation:(int)animation; 31 | - (void)addString:(NSString *)text andFont:(UIFont *)font inFrame:(CGRect)frame inPage:(int)page withAnimation:(int)animation; 32 | - (void)addString:(NSString *)text andFont:(UIFont *)font andTextColor:(UIColor *)color inFrame:(CGRect)frame inPage:(int)page withAnimation:(int)animation; 33 | 34 | - (void)addBackgroundColor:(UIColor *)color inPage:(int)page; 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /Examples/RGDynamicOnboard/RGDynamicOnboard.m: -------------------------------------------------------------------------------- 1 | #import "RGDynamicOnboard.h" 2 | 3 | @interface RGDynamicOnboard () 4 | 5 | @property (strong, nonatomic) UIPageControl *pageControl; 6 | @property (strong, nonatomic) UIWindow *mainView; 7 | @property (strong, nonatomic) UIColor *colorSlide; 8 | @property (strong, nonatomic) UIView *viewMain; 9 | @property (strong, nonatomic) UIButton *buttonDismiss; 10 | @property (strong, nonatomic) UIImageView *staticImageView; 11 | @property (strong, nonatomic) UIImageView *staticImageViewSecond; 12 | @property (strong, nonatomic) UIImageView *backgroundImageView; 13 | @property (strong, nonatomic) UIImageView *imageViewThatMoves; 14 | @property (strong, nonatomic) NSMutableArray *arrayWithSlides; 15 | @property (strong, nonatomic) NSMutableArray *arrayOfAnimations; 16 | @property (strong, nonatomic) NSMutableArray *arrayWithImagesAnimation; 17 | @property (strong, nonatomic) NSMutableArray *arrayWithImages; 18 | @property (strong, nonatomic) NSMutableArray *arrayWithImagesPages; 19 | @property (strong, nonatomic) NSMutableArray *arrayOfFrames; 20 | @property (strong, nonatomic) NSMutableArray *arrayOfFramesX; 21 | @property (weak, nonatomic) NSNumber *firstPageFirst; 22 | @property (weak, nonatomic) NSNumber *firstPageSecond; 23 | @property (weak, nonatomic) NSNumber *secondPageFirst; 24 | @property (weak, nonatomic) NSNumber *secondPageSecond; 25 | @property CGRect frameToGo; 26 | @property CGRect initialFrame; 27 | @property CGRect initialFrameOnceAnimationDone; 28 | @property CGRect finalFrameOnceAnimationDone; 29 | @property CGFloat deviceWidth; 30 | @property CGFloat deviceHeight; 31 | @property CGFloat scrollOffset; 32 | @property int numberOfPages; 33 | @property int animationStaticImage; 34 | @property int animationStaticImageSecond; 35 | @property int pageToPerformFirstAnimation; 36 | @property int pageToPerformSecondAnimation; 37 | @property int pageToPerformThirdAnimation; 38 | 39 | @end 40 | 41 | @implementation RGDynamicOnboard 42 | 43 | - (instancetype)initFullscreenWithNumberOfSlides:(int)slides andPageControl:(BOOL)pageControl inView:(UIView *)view 44 | { 45 | self = [RGDynamicOnboard new]; 46 | 47 | self.pageToPerformFirstAnimation = 100; 48 | self.pageToPerformSecondAnimation = 100; 49 | self.pageToPerformThirdAnimation = 100; 50 | 51 | self.viewMain = [UIView new]; 52 | self.viewMain = view; 53 | 54 | self.deviceWidth = [UIScreen mainScreen].bounds.size.width; 55 | self.deviceHeight = [UIScreen mainScreen].bounds.size.height; 56 | 57 | self.arrayWithSlides = [NSMutableArray new]; 58 | self.arrayOfAnimations = [NSMutableArray new]; 59 | self.arrayWithImages = [NSMutableArray new]; 60 | self.arrayWithImagesAnimation = [NSMutableArray new]; 61 | self.arrayWithImagesPages = [NSMutableArray new]; 62 | self.arrayOfFrames = [NSMutableArray new]; 63 | self.arrayOfFramesX = [NSMutableArray new]; 64 | 65 | for (int i = 0; i < slides; i++) { 66 | [self.arrayWithSlides addObject:[NSNull null]]; 67 | [self.arrayOfAnimations addObject:[NSNull null]]; 68 | } 69 | 70 | self.mainView = [[[UIApplication sharedApplication] delegate] window]; 71 | 72 | self.numberOfPages = slides; 73 | 74 | self.frame = CGRectMake(0, 0, self.deviceWidth, self.deviceHeight); 75 | self.pagingEnabled = YES; 76 | self.contentSize = CGSizeMake(self.deviceWidth * slides, self.deviceHeight); 77 | self.showsHorizontalScrollIndicator = NO; 78 | self.showsVerticalScrollIndicator = NO; 79 | self.scrollsToTop = NO; 80 | self.delegate = self; 81 | 82 | if (pageControl) { 83 | self.pageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(0, self.deviceHeight - 75, self.deviceWidth, 20)]; 84 | self.pageControl.numberOfPages = slides; 85 | [self getPageControlColorFromBackgroundColor:[UIColor darkGrayColor]]; 86 | [self.viewMain addSubview:self.pageControl]; 87 | } 88 | 89 | [self.viewMain addSubview: self]; 90 | 91 | [self loadScrollViewWithPage:0]; 92 | [self loadScrollViewWithPage:1]; 93 | [self loadScrollViewWithPage:2]; 94 | [self loadScrollViewWithPage:3]; 95 | 96 | return self; 97 | } 98 | 99 | - (void)addBackgroundColor:(UIColor *)color inPage:(int)page 100 | { 101 | if (page >= self.numberOfPages) return; 102 | 103 | UIView *view = [self.arrayWithSlides objectAtIndex:page]; 104 | 105 | if ((NSNull *)view == [NSNull null]) { 106 | view = [UIView new]; 107 | [self.arrayWithSlides replaceObjectAtIndex:page withObject:view]; 108 | } 109 | 110 | view.backgroundColor = color; 111 | } 112 | 113 | - (void)setBackgroundColorAllScrollView:(UIColor *)backgroundColorAllScrollView 114 | { 115 | self.viewMain.backgroundColor = backgroundColorAllScrollView; 116 | 117 | if (self.pageControl) { 118 | CGFloat hueColor; 119 | CGFloat saturationColor; 120 | CGFloat brightnessColor; 121 | CGFloat alphaColor; 122 | 123 | [backgroundColorAllScrollView getHue:&hueColor saturation:&saturationColor brightness:&brightnessColor alpha:&alphaColor]; 124 | 125 | self.pageControl.currentPageIndicatorTintColor = [UIColor colorWithHue:hueColor saturation:saturationColor brightness:brightnessColor-0.4 alpha:alphaColor]; 126 | self.pageControl.pageIndicatorTintColor = [UIColor colorWithHue:hueColor saturation:saturationColor brightness:brightnessColor-0.2 alpha:alphaColor]; 127 | } 128 | } 129 | 130 | - (void)setDismissButtonCornerColor:(UIColor *)dismissButtonCornerColor 131 | { 132 | self.buttonDismiss.layer.borderColor = dismissButtonCornerColor.CGColor; 133 | } 134 | 135 | - (void)setDismissButtonFontColor:(UIColor *)dismissButtonFontColor 136 | { 137 | [self.buttonDismiss setTitleColor:dismissButtonFontColor forState:UIControlStateNormal]; 138 | } 139 | 140 | - (void)setDismissButtonBackgroundColor:(UIColor *)dismissButtonBackgroundColor 141 | { 142 | self.buttonDismiss.backgroundColor = dismissButtonBackgroundColor; 143 | } 144 | 145 | - (void)addImage:(UIImage *)image inFrame:(CGRect)frame inPage:(int)page withAnimation:(int)animation 146 | { 147 | if (page >= self.numberOfPages) return; 148 | 149 | UIView *view = [self.arrayWithSlides objectAtIndex:page]; 150 | 151 | if ((NSNull *)view == [NSNull null]) { 152 | view = [UIView new]; 153 | [self.arrayWithSlides replaceObjectAtIndex:page withObject:view]; 154 | } 155 | 156 | UIImageView *imageView = [[UIImageView alloc] initWithFrame:frame]; 157 | imageView.contentMode = UIViewContentModeScaleAspectFill; 158 | imageView.image = image; 159 | 160 | [self.arrayWithImagesPages addObject:[NSNumber numberWithInt:page]]; 161 | [self.arrayWithImagesAnimation addObject:[NSNumber numberWithInt:animation]]; 162 | [self.arrayWithImages addObject:imageView]; 163 | [self.arrayOfFrames addObject:[NSNumber numberWithFloat:imageView.frame.origin.y]]; 164 | [self.arrayOfFramesX addObject:[NSNumber numberWithFloat:imageView.frame.origin.x]]; 165 | 166 | [view addSubview:imageView]; 167 | } 168 | 169 | - (void)addString:(NSString *)text inFrame:(CGRect)frame inPage:(int)page withAnimation:(int)animation 170 | { 171 | if (page >= self.numberOfPages) return; 172 | 173 | UIView *view = [self.arrayWithSlides objectAtIndex:page]; 174 | 175 | if ((NSNull *)view == [NSNull null]) { 176 | view = [UIView new]; 177 | [self.arrayWithSlides replaceObjectAtIndex:page withObject:view]; 178 | } 179 | 180 | UILabel *label = [[UILabel alloc] initWithFrame:frame]; 181 | label.text = text; 182 | label.numberOfLines = 10; 183 | label.textColor = [UIColor darkGrayColor]; 184 | label.textAlignment = NSTextAlignmentCenter; 185 | label.font = [UIFont fontWithName:@"Helvetica" size:22]; 186 | 187 | [view addSubview:label]; 188 | } 189 | 190 | - (void)addString:(NSString *)text andFont:(UIFont *)font inFrame:(CGRect)frame inPage:(int)page withAnimation:(int)animation 191 | { 192 | if (page >= self.numberOfPages) return; 193 | 194 | UIView *view = [self.arrayWithSlides objectAtIndex:page]; 195 | 196 | if ((NSNull *)view == [NSNull null]) { 197 | view = [UIView new]; 198 | [self.arrayWithSlides replaceObjectAtIndex:page withObject:view]; 199 | } 200 | 201 | UILabel *label = [[UILabel alloc] initWithFrame:frame]; 202 | label.text = text; 203 | label.numberOfLines = 10; 204 | label.textColor = [UIColor darkGrayColor]; 205 | label.textAlignment = NSTextAlignmentCenter; 206 | label.font = font; 207 | 208 | [view addSubview:label]; 209 | } 210 | 211 | - (void)addString:(NSString *)text andFont:(UIFont *)font andTextColor:(UIColor *)color inFrame:(CGRect)frame inPage:(int)page withAnimation:(int)animation 212 | { 213 | if (page >= self.numberOfPages) return; 214 | 215 | UIView *view = [self.arrayWithSlides objectAtIndex:page]; 216 | 217 | if ((NSNull *)view == [NSNull null]) { 218 | view = [UIView new]; 219 | [self.arrayWithSlides replaceObjectAtIndex:page withObject:view]; 220 | } 221 | 222 | UILabel *label = [[UILabel alloc] initWithFrame:frame]; 223 | label.text = text; 224 | label.numberOfLines = 10; 225 | label.textColor = color; 226 | label.textAlignment = NSTextAlignmentCenter; 227 | label.font = font; 228 | 229 | [view addSubview:label]; 230 | } 231 | 232 | - (void)addEditableStaticImage:(UIImage *)image inPage:(int)page inFrame:(CGRect)initialFrame andGoToFrame:(CGRect)secondFrame toPage:(int)pageToGo 233 | { 234 | if (image) { 235 | self.imageViewThatMoves = [[UIImageView alloc] initWithFrame:initialFrame]; 236 | self.imageViewThatMoves.contentMode = UIViewContentModeScaleAspectFit; 237 | self.imageViewThatMoves.image = image; 238 | self.frameToGo = secondFrame; 239 | self.pageToPerformFirstAnimation = page; 240 | self.pageToPerformSecondAnimation = pageToGo - 1; 241 | self.initialFrame = initialFrame; 242 | 243 | if (page == 0) { 244 | [self.viewMain addSubview:self.imageViewThatMoves]; 245 | } 246 | } 247 | } 248 | 249 | - (void)image:(UIImage *)image toGoFromPage:(int)page toFrame:(CGRect)lastFrame 250 | { 251 | if ([self.imageViewThatMoves.image isEqual:image]) { 252 | self.pageToPerformThirdAnimation = page; 253 | self.finalFrameOnceAnimationDone = lastFrame; 254 | } 255 | } 256 | 257 | - (void)addBackgroundImage:(UIImage *)image 258 | { 259 | if (image) { 260 | self.backgroundImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width*self.numberOfPages, self.deviceHeight)]; 261 | self.backgroundImageView.contentMode = UIViewContentModeScaleAspectFill; 262 | self.backgroundImageView.image = image; 263 | [self insertSubview:self.backgroundImageView atIndex:0]; 264 | 265 | self.pageControl.currentPageIndicatorTintColor = [UIColor whiteColor]; 266 | self.pageControl.pageIndicatorTintColor = [UIColor lightGrayColor]; 267 | [self.viewMain bringSubviewToFront:self.pageControl]; 268 | 269 | self.buttonDismiss.layer.borderColor = [UIColor whiteColor].CGColor; 270 | [self.buttonDismiss setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; 271 | } 272 | } 273 | 274 | - (void)addBackgroundImage:(UIImage *)image withFrame:(CGRect)frame 275 | { 276 | if (image) { 277 | self.backgroundImageView = [[UIImageView alloc] initWithFrame:frame]; 278 | self.backgroundImageView.contentMode = UIViewContentModeScaleAspectFill; 279 | self.backgroundImageView.image = image; 280 | [self insertSubview:self.backgroundImageView atIndex:0]; 281 | 282 | if (frame.origin.y > self.deviceHeight/2 || frame.size.height >= self.deviceHeight) { 283 | self.pageControl.currentPageIndicatorTintColor = [UIColor whiteColor]; 284 | self.pageControl.pageIndicatorTintColor = [UIColor lightGrayColor]; 285 | self.buttonDismiss.layer.borderColor = [UIColor whiteColor].CGColor; 286 | [self.buttonDismiss setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; 287 | } 288 | } 289 | } 290 | 291 | - (void)addBackgroundImage:(UIImage *)image withX:(CGFloat)xValue withY:(CGFloat)yValue withAllWidthAndHeight:(CGFloat)height 292 | { 293 | if (image) { 294 | self.backgroundImageView = [[UIImageView alloc] initWithFrame:CGRectMake(xValue, yValue, self.frame.size.width*self.numberOfPages, height)]; 295 | self.backgroundImageView.contentMode = UIViewContentModeScaleAspectFill; 296 | self.backgroundImageView.image = image; 297 | [self insertSubview:self.backgroundImageView atIndex:0]; 298 | 299 | if (yValue > self.deviceHeight/2 || height >= self.deviceHeight) { 300 | self.pageControl.currentPageIndicatorTintColor = [UIColor whiteColor]; 301 | self.pageControl.pageIndicatorTintColor = [UIColor lightGrayColor]; 302 | 303 | self.buttonDismiss.layer.borderColor = [UIColor whiteColor].CGColor; 304 | [self.buttonDismiss setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; 305 | } 306 | } 307 | } 308 | 309 | - (void)addStaticImage:(UIImage *)image inPosition:(int)position 310 | { 311 | self.staticImageView = [UIImageView new]; 312 | 313 | if (position == 0) { 314 | self.staticImageView.frame = CGRectMake((self.deviceWidth - self.deviceWidth/1.7)/2, (self.deviceHeight - self.deviceHeight/3)/2 - 25, self.deviceWidth/1.7, self.deviceHeight/3); 315 | } else if (position == 1) { 316 | self.staticImageView.frame = CGRectMake((self.deviceWidth - self.deviceWidth/1.7)/2 + 60, (self.deviceHeight - self.deviceHeight/3)/2 - 100, self.deviceWidth/1.7, self.deviceHeight/3); 317 | } else if (position == 2) { 318 | self.staticImageView.frame = CGRectMake((self.deviceWidth - self.deviceWidth/1.7)/2 - 60, (self.deviceHeight - self.deviceHeight/3)/2 - 100, self.deviceWidth/1.7, self.deviceHeight/3); 319 | } else { 320 | self.staticImageView.frame = CGRectMake((self.deviceWidth - self.deviceWidth/1.7)/2, (self.deviceHeight - self.deviceHeight/3)/2 - 100, self.deviceWidth/1.7, self.deviceHeight/3); 321 | } 322 | 323 | self.staticImageView.contentMode = UIViewContentModeScaleAspectFill; 324 | self.staticImageView.image = image; 325 | 326 | [self.viewMain addSubview:self.staticImageView]; 327 | } 328 | 329 | - (void)addStaticImage:(UIImage *)image inPosition:(int)position fromPage:(int)firstPage toPage:(int)secondPage withAnimationAppearance:(int)animationOption 330 | { 331 | if (!self.firstPageFirst) { 332 | self.animationStaticImage = animationOption; 333 | 334 | self.firstPageFirst = [NSNumber numberWithInt:firstPage]; 335 | self.firstPageSecond = [NSNumber numberWithInt:secondPage]; 336 | 337 | self.staticImageView = [UIImageView new]; 338 | 339 | if (position == 0) { 340 | self.staticImageView.frame = CGRectMake((self.deviceWidth - self.deviceWidth/1.7)/2, (self.deviceHeight - self.deviceHeight/3)/2 - 25, self.deviceWidth/1.7, self.deviceHeight/3); 341 | } else if (position == 1) { 342 | self.staticImageView.frame = CGRectMake((self.deviceWidth - self.deviceWidth/1.7)/2 + 60, (self.deviceHeight - self.deviceHeight/3)/2 - 100, self.deviceWidth/1.7, self.deviceHeight/3); 343 | } else if (position == 2) { 344 | self.staticImageView.frame = CGRectMake((self.deviceWidth - self.deviceWidth/1.7)/2 - 60, (self.deviceHeight - self.deviceHeight/3)/2 - 100, self.deviceWidth/1.7, self.deviceHeight/3); 345 | } else { 346 | self.staticImageView.frame = CGRectMake((self.deviceWidth - self.deviceWidth/1.7)/2, (self.deviceHeight - self.deviceHeight/3)/2 - 100, self.deviceWidth/1.7, self.deviceHeight/3); 347 | } 348 | 349 | self.staticImageView.contentMode = UIViewContentModeScaleAspectFill; 350 | self.staticImageView.image = image; 351 | 352 | } else { 353 | self.animationStaticImageSecond = animationOption; 354 | 355 | self.secondPageFirst = [NSNumber numberWithInt:firstPage]; 356 | self.secondPageSecond = [NSNumber numberWithInt:secondPage]; 357 | 358 | self.staticImageViewSecond = [UIImageView new]; 359 | 360 | if (position == 0) { 361 | self.staticImageViewSecond.frame = CGRectMake((self.deviceWidth - self.deviceWidth/1.7)/2, (self.deviceHeight - self.deviceHeight/3)/2 - 25, self.deviceWidth/1.7, self.deviceHeight/3); 362 | } else if (position == 1) { 363 | self.staticImageViewSecond.frame = CGRectMake((self.deviceWidth - self.deviceWidth/1.7)/2 + 60, (self.deviceHeight - self.deviceHeight/3)/2 - 100, self.deviceWidth/1.7, self.deviceHeight/3); 364 | } else if (position == 2) { 365 | self.staticImageViewSecond.frame = CGRectMake((self.deviceWidth - self.deviceWidth/1.7)/2 - 60, (self.deviceHeight - self.deviceHeight/3)/2 - 100, self.deviceWidth/1.7, self.deviceHeight/3); 366 | } else { 367 | self.staticImageViewSecond.frame = CGRectMake((self.deviceWidth - self.deviceWidth/1.7)/2, (self.deviceHeight - self.deviceHeight/3)/2 - 100, self.deviceWidth/1.7, self.deviceHeight/3); 368 | } 369 | 370 | self.staticImageViewSecond.contentMode = UIViewContentModeScaleAspectFill; 371 | self.staticImageViewSecond.image = image; 372 | } 373 | 374 | [self.viewMain addSubview:self.staticImageView]; 375 | } 376 | 377 | - (void)addStaticImage:(UIImage *)image inFrame:(CGRect)frame 378 | { 379 | if (&frame && image) { 380 | self.staticImageView = [[UIImageView alloc] initWithFrame:frame]; 381 | self.staticImageView.contentMode = UIViewContentModeScaleAspectFill; 382 | self.staticImageView.image = image; 383 | [self.viewMain addSubview:self.staticImageView]; 384 | } 385 | } 386 | 387 | - (void)addText:(NSString *)string inPage:(int)page withColor:(UIColor *)color 388 | { 389 | UIView *view = [self.arrayWithSlides objectAtIndex:page]; 390 | UILabel *labelOfText = [[UILabel alloc] initWithFrame:CGRectMake(25, self.deviceHeight - self.deviceHeight/6, self.deviceWidth - 50, 200)]; 391 | labelOfText.numberOfLines = 10; 392 | labelOfText.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:22]; 393 | labelOfText.textColor = color; 394 | labelOfText.textAlignment = NSTextAlignmentCenter; 395 | labelOfText.text = string; 396 | [labelOfText sizeToFit]; 397 | CGRect rectOfLabel = labelOfText.frame; 398 | labelOfText.frame = CGRectMake((self.deviceWidth - rectOfLabel.size.width)/2, self.deviceHeight - rectOfLabel.size.height - self.deviceHeight/4, rectOfLabel.size.width, rectOfLabel.size.height); 399 | [view addSubview:labelOfText]; 400 | } 401 | 402 | - (void)addText:(NSString *)string inPage:(int)page 403 | { 404 | UIView *view = [self.arrayWithSlides objectAtIndex:page]; 405 | UILabel *labelOfText = [[UILabel alloc] initWithFrame:CGRectMake(25, self.deviceHeight - self.deviceHeight/6, self.deviceWidth - 50, 200)]; 406 | labelOfText.numberOfLines = 10; 407 | labelOfText.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:22]; 408 | labelOfText.textAlignment = NSTextAlignmentCenter; 409 | labelOfText.text = string; 410 | [labelOfText sizeToFit]; 411 | CGRect rectOfLabel = labelOfText.frame; 412 | labelOfText.frame = CGRectMake((self.deviceWidth - rectOfLabel.size.width)/2, self.deviceHeight - rectOfLabel.size.height - self.deviceHeight/4, rectOfLabel.size.width, rectOfLabel.size.height); 413 | [view addSubview:labelOfText]; 414 | } 415 | 416 | - (void)addImage:(UIImage *)image andText:(NSString *)string toPageNumber:(int)page 417 | { 418 | [self loadScrollViewWithPage:page]; 419 | 420 | UIView *view = [self.arrayWithSlides objectAtIndex:page]; 421 | 422 | UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake((self.deviceWidth - (self.deviceWidth/3))/2, self.deviceHeight/2 - self.deviceHeight/3 + 40, self.deviceWidth/3, self.deviceHeight/4)]; 423 | imageView.image = image; 424 | imageView.contentMode = UIViewContentModeScaleAspectFill; 425 | [view addSubview:imageView]; 426 | 427 | UILabel *labelWithText = [[UILabel alloc] initWithFrame:CGRectMake((self.deviceWidth - (self.deviceWidth - 150))/2, self.deviceHeight/2 + 100, self.deviceWidth - 80, 200)]; 428 | labelWithText.textAlignment = NSTextAlignmentCenter; 429 | labelWithText.numberOfLines = 10; 430 | labelWithText.text = string; 431 | labelWithText.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:22]; 432 | [labelWithText sizeToFit]; 433 | labelWithText.frame = CGRectMake((self.deviceWidth - labelWithText.frame.size.width)/2, self.deviceHeight/2 + 75, labelWithText.frame.size.width, labelWithText.frame.size.height); 434 | [view addSubview:labelWithText]; 435 | 436 | [self.arrayWithSlides replaceObjectAtIndex:page withObject:view]; 437 | } 438 | 439 | - (void)onDismissButtonPressed 440 | { 441 | [UIView animateWithDuration:0.5 animations:^{ 442 | if (self.staticImageView) { 443 | self.staticImageView.transform = CGAffineTransformMakeScale(3, 3); 444 | self.staticImageView.alpha = 0; 445 | } 446 | 447 | if (self.staticImageViewSecond) { 448 | self.staticImageViewSecond.transform = CGAffineTransformMakeScale(3, 3); 449 | self.staticImageViewSecond.alpha = 0; 450 | } 451 | 452 | if (self.imageViewThatMoves) { 453 | self.imageViewThatMoves.transform = CGAffineTransformMakeScale(3, 3); 454 | self.imageViewThatMoves.alpha = 0; 455 | } 456 | 457 | self.transform = CGAffineTransformMakeScale(3, 3); 458 | self.alpha = 0; 459 | } completion:^(BOOL finished) { 460 | if (self.staticImageView) { 461 | [self.staticImageView removeFromSuperview]; 462 | } 463 | 464 | if (self.staticImageViewSecond) { 465 | [self.staticImageViewSecond removeFromSuperview]; 466 | } 467 | 468 | if (self.imageViewThatMoves) { 469 | [self.imageViewThatMoves removeFromSuperview]; 470 | } 471 | 472 | [self removeFromSuperview]; 473 | }]; 474 | } 475 | 476 | - (void)applyAnimationNumber:(int)animation toGoFromPage:(int)page 477 | { 478 | [self.arrayOfAnimations replaceObjectAtIndex:page withObject:[NSNumber numberWithInt:animation]]; 479 | } 480 | 481 | - (void)loadScrollViewWithPage:(NSUInteger)page 482 | { 483 | if (page >= self.numberOfPages) return; 484 | 485 | UIView *view = [self.arrayWithSlides objectAtIndex:page]; 486 | 487 | if ((NSNull *)view == [NSNull null]) { 488 | view = [UIView new]; 489 | [self.arrayWithSlides replaceObjectAtIndex:page withObject:view]; 490 | } 491 | 492 | if (view.superview == nil) 493 | { 494 | CGRect frame = self.frame; 495 | frame.origin.x = CGRectGetWidth(frame) * page; 496 | frame.origin.y = 0; 497 | view.frame = frame; 498 | 499 | [self addSubview:view]; 500 | } 501 | 502 | if ((int)(page + 1) == (int)self.arrayWithSlides.count) { 503 | if (!self.buttonDismiss) { 504 | self.buttonDismiss = [[UIButton alloc] initWithFrame:CGRectMake(50, self.deviceHeight - self.deviceHeight/5.5, self.deviceWidth - 100, 65)]; 505 | self.buttonDismiss.layer.cornerRadius = 7.5; 506 | self.buttonDismiss.layer.borderColor = [UIColor darkGrayColor].CGColor; 507 | self.buttonDismiss.layer.borderWidth = 2; 508 | self.buttonDismiss.titleLabel.font = [UIFont fontWithName:@"Avenir" size:26]; 509 | [self.buttonDismiss setTitle:@"Start this journey" forState:UIControlStateNormal]; 510 | [self.buttonDismiss setTitleColor:[UIColor darkGrayColor] forState:UIControlStateNormal]; 511 | [self.buttonDismiss addTarget:self action:@selector(onDismissButtonPressed) forControlEvents:UIControlEventTouchUpInside]; 512 | self.buttonDismiss.alpha = 0; 513 | [view addSubview:self.buttonDismiss]; 514 | } 515 | } 516 | } 517 | 518 | #pragma mark - Delegate methods 519 | 520 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView 521 | { 522 | CGFloat pageWidth = CGRectGetWidth(self.frame); 523 | NSUInteger page = floor((self.contentOffset.x - pageWidth) / pageWidth) + 1; 524 | 525 | CGFloat realLocation = scrollView.contentOffset.x - self.deviceWidth * page; 526 | 527 | self.scrollOffset = realLocation; 528 | 529 | if ((int)page < 0) return; 530 | 531 | UIView *view = [self.arrayWithSlides objectAtIndex:page]; 532 | UIView *viewSecond = [UIView new]; 533 | 534 | if (page + 1 < self.arrayWithSlides.count) { 535 | viewSecond = [self.arrayWithSlides objectAtIndex:(page + 1)]; 536 | } 537 | 538 | UIImageView *imageViewToAnimate = [UIImageView new]; 539 | UILabel *labelToAnimate = [UILabel new]; 540 | UIImageView *imageViewToAnimateFollowingPage = [UIImageView new]; 541 | UILabel *labelToAnimateFollowingPage = [UILabel new]; 542 | 543 | if (view.subviews.count > 0) { 544 | for (UIView *viewWeTake in view.subviews) { 545 | if ([viewWeTake isKindOfClass:[UILabel class]]) { 546 | labelToAnimate = (UILabel *)viewWeTake; 547 | } else if ([viewWeTake isKindOfClass:[UIImageView class]]) { 548 | imageViewToAnimate = (UIImageView *)viewWeTake; 549 | } 550 | } 551 | } 552 | 553 | if (![viewSecond isKindOfClass:[NSNull class]]) { 554 | for (UIView *viewWeTake in viewSecond.subviews) { 555 | if ([viewWeTake isKindOfClass:[UILabel class]]) { 556 | labelToAnimateFollowingPage = (UILabel *)viewWeTake; 557 | } else if ([viewWeTake isKindOfClass:[UIImageView class]]) { 558 | imageViewToAnimateFollowingPage = (UIImageView *)viewWeTake; 559 | } 560 | } 561 | } 562 | 563 | for (NSNumber *number in self.arrayWithImagesPages) { 564 | if ([number intValue] == page) { 565 | int indexOfPage = (int)[self.arrayWithImagesPages indexOfObject:number]; 566 | UIImageView *imageView = self.arrayWithImages[indexOfPage]; 567 | 568 | if ([self.arrayWithImagesAnimation[indexOfPage] isEqual:[NSNumber numberWithInt:0]]) { 569 | imageView.frame = CGRectMake([self.arrayOfFramesX[indexOfPage] floatValue] + self.scrollOffset/1.5, [self.arrayOfFrames[indexOfPage] floatValue] - self.scrollOffset*1.5, imageView.frame.size.width, imageView.frame.size.height); 570 | } 571 | } else if ([number intValue] == page + 1) { 572 | int indexOfPage = (int)[self.arrayWithImagesPages indexOfObject:number]; 573 | UIImageView *imageView = self.arrayWithImages[indexOfPage]; 574 | 575 | if ([self.arrayWithImagesAnimation[indexOfPage] isEqual:[NSNumber numberWithInt:0]]) { 576 | imageView.frame = CGRectMake([self.arrayOfFramesX[indexOfPage] floatValue] - (self.frame.size.width - self.scrollOffset)/1.5, [self.arrayOfFrames[indexOfPage] floatValue] - (self.frame.size.width - self.scrollOffset)*1.5, imageView.frame.size.width, imageView.frame.size.height); 577 | } 578 | } 579 | } 580 | 581 | if (self.pageToPerformSecondAnimation == (int)page) { 582 | CGFloat floatValue = (self.frameToGo.origin.y - self.initialFrame.origin.y)/self.frame.size.width; 583 | CGFloat floatValueX = (self.frameToGo.origin.x - self.initialFrame.origin.x)/self.frame.size.width; 584 | CGFloat floatValueHeight = (self.frameToGo.size.height - self.initialFrame.size.height)/self.frame.size.width; 585 | CGFloat floatValueWidth = (self.frameToGo.size.width - self.initialFrame.size.width)/self.frame.size.width; 586 | 587 | self.imageViewThatMoves.frame = CGRectMake(self.initialFrame.origin.x + self.scrollOffset*floatValueX, self.initialFrame.origin.y + self.scrollOffset*floatValue, self.initialFrame.size.width + self.scrollOffset*floatValueWidth, self.initialFrame.size.height + self.scrollOffset*floatValueHeight); 588 | } 589 | 590 | if (self.pageToPerformThirdAnimation == (int)page) { 591 | CGFloat floatValue = (self.frameToGo.origin.y - self.finalFrameOnceAnimationDone.origin.y)/self.frame.size.width; 592 | CGFloat floatValueX = (self.frameToGo.origin.x - self.finalFrameOnceAnimationDone.origin.x)/self.frame.size.width; 593 | CGFloat floatValueHeight = (self.frameToGo.size.height - self.finalFrameOnceAnimationDone.size.height)/self.frame.size.width; 594 | CGFloat floatValueWidth = (self.frameToGo.size.width - self.finalFrameOnceAnimationDone.size.width)/self.frame.size.width; 595 | 596 | self.imageViewThatMoves.frame = CGRectMake(self.frameToGo.origin.x - self.scrollOffset*floatValueX, self.frameToGo.origin.y - self.scrollOffset*floatValue, self.frameToGo.size.width - self.scrollOffset*floatValueWidth, self.frameToGo.size.height - self.scrollOffset*floatValueHeight); 597 | } 598 | 599 | if (![self.arrayOfAnimations[page] isKindOfClass:[NSNull class]]) { 600 | if ([self.arrayOfAnimations[page] intValue] == 0) { 601 | imageViewToAnimate.frame = CGRectMake((self.deviceWidth - (self.deviceWidth/3))/2 + self.scrollOffset/1.5, self.deviceHeight/2 - self.deviceHeight/3 + 40 - realLocation, imageViewToAnimate.frame.size.width, imageViewToAnimate.frame.size.height); 602 | 603 | if (imageViewToAnimateFollowingPage && (self.arrayOfAnimations.count >= page + 2)) { 604 | if (![self.arrayOfAnimations[page + 1] isKindOfClass:[NSNull class]]) { 605 | if ([self.arrayOfAnimations[page + 1] intValue] == 0) { 606 | if (self.scrollOffset + 20 > self.frame.size.width) { 607 | imageViewToAnimateFollowingPage.frame = CGRectMake(imageViewToAnimateFollowingPage.frame.origin.x, self.deviceHeight/2 - self.deviceHeight/3 + 40, imageViewToAnimateFollowingPage.frame.size.width, imageViewToAnimateFollowingPage.frame.size.height); 608 | } else { 609 | imageViewToAnimateFollowingPage.frame = CGRectMake(imageViewToAnimateFollowingPage.frame.origin.x, - self.frame.size.width + self.scrollOffset * 1.5, imageViewToAnimateFollowingPage.frame.size.width, imageViewToAnimateFollowingPage.frame.size.height); 610 | } 611 | } else if ([self.arrayOfAnimations[page + 1] intValue] == 1) { 612 | if (self.scrollOffset > self.frame.size.width) { 613 | imageViewToAnimateFollowingPage.transform = CGAffineTransformMakeScale(1 - (realLocation/self.frame.size.width), 1 - (realLocation/self.frame.size.width)); 614 | imageViewToAnimateFollowingPage.frame = CGRectMake((self.deviceWidth - (self.deviceWidth/3))/2 + realLocation/1.5, imageViewToAnimateFollowingPage.frame.origin.y, imageViewToAnimateFollowingPage.frame.size.width, imageViewToAnimateFollowingPage.frame.size.height); 615 | } else { 616 | imageViewToAnimateFollowingPage.transform = CGAffineTransformMakeScale(realLocation/self.frame.size.width, realLocation/self.frame.size.width); 617 | imageViewToAnimateFollowingPage.frame = CGRectMake((self.deviceWidth - (self.deviceWidth/3))/2 - realLocation/1.5, imageViewToAnimateFollowingPage.frame.origin.y, imageViewToAnimateFollowingPage.frame.size.width, imageViewToAnimateFollowingPage.frame.size.height); 618 | } 619 | } 620 | } 621 | } 622 | } else if ([self.arrayOfAnimations[page] intValue] == 1) { 623 | if (self.scrollOffset > self.frame.size.width) { 624 | imageViewToAnimate.transform = CGAffineTransformMakeScale(realLocation/self.frame.size.width, realLocation/self.frame.size.width); 625 | imageViewToAnimate.frame = CGRectMake((self.deviceWidth - (self.deviceWidth/3))/2 + realLocation/1.5, imageViewToAnimate.frame.origin.y, imageViewToAnimate.frame.size.width, imageViewToAnimate.frame.size.height); 626 | 627 | imageViewToAnimateFollowingPage.transform = CGAffineTransformMakeScale(1 - (realLocation/self.frame.size.width), 1 - (realLocation/self.frame.size.width)); 628 | imageViewToAnimateFollowingPage.frame = CGRectMake((self.deviceWidth - (self.deviceWidth/3))/2 + realLocation/1.5, imageViewToAnimateFollowingPage.frame.origin.y, imageViewToAnimateFollowingPage.frame.size.width, imageViewToAnimateFollowingPage.frame.size.height); 629 | } else { 630 | imageViewToAnimate.transform = CGAffineTransformMakeScale(1 - (realLocation/self.frame.size.width), 1 - (realLocation/self.frame.size.width)); 631 | } 632 | 633 | if (imageViewToAnimateFollowingPage && (self.arrayOfAnimations.count >= page + 2)) { 634 | if ([self.arrayOfAnimations[page + 1] intValue] == 0) { 635 | if (self.scrollOffset + 20 > self.frame.size.width) { 636 | imageViewToAnimateFollowingPage.frame = CGRectMake(imageViewToAnimateFollowingPage.frame.origin.x, self.deviceHeight/2 - self.deviceHeight/3 + 40, imageViewToAnimateFollowingPage.frame.size.width, imageViewToAnimateFollowingPage.frame.size.height); 637 | } else { 638 | imageViewToAnimateFollowingPage.frame = CGRectMake(imageViewToAnimateFollowingPage.frame.origin.x, - self.frame.size.width + self.scrollOffset * 1.5, imageViewToAnimateFollowingPage.frame.size.width, imageViewToAnimateFollowingPage.frame.size.height); 639 | } 640 | } else if ([self.arrayOfAnimations[page + 1] intValue] == 1) { 641 | if (self.scrollOffset > self.frame.size.width) { 642 | imageViewToAnimateFollowingPage.transform = CGAffineTransformMakeScale(1 - (realLocation/self.frame.size.width), 1 - (realLocation/self.frame.size.width)); 643 | imageViewToAnimateFollowingPage.frame = CGRectMake((self.deviceWidth - (self.deviceWidth/3))/2 + realLocation/1.5, imageViewToAnimateFollowingPage.frame.origin.y, imageViewToAnimateFollowingPage.frame.size.width, imageViewToAnimateFollowingPage.frame.size.height); 644 | } else { 645 | imageViewToAnimateFollowingPage.transform = CGAffineTransformMakeScale(realLocation/self.frame.size.width, realLocation/self.frame.size.width); 646 | } 647 | } 648 | } 649 | } 650 | } 651 | 652 | if ((int)(page + 2) == (int)self.arrayWithSlides.count) { 653 | self.pageControl.alpha = (self.frame.size.width - self.scrollOffset)/self.frame.size.width; 654 | self.buttonDismiss.alpha = self.scrollOffset/self.frame.size.width; 655 | } 656 | } 657 | 658 | - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView 659 | { 660 | self.scrollOffset = 0; 661 | 662 | CGFloat pageWidth = CGRectGetWidth(self.frame); 663 | NSUInteger page = floor((self.contentOffset.x - pageWidth / 2) / pageWidth) + 1; 664 | self.pageControl.currentPage = page; 665 | 666 | if (self.pageToPerformFirstAnimation == (int)page && ![self.viewMain.subviews containsObject:self.imageViewThatMoves]) { 667 | [self.viewMain addSubview:self.imageViewThatMoves]; 668 | self.imageViewThatMoves.alpha = 0; 669 | 670 | self.imageViewThatMoves.transform = CGAffineTransformMakeScale(0, 0); 671 | [UIView animateWithDuration:0.3 animations:^{ 672 | self.imageViewThatMoves.alpha = 1; 673 | self.imageViewThatMoves.transform = CGAffineTransformMakeScale(1.2, 1.2); 674 | } completion:^(BOOL finished) { 675 | [UIView animateWithDuration:0.2 animations:^{ 676 | self.imageViewThatMoves.transform = CGAffineTransformMakeScale(1, 1); 677 | }]; 678 | }]; 679 | } 680 | 681 | if ((int)page < self.pageToPerformFirstAnimation) { 682 | self.imageViewThatMoves.transform = CGAffineTransformMakeScale(1, 1); 683 | [UIView animateWithDuration:0.2 animations:^{ 684 | self.imageViewThatMoves.transform = CGAffineTransformMakeScale(1.1, 1.1); 685 | } completion:^(BOOL finished) { 686 | [UIView animateWithDuration:1.4 animations:^{ 687 | self.imageViewThatMoves.transform = CGAffineTransformMakeScale(0, 0); 688 | self.imageViewThatMoves.alpha = 0; 689 | } completion:^(BOOL finished) { 690 | [self.imageViewThatMoves removeFromSuperview]; 691 | }]; 692 | }]; 693 | } 694 | 695 | [self loadScrollViewWithPage:page - 1]; 696 | [self loadScrollViewWithPage:page]; 697 | [self loadScrollViewWithPage:page + 1]; 698 | [self loadScrollViewWithPage:page + 2]; 699 | [self loadScrollViewWithPage:page + 3]; 700 | 701 | if ([self.firstPageSecond intValue] == (int)page) { 702 | [self.staticImageView removeFromSuperview]; 703 | } else if ([self.firstPageFirst intValue] == (int)page) { 704 | [self.mainView addSubview:self.staticImageView]; 705 | self.staticImageView.alpha = 0; 706 | 707 | if (self.animationStaticImage == 0) { 708 | self.staticImageView.transform = CGAffineTransformMakeScale(0, 0); 709 | [UIView animateWithDuration:0.3 animations:^{ 710 | self.staticImageView.alpha = 1; 711 | self.staticImageView.transform = CGAffineTransformMakeScale(1.2, 1.2); 712 | } completion:^(BOOL finished) { 713 | [UIView animateWithDuration:0.2 animations:^{ 714 | self.staticImageView.transform = CGAffineTransformMakeScale(1, 1); 715 | }]; 716 | }]; 717 | } else if (self.animationStaticImage == 1) { 718 | self.staticImageView.transform = CGAffineTransformMakeTranslation(10, -500); 719 | [UIView animateWithDuration:0.3 animations:^{ 720 | self.staticImageView.alpha = 1; 721 | self.staticImageView.transform = CGAffineTransformMakeTranslation(0, 20); 722 | } completion:^(BOOL finished) { 723 | [UIView animateWithDuration:0.2 animations:^{ 724 | self.staticImageView.transform = CGAffineTransformMakeTranslation(0, 0); 725 | }]; 726 | }]; 727 | } else { 728 | self.staticImageView.alpha = 1; 729 | } 730 | 731 | if ([self.mainView.subviews containsObject:self.staticImageViewSecond]) { 732 | [self.staticImageViewSecond removeFromSuperview]; 733 | } 734 | } 735 | 736 | if ([self.secondPageFirst intValue] == (int)page && ![self.mainView.subviews containsObject:self.staticImageViewSecond]) { 737 | [self.mainView addSubview:self.staticImageViewSecond]; 738 | self.staticImageViewSecond.alpha = 0; 739 | 740 | if (self.animationStaticImageSecond == 0) { 741 | self.staticImageViewSecond.transform = CGAffineTransformMakeScale(0, 0); 742 | [UIView animateWithDuration:0.3 animations:^{ 743 | self.staticImageViewSecond.alpha = 1; 744 | self.staticImageViewSecond.transform = CGAffineTransformMakeScale(1.2, 1.2); 745 | } completion:^(BOOL finished) { 746 | [UIView animateWithDuration:0.2 animations:^{ 747 | self.staticImageViewSecond.transform = CGAffineTransformMakeScale(1, 1); 748 | }]; 749 | }]; 750 | } else if (self.animationStaticImageSecond == 1) { 751 | self.staticImageViewSecond.transform = CGAffineTransformMakeTranslation(10, -500); 752 | [UIView animateWithDuration:0.3 animations:^{ 753 | self.staticImageViewSecond.alpha = 1; 754 | self.staticImageViewSecond.transform = CGAffineTransformMakeTranslation(0, 20); 755 | } completion:^(BOOL finished) { 756 | [UIView animateWithDuration:0.2 animations:^{ 757 | self.staticImageViewSecond.transform = CGAffineTransformMakeTranslation(0, 0); 758 | }]; 759 | }]; 760 | } else { 761 | self.staticImageViewSecond.alpha = 1; 762 | } 763 | } else if ([self.secondPageSecond intValue] == (int)page) { 764 | [self.staticImageViewSecond removeFromSuperview]; 765 | } 766 | } 767 | 768 | #pragma mark - Helper methods 769 | 770 | - (void)getPageControlColorFromBackgroundColor:(UIColor *)backgroundColor 771 | { 772 | CGFloat hue = 0; 773 | CGFloat saturation = 0; 774 | CGFloat brightness = 0; 775 | CGFloat alpha = 0; 776 | [backgroundColor getHue:&hue saturation:&saturation brightness:&brightness alpha:&alpha]; 777 | self.pageControl.currentPageIndicatorTintColor = [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:alpha-0.3]; 778 | self.pageControl.pageIndicatorTintColor = [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:alpha-0.5]; 779 | } 780 | 781 | @end 782 | -------------------------------------------------------------------------------- /Examples/RGDynamicOnboard/ViewController.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface ViewController : UIViewController 4 | 5 | 6 | @end 7 | 8 | -------------------------------------------------------------------------------- /Examples/RGDynamicOnboard/ViewController.m: -------------------------------------------------------------------------------- 1 | #import "ViewController.h" 2 | #import "RGDynamicOnboard.h" 3 | 4 | @interface ViewController () 5 | 6 | @property UIView *viewHeader; 7 | @property RGDynamicOnboard *mainSlideView; 8 | @property CGFloat deviceWidth; 9 | @property CGFloat deviceHeight; 10 | 11 | @end 12 | 13 | @implementation ViewController 14 | 15 | - (void)viewDidLoad 16 | { 17 | [super viewDidLoad]; 18 | 19 | [self setNeedsStatusBarAppearanceUpdate]; 20 | 21 | self.deviceWidth = [UIScreen mainScreen].bounds.size.width; 22 | self.deviceHeight = [UIScreen mainScreen].bounds.size.height; 23 | 24 | #pragma mark - Examples 25 | 26 | // IMPORTANT: It's important to add the line below this comment to use the examples! 27 | 28 | self.mainSlideView = [[RGDynamicOnboard alloc] initFullscreenWithNumberOfSlides:3 andPageControl:YES inView:self.view]; 29 | 30 | #pragma mark - First example 31 | 32 | // [self.mainSlideView addImage:[UIImage imageNamed:@"firstImage"] andText:@"Just like magic, add two lines of code and that's it..." toPageNumber:0]; 33 | // [self.mainSlideView applyAnimationNumber:0 toGoFromPage:0]; 34 | // [self.mainSlideView addImage:[UIImage imageNamed:@"secondImage"] andText:@"With multiple animations and some more options!" toPageNumber:1]; 35 | // [self.mainSlideView applyAnimationNumber:0 toGoFromPage:1]; 36 | // [self.mainSlideView addImage:[UIImage imageNamed:@"thirdImage"] andText:@"And some more customization is coming!" toPageNumber:2]; 37 | // [self.mainSlideView applyAnimationNumber:0 toGoFromPage:2]; 38 | 39 | #pragma mark - Second example 40 | 41 | // [self.mainSlideView addStaticImage:[UIImage imageNamed:@"firstImage"] inPosition:3]; 42 | // [self.mainSlideView addText:@"Just like magic too, add static images!" inPage:0]; 43 | // [self.mainSlideView addText:@"Add then text to pages" inPage:1]; 44 | 45 | #pragma mark - Third example 46 | 47 | // [self.mainSlideView addBackgroundImage:[UIImage imageNamed:@"mountain"]]; 48 | // [self.mainSlideView addText:@"Like magic, a background image all over the place" inPage:0 withColor:[UIColor whiteColor]]; 49 | // [self.mainSlideView addText:@"Add then text to pages" inPage:1 withColor:[UIColor whiteColor]]; 50 | 51 | #pragma mark - Fourth example 52 | 53 | // [self.mainSlideView addStaticImage:[UIImage imageNamed:@"firstImage"] inPosition:3 fromPage:0 toPage:1 withAnimationAppearance:1]; 54 | // [self.mainSlideView addStaticImage:[UIImage imageNamed:@"secondImage"] inPosition:3 fromPage:1 toPage:3 withAnimationAppearance:0]; 55 | 56 | #pragma mark - Fifth example 57 | 58 | // [self.mainSlideView addEditableStaticImage:[UIImage imageNamed:@"thirdImage"] inPage:0 inFrame:CGRectMake((self.deviceWidth - 200)/2, 200, 200, 200) andGoToFrame:CGRectMake((self.deviceWidth - 100)/2, 0, 100, 100) toPage:1]; 59 | // [self.mainSlideView image:[UIImage imageNamed:@"thirdImage"] toGoFromPage:1 toFrame:CGRectMake((self.deviceWidth - 200)/2, 200, 200, 200)]; 60 | // self.mainSlideView.backgroundColorAllScrollView = [UIColor redColor]; 61 | // self.mainSlideView.dismissButtonCornerColor = [UIColor whiteColor]; 62 | // self.mainSlideView.dismissButtonFontColor = [UIColor whiteColor]; 63 | 64 | #pragma mark - Sixth example 65 | 66 | // [self.mainSlideView addImage:[UIImage imageNamed:@"firstImage"] inFrame:CGRectMake((self.deviceWidth - 200)/2, 200, 200, 200) inPage:1 withAnimation:0]; 67 | 68 | #pragma mark - Seventh example 69 | 70 | // [self.mainSlideView addImage:[UIImage imageNamed:@"firstImage"] andText:@"Just like magic, add two lines of code and that's it..." toPageNumber:0]; 71 | // [self.mainSlideView applyAnimationNumber:1 toGoFromPage:0]; 72 | // [self.mainSlideView addImage:[UIImage imageNamed:@"secondImage"] andText:@"With multiple animations and some more options!" toPageNumber:1]; 73 | // [self.mainSlideView applyAnimationNumber:1 toGoFromPage:1]; 74 | // [self.mainSlideView addImage:[UIImage imageNamed:@"thirdImage"] andText:@"And some more customization is coming!" toPageNumber:2]; 75 | // [self.mainSlideView applyAnimationNumber:0 toGoFromPage:2]; 76 | 77 | #pragma mark - Eighth example 78 | 79 | [self.mainSlideView addBackgroundImage:[UIImage imageNamed:@"background"]]; 80 | [self.mainSlideView addEditableStaticImage:[UIImage imageNamed:@"welcomeImage"] inPage:0 inFrame:CGRectMake(50, self.deviceHeight/3, self.deviceWidth - 100, 150) andGoToFrame:CGRectMake(100, 25, self.deviceWidth - 200, 100) toPage:1]; 81 | [self.mainSlideView addImage:[UIImage imageNamed:@"fourthImage"] inFrame:CGRectMake((self.deviceWidth - 200)/2, (self.deviceHeight - 200)/2 - 50, 200, 200) inPage:1 withAnimation:1]; 82 | [self.mainSlideView addString:@"Just like magic, just with 4 lines of code..." andFont:[UIFont fontWithName:@"AvenirNextCondensed-DemiBold" size:24] andTextColor:[UIColor whiteColor] inFrame:CGRectMake(50, self.deviceHeight - 280, self.deviceWidth - 100, 200) inPage:1 withAnimation:0]; 83 | [self.mainSlideView image:[UIImage imageNamed:@"welcomeImage"] toGoFromPage:1 toFrame:CGRectMake(50, self.deviceHeight/3, self.deviceWidth - 100, 150)]; 84 | 85 | 86 | 87 | } 88 | 89 | #pragma mark - Change color status bar 90 | 91 | - (UIStatusBarStyle)preferredStatusBarStyle 92 | { 93 | return UIStatusBarStyleLightContent; 94 | } 95 | 96 | @end 97 | -------------------------------------------------------------------------------- /Examples/RGDynamicOnboard/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // RGDynamicOnboard 4 | // 5 | // Created by Ramon Gilabert Llop on 3/12/15. 6 | // Copyright (c) 2015 Ramon Gilabert. 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 | -------------------------------------------------------------------------------- /Examples/RGDynamicOnboardTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.ramongilabert.$(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 | -------------------------------------------------------------------------------- /Examples/RGDynamicOnboardTests/RGDynamicOnboardTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // RGDynamicOnboardTests.m 3 | // RGDynamicOnboardTests 4 | // 5 | // Created by Ramon Gilabert Llop on 3/12/15. 6 | // Copyright (c) 2015 Ramon Gilabert. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface RGDynamicOnboardTests : XCTestCase 13 | 14 | @end 15 | 16 | @implementation RGDynamicOnboardTests 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![RGDynamicOnboard](https://github.com/RamonGilabert/RGDynamicOnboard/blob/master/Resources/Header.png) 2 | 3 | ## RGDynamicOnboard 4 | 5 | A nicely dynamic slideshow to present whatever you want, just add an image, some text and choose one of the animations, RGDynamicOnboard will take care of the rest. There are multiple ways to customize your slide show, add static images, images that go from a page to another, add text, choose the font and some colors and, with just 5 lines of code, you have a fully responsive slideshow! 6 | 7 | ## Featuring 8 | 9 | - As easy as entering a string and choosing some animations. 10 | - For all devices, calculated sizes dinamically. 11 | - Multiple options of customization. 12 | - Do more, write less. 13 | - Animations calculated dinamically. 14 | - Animations going left or right. 15 | - Not all pages loaded at the same time, less memory space. 16 | 17 | ## Usage 18 | 19 | Import the main file into your Xcode project or use Cocoapods to install the pod. 20 | 21 | ### Create a simple walkthrough 22 | 23 | ```objc 24 | self.mainSlideView = [[RGDynamicOnboard alloc] initFullscreenWithNumberOfSlides:3 andPageControl:YES inView:self.view]; 25 | ``` 26 | 27 | ### Customize it, add images, some text 28 | 29 | ```objc 30 | [self.mainSlideView addImage:[UIImage imageNamed:@"firstImage"] andText:@"Just like magic, add two lines of code and that's it..." toPageNumber:0]; 31 | [self.mainSlideView applyAnimationNumber:0 toGoFromPage:0]; 32 | [self.mainSlideView addImage:[UIImage imageNamed:@"secondImage"] andText:@"With multiple animations and some more options!" toPageNumber:1]; 33 | [self.mainSlideView applyAnimationNumber:0 toGoFromPage:1]; 34 | [self.mainSlideView addImage:[UIImage imageNamed:@"thirdImage"] andText:@"And some more customization is coming!" toPageNumber:2]; 35 | [self.mainSlideView applyAnimationNumber:0 toGoFromPage:2]; 36 | ``` 37 | 38 | ### More options 39 | 40 | Add static images, text and customize your colors. 41 | 42 | ## Example 43 | 44 | ![RGDynamicOnboard](https://github.com/RamonGilabert/RGDynamicOnboard/blob/master/Resources/AppFirst.gif) 45 | 46 | ![RGDynamicOnboard](https://github.com/RamonGilabert/RGDynamicOnboard/blob/master/Resources/AppSecond.gif) 47 | 48 | ## Upcoming features 49 | 50 | - Add more animations to the table. 51 | 52 | ## Contributing 53 | 54 | 1. Fork it. 55 | 2. Create your branch (`git checkout -b feature-branch`). 56 | 3. Commit your changes (`git commit -am 'Added this feature'`). 57 | 4. Push to the branch (`git push origin feature-branch`). 58 | 5. Create new pull request. 59 | 60 | ## Done by 61 | 62 | [Ramon Gilabert](http://ramongilabert.com) with love! :) 63 | -------------------------------------------------------------------------------- /RGDynamicOnboard.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface RGDynamicOnboard : UIScrollView 4 | 5 | @property (strong, nonatomic) UIColor *backgroundColorAllScrollView; 6 | @property (strong, nonatomic) UIColor *dismissButtonCornerColor; 7 | @property (strong, nonatomic) UIColor *dismissButtonFontColor; 8 | @property (strong, nonatomic) UIColor *dismissButtonBackgroundColor; 9 | 10 | - (instancetype)initFullscreenWithNumberOfSlides:(int)slides andPageControl:(BOOL)pageControl inView:(UIView *)view; 11 | 12 | - (void)addImage:(UIImage *)image andText:(NSString *)string toPageNumber:(int)page; 13 | - (void)applyAnimationNumber:(int)animation toGoFromPage:(int)page; 14 | 15 | - (void)addStaticImage:(UIImage *)image inPosition:(int)position; 16 | - (void)addStaticImage:(UIImage *)image inFrame:(CGRect)frame; 17 | - (void)addStaticImage:(UIImage *)image inPosition:(int)position fromPage:(int)firstPage toPage:(int)secondPage withAnimationAppearance:(int)animationOption; 18 | 19 | - (void)addText:(NSString *)string inPage:(int)page withFontColor:(UIColor *)color; 20 | - (void)addText:(NSString *)string inPage:(int)page withColor:(UIColor *)color; 21 | 22 | - (void)addBackgroundImage:(UIImage *)image; 23 | - (void)addBackgroundImage:(UIImage *)image withFrame:(CGRect)frame; 24 | - (void)addBackgroundImage:(UIImage *)image withX:(CGFloat)xValue withY:(CGFloat)yValue withAllWidthAndHeight:(CGFloat)height; 25 | 26 | - (void)addEditableStaticImage:(UIImage *)image inPage:(int)page inFrame:(CGRect)initialFrame andGoToFrame:(CGRect)secondFrame toPage:(int)pageToGo; 27 | - (void)image:(UIImage *)image toGoFromPage:(int)page toFrame:(CGRect)lastFrame; 28 | 29 | - (void)addImage:(UIImage *)image inFrame:(CGRect)frame inPage:(int)page withAnimation:(int)animation; 30 | - (void)addString:(NSString *)text inFrame:(CGRect)frame inPage:(int)page withAnimation:(int)animation; 31 | - (void)addString:(NSString *)text andFont:(UIFont *)font inFrame:(CGRect)frame inPage:(int)page withAnimation:(int)animation; 32 | - (void)addString:(NSString *)text andFont:(UIFont *)font andTextColor:(UIColor *)color inFrame:(CGRect)frame inPage:(int)page withAnimation:(int)animation; 33 | 34 | - (void)addBackgroundColor:(UIColor *)color inPage:(int)page; 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /RGDynamicOnboard.m: -------------------------------------------------------------------------------- 1 | #import "RGDynamicOnboard.h" 2 | 3 | @interface RGDynamicOnboard () 4 | 5 | @property (strong, nonatomic) UIPageControl *pageControl; 6 | @property (strong, nonatomic) UIWindow *mainView; 7 | @property (strong, nonatomic) UIColor *colorSlide; 8 | @property (strong, nonatomic) UIView *viewMain; 9 | @property (strong, nonatomic) UIButton *buttonDismiss; 10 | @property (strong, nonatomic) UIImageView *staticImageView; 11 | @property (strong, nonatomic) UIImageView *staticImageViewSecond; 12 | @property (strong, nonatomic) UIImageView *backgroundImageView; 13 | @property (strong, nonatomic) UIImageView *imageViewThatMoves; 14 | @property (strong, nonatomic) NSMutableArray *arrayWithSlides; 15 | @property (strong, nonatomic) NSMutableArray *arrayOfAnimations; 16 | @property (strong, nonatomic) NSMutableArray *arrayWithImagesAnimation; 17 | @property (strong, nonatomic) NSMutableArray *arrayWithImages; 18 | @property (strong, nonatomic) NSMutableArray *arrayWithImagesPages; 19 | @property (strong, nonatomic) NSMutableArray *arrayOfFrames; 20 | @property (strong, nonatomic) NSMutableArray *arrayOfFramesX; 21 | @property (weak, nonatomic) NSNumber *firstPageFirst; 22 | @property (weak, nonatomic) NSNumber *firstPageSecond; 23 | @property (weak, nonatomic) NSNumber *secondPageFirst; 24 | @property (weak, nonatomic) NSNumber *secondPageSecond; 25 | @property CGRect frameToGo; 26 | @property CGRect initialFrame; 27 | @property CGRect initialFrameOnceAnimationDone; 28 | @property CGRect finalFrameOnceAnimationDone; 29 | @property CGFloat deviceWidth; 30 | @property CGFloat deviceHeight; 31 | @property CGFloat scrollOffset; 32 | @property int numberOfPages; 33 | @property int animationStaticImage; 34 | @property int animationStaticImageSecond; 35 | @property int pageToPerformFirstAnimation; 36 | @property int pageToPerformSecondAnimation; 37 | @property int pageToPerformThirdAnimation; 38 | 39 | @end 40 | 41 | @implementation RGDynamicOnboard 42 | 43 | - (instancetype)initFullscreenWithNumberOfSlides:(int)slides andPageControl:(BOOL)pageControl inView:(UIView *)view 44 | { 45 | self = [RGDynamicOnboard new]; 46 | 47 | self.pageToPerformFirstAnimation = 100; 48 | self.pageToPerformSecondAnimation = 100; 49 | self.pageToPerformThirdAnimation = 100; 50 | 51 | self.viewMain = [UIView new]; 52 | self.viewMain = view; 53 | 54 | self.deviceWidth = [UIScreen mainScreen].bounds.size.width; 55 | self.deviceHeight = [UIScreen mainScreen].bounds.size.height; 56 | 57 | self.arrayWithSlides = [NSMutableArray new]; 58 | self.arrayOfAnimations = [NSMutableArray new]; 59 | self.arrayWithImages = [NSMutableArray new]; 60 | self.arrayWithImagesAnimation = [NSMutableArray new]; 61 | self.arrayWithImagesPages = [NSMutableArray new]; 62 | self.arrayOfFrames = [NSMutableArray new]; 63 | self.arrayOfFramesX = [NSMutableArray new]; 64 | 65 | for (int i = 0; i < slides; i++) { 66 | [self.arrayWithSlides addObject:[NSNull null]]; 67 | [self.arrayOfAnimations addObject:[NSNull null]]; 68 | } 69 | 70 | self.mainView = [[[UIApplication sharedApplication] delegate] window]; 71 | 72 | self.numberOfPages = slides; 73 | 74 | self.frame = CGRectMake(0, 0, self.deviceWidth, self.deviceHeight); 75 | self.pagingEnabled = YES; 76 | self.contentSize = CGSizeMake(self.deviceWidth * slides, self.deviceHeight); 77 | self.showsHorizontalScrollIndicator = NO; 78 | self.showsVerticalScrollIndicator = NO; 79 | self.scrollsToTop = NO; 80 | self.delegate = self; 81 | 82 | if (pageControl) { 83 | self.pageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(0, self.deviceHeight - 75, self.deviceWidth, 20)]; 84 | self.pageControl.numberOfPages = slides; 85 | [self getPageControlColorFromBackgroundColor:[UIColor darkGrayColor]]; 86 | [self.viewMain addSubview:self.pageControl]; 87 | } 88 | 89 | [self.viewMain addSubview: self]; 90 | 91 | [self loadScrollViewWithPage:0]; 92 | [self loadScrollViewWithPage:1]; 93 | [self loadScrollViewWithPage:2]; 94 | [self loadScrollViewWithPage:3]; 95 | 96 | return self; 97 | } 98 | 99 | - (void)addBackgroundColor:(UIColor *)color inPage:(int)page 100 | { 101 | if (page >= self.numberOfPages) return; 102 | 103 | UIView *view = [self.arrayWithSlides objectAtIndex:page]; 104 | 105 | if ((NSNull *)view == [NSNull null]) { 106 | view = [UIView new]; 107 | [self.arrayWithSlides replaceObjectAtIndex:page withObject:view]; 108 | } 109 | 110 | view.backgroundColor = color; 111 | } 112 | 113 | - (void)setBackgroundColorAllScrollView:(UIColor *)backgroundColorAllScrollView 114 | { 115 | self.viewMain.backgroundColor = backgroundColorAllScrollView; 116 | 117 | if (self.pageControl) { 118 | CGFloat hueColor; 119 | CGFloat saturationColor; 120 | CGFloat brightnessColor; 121 | CGFloat alphaColor; 122 | 123 | [backgroundColorAllScrollView getHue:&hueColor saturation:&saturationColor brightness:&brightnessColor alpha:&alphaColor]; 124 | 125 | self.pageControl.currentPageIndicatorTintColor = [UIColor colorWithHue:hueColor saturation:saturationColor brightness:brightnessColor-0.4 alpha:alphaColor]; 126 | self.pageControl.pageIndicatorTintColor = [UIColor colorWithHue:hueColor saturation:saturationColor brightness:brightnessColor-0.2 alpha:alphaColor]; 127 | } 128 | } 129 | 130 | - (void)setDismissButtonCornerColor:(UIColor *)dismissButtonCornerColor 131 | { 132 | self.buttonDismiss.layer.borderColor = dismissButtonCornerColor.CGColor; 133 | } 134 | 135 | - (void)setDismissButtonFontColor:(UIColor *)dismissButtonFontColor 136 | { 137 | [self.buttonDismiss setTitleColor:dismissButtonFontColor forState:UIControlStateNormal]; 138 | } 139 | 140 | - (void)setDismissButtonBackgroundColor:(UIColor *)dismissButtonBackgroundColor 141 | { 142 | self.buttonDismiss.backgroundColor = dismissButtonBackgroundColor; 143 | } 144 | 145 | - (void)addImage:(UIImage *)image inFrame:(CGRect)frame inPage:(int)page withAnimation:(int)animation 146 | { 147 | if (page >= self.numberOfPages) return; 148 | 149 | UIView *view = [self.arrayWithSlides objectAtIndex:page]; 150 | 151 | if ((NSNull *)view == [NSNull null]) { 152 | view = [UIView new]; 153 | [self.arrayWithSlides replaceObjectAtIndex:page withObject:view]; 154 | } 155 | 156 | UIImageView *imageView = [[UIImageView alloc] initWithFrame:frame]; 157 | imageView.contentMode = UIViewContentModeScaleAspectFill; 158 | imageView.image = image; 159 | 160 | [self.arrayWithImagesPages addObject:[NSNumber numberWithInt:page]]; 161 | [self.arrayWithImagesAnimation addObject:[NSNumber numberWithInt:animation]]; 162 | [self.arrayWithImages addObject:imageView]; 163 | [self.arrayOfFrames addObject:[NSNumber numberWithFloat:imageView.frame.origin.y]]; 164 | [self.arrayOfFramesX addObject:[NSNumber numberWithFloat:imageView.frame.origin.x]]; 165 | 166 | [view addSubview:imageView]; 167 | } 168 | 169 | - (void)addString:(NSString *)text inFrame:(CGRect)frame inPage:(int)page withAnimation:(int)animation 170 | { 171 | if (page >= self.numberOfPages) return; 172 | 173 | UIView *view = [self.arrayWithSlides objectAtIndex:page]; 174 | 175 | if ((NSNull *)view == [NSNull null]) { 176 | view = [UIView new]; 177 | [self.arrayWithSlides replaceObjectAtIndex:page withObject:view]; 178 | } 179 | 180 | UILabel *label = [[UILabel alloc] initWithFrame:frame]; 181 | label.text = text; 182 | label.numberOfLines = 10; 183 | label.textColor = [UIColor darkGrayColor]; 184 | label.textAlignment = NSTextAlignmentCenter; 185 | label.font = [UIFont fontWithName:@"Helvetica" size:22]; 186 | 187 | [view addSubview:label]; 188 | } 189 | 190 | - (void)addString:(NSString *)text andFont:(UIFont *)font inFrame:(CGRect)frame inPage:(int)page withAnimation:(int)animation 191 | { 192 | if (page >= self.numberOfPages) return; 193 | 194 | UIView *view = [self.arrayWithSlides objectAtIndex:page]; 195 | 196 | if ((NSNull *)view == [NSNull null]) { 197 | view = [UIView new]; 198 | [self.arrayWithSlides replaceObjectAtIndex:page withObject:view]; 199 | } 200 | 201 | UILabel *label = [[UILabel alloc] initWithFrame:frame]; 202 | label.text = text; 203 | label.numberOfLines = 10; 204 | label.textColor = [UIColor darkGrayColor]; 205 | label.textAlignment = NSTextAlignmentCenter; 206 | label.font = font; 207 | 208 | [view addSubview:label]; 209 | } 210 | 211 | - (void)addString:(NSString *)text andFont:(UIFont *)font andTextColor:(UIColor *)color inFrame:(CGRect)frame inPage:(int)page withAnimation:(int)animation 212 | { 213 | if (page >= self.numberOfPages) return; 214 | 215 | UIView *view = [self.arrayWithSlides objectAtIndex:page]; 216 | 217 | if ((NSNull *)view == [NSNull null]) { 218 | view = [UIView new]; 219 | [self.arrayWithSlides replaceObjectAtIndex:page withObject:view]; 220 | } 221 | 222 | UILabel *label = [[UILabel alloc] initWithFrame:frame]; 223 | label.text = text; 224 | label.numberOfLines = 10; 225 | label.textColor = color; 226 | label.textAlignment = NSTextAlignmentCenter; 227 | label.font = font; 228 | 229 | [view addSubview:label]; 230 | } 231 | 232 | - (void)addEditableStaticImage:(UIImage *)image inPage:(int)page inFrame:(CGRect)initialFrame andGoToFrame:(CGRect)secondFrame toPage:(int)pageToGo 233 | { 234 | if (image) { 235 | self.imageViewThatMoves = [[UIImageView alloc] initWithFrame:initialFrame]; 236 | self.imageViewThatMoves.contentMode = UIViewContentModeScaleAspectFit; 237 | self.imageViewThatMoves.image = image; 238 | self.frameToGo = secondFrame; 239 | self.pageToPerformFirstAnimation = page; 240 | self.pageToPerformSecondAnimation = pageToGo - 1; 241 | self.initialFrame = initialFrame; 242 | 243 | if (page == 0) { 244 | [self.viewMain addSubview:self.imageViewThatMoves]; 245 | } 246 | } 247 | } 248 | 249 | - (void)image:(UIImage *)image toGoFromPage:(int)page toFrame:(CGRect)lastFrame 250 | { 251 | if ([self.imageViewThatMoves.image isEqual:image]) { 252 | self.pageToPerformThirdAnimation = page; 253 | self.finalFrameOnceAnimationDone = lastFrame; 254 | } 255 | } 256 | 257 | - (void)addBackgroundImage:(UIImage *)image 258 | { 259 | if (image) { 260 | self.backgroundImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width*self.numberOfPages, self.deviceHeight)]; 261 | self.backgroundImageView.contentMode = UIViewContentModeScaleAspectFill; 262 | self.backgroundImageView.image = image; 263 | [self insertSubview:self.backgroundImageView atIndex:0]; 264 | 265 | self.pageControl.currentPageIndicatorTintColor = [UIColor whiteColor]; 266 | self.pageControl.pageIndicatorTintColor = [UIColor lightGrayColor]; 267 | [self.viewMain bringSubviewToFront:self.pageControl]; 268 | 269 | self.buttonDismiss.layer.borderColor = [UIColor whiteColor].CGColor; 270 | [self.buttonDismiss setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; 271 | } 272 | } 273 | 274 | - (void)addBackgroundImage:(UIImage *)image withFrame:(CGRect)frame 275 | { 276 | if (image) { 277 | self.backgroundImageView = [[UIImageView alloc] initWithFrame:frame]; 278 | self.backgroundImageView.contentMode = UIViewContentModeScaleAspectFill; 279 | self.backgroundImageView.image = image; 280 | [self insertSubview:self.backgroundImageView atIndex:0]; 281 | 282 | if (frame.origin.y > self.deviceHeight/2 || frame.size.height >= self.deviceHeight) { 283 | self.pageControl.currentPageIndicatorTintColor = [UIColor whiteColor]; 284 | self.pageControl.pageIndicatorTintColor = [UIColor lightGrayColor]; 285 | self.buttonDismiss.layer.borderColor = [UIColor whiteColor].CGColor; 286 | [self.buttonDismiss setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; 287 | } 288 | } 289 | } 290 | 291 | - (void)addBackgroundImage:(UIImage *)image withX:(CGFloat)xValue withY:(CGFloat)yValue withAllWidthAndHeight:(CGFloat)height 292 | { 293 | if (image) { 294 | self.backgroundImageView = [[UIImageView alloc] initWithFrame:CGRectMake(xValue, yValue, self.frame.size.width*self.numberOfPages, height)]; 295 | self.backgroundImageView.contentMode = UIViewContentModeScaleAspectFill; 296 | self.backgroundImageView.image = image; 297 | [self insertSubview:self.backgroundImageView atIndex:0]; 298 | 299 | if (yValue > self.deviceHeight/2 || height >= self.deviceHeight) { 300 | self.pageControl.currentPageIndicatorTintColor = [UIColor whiteColor]; 301 | self.pageControl.pageIndicatorTintColor = [UIColor lightGrayColor]; 302 | 303 | self.buttonDismiss.layer.borderColor = [UIColor whiteColor].CGColor; 304 | [self.buttonDismiss setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; 305 | } 306 | } 307 | } 308 | 309 | - (void)addStaticImage:(UIImage *)image inPosition:(int)position 310 | { 311 | self.staticImageView = [UIImageView new]; 312 | 313 | if (position == 0) { 314 | self.staticImageView.frame = CGRectMake((self.deviceWidth - self.deviceWidth/1.7)/2, (self.deviceHeight - self.deviceHeight/3)/2 - 25, self.deviceWidth/1.7, self.deviceHeight/3); 315 | } else if (position == 1) { 316 | self.staticImageView.frame = CGRectMake((self.deviceWidth - self.deviceWidth/1.7)/2 + 60, (self.deviceHeight - self.deviceHeight/3)/2 - 100, self.deviceWidth/1.7, self.deviceHeight/3); 317 | } else if (position == 2) { 318 | self.staticImageView.frame = CGRectMake((self.deviceWidth - self.deviceWidth/1.7)/2 - 60, (self.deviceHeight - self.deviceHeight/3)/2 - 100, self.deviceWidth/1.7, self.deviceHeight/3); 319 | } else { 320 | self.staticImageView.frame = CGRectMake((self.deviceWidth - self.deviceWidth/1.7)/2, (self.deviceHeight - self.deviceHeight/3)/2 - 100, self.deviceWidth/1.7, self.deviceHeight/3); 321 | } 322 | 323 | self.staticImageView.contentMode = UIViewContentModeScaleAspectFill; 324 | self.staticImageView.image = image; 325 | 326 | [self.viewMain addSubview:self.staticImageView]; 327 | } 328 | 329 | - (void)addStaticImage:(UIImage *)image inPosition:(int)position fromPage:(int)firstPage toPage:(int)secondPage withAnimationAppearance:(int)animationOption 330 | { 331 | if (!self.firstPageFirst) { 332 | self.animationStaticImage = animationOption; 333 | 334 | self.firstPageFirst = [NSNumber numberWithInt:firstPage]; 335 | self.firstPageSecond = [NSNumber numberWithInt:secondPage]; 336 | 337 | self.staticImageView = [UIImageView new]; 338 | 339 | if (position == 0) { 340 | self.staticImageView.frame = CGRectMake((self.deviceWidth - self.deviceWidth/1.7)/2, (self.deviceHeight - self.deviceHeight/3)/2 - 25, self.deviceWidth/1.7, self.deviceHeight/3); 341 | } else if (position == 1) { 342 | self.staticImageView.frame = CGRectMake((self.deviceWidth - self.deviceWidth/1.7)/2 + 60, (self.deviceHeight - self.deviceHeight/3)/2 - 100, self.deviceWidth/1.7, self.deviceHeight/3); 343 | } else if (position == 2) { 344 | self.staticImageView.frame = CGRectMake((self.deviceWidth - self.deviceWidth/1.7)/2 - 60, (self.deviceHeight - self.deviceHeight/3)/2 - 100, self.deviceWidth/1.7, self.deviceHeight/3); 345 | } else { 346 | self.staticImageView.frame = CGRectMake((self.deviceWidth - self.deviceWidth/1.7)/2, (self.deviceHeight - self.deviceHeight/3)/2 - 100, self.deviceWidth/1.7, self.deviceHeight/3); 347 | } 348 | 349 | self.staticImageView.contentMode = UIViewContentModeScaleAspectFill; 350 | self.staticImageView.image = image; 351 | 352 | } else { 353 | self.animationStaticImageSecond = animationOption; 354 | 355 | self.secondPageFirst = [NSNumber numberWithInt:firstPage]; 356 | self.secondPageSecond = [NSNumber numberWithInt:secondPage]; 357 | 358 | self.staticImageViewSecond = [UIImageView new]; 359 | 360 | if (position == 0) { 361 | self.staticImageViewSecond.frame = CGRectMake((self.deviceWidth - self.deviceWidth/1.7)/2, (self.deviceHeight - self.deviceHeight/3)/2 - 25, self.deviceWidth/1.7, self.deviceHeight/3); 362 | } else if (position == 1) { 363 | self.staticImageViewSecond.frame = CGRectMake((self.deviceWidth - self.deviceWidth/1.7)/2 + 60, (self.deviceHeight - self.deviceHeight/3)/2 - 100, self.deviceWidth/1.7, self.deviceHeight/3); 364 | } else if (position == 2) { 365 | self.staticImageViewSecond.frame = CGRectMake((self.deviceWidth - self.deviceWidth/1.7)/2 - 60, (self.deviceHeight - self.deviceHeight/3)/2 - 100, self.deviceWidth/1.7, self.deviceHeight/3); 366 | } else { 367 | self.staticImageViewSecond.frame = CGRectMake((self.deviceWidth - self.deviceWidth/1.7)/2, (self.deviceHeight - self.deviceHeight/3)/2 - 100, self.deviceWidth/1.7, self.deviceHeight/3); 368 | } 369 | 370 | self.staticImageViewSecond.contentMode = UIViewContentModeScaleAspectFill; 371 | self.staticImageViewSecond.image = image; 372 | } 373 | 374 | [self.viewMain addSubview:self.staticImageView]; 375 | } 376 | 377 | - (void)addStaticImage:(UIImage *)image inFrame:(CGRect)frame 378 | { 379 | if (&frame && image) { 380 | self.staticImageView = [[UIImageView alloc] initWithFrame:frame]; 381 | self.staticImageView.contentMode = UIViewContentModeScaleAspectFill; 382 | self.staticImageView.image = image; 383 | [self.viewMain addSubview:self.staticImageView]; 384 | } 385 | } 386 | 387 | - (void)addText:(NSString *)string inPage:(int)page withColor:(UIColor *)color 388 | { 389 | UIView *view = [self.arrayWithSlides objectAtIndex:page]; 390 | UILabel *labelOfText = [[UILabel alloc] initWithFrame:CGRectMake(25, self.deviceHeight - self.deviceHeight/6, self.deviceWidth - 50, 200)]; 391 | labelOfText.numberOfLines = 10; 392 | labelOfText.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:22]; 393 | labelOfText.textColor = color; 394 | labelOfText.textAlignment = NSTextAlignmentCenter; 395 | labelOfText.text = string; 396 | [labelOfText sizeToFit]; 397 | CGRect rectOfLabel = labelOfText.frame; 398 | labelOfText.frame = CGRectMake((self.deviceWidth - rectOfLabel.size.width)/2, self.deviceHeight - rectOfLabel.size.height - self.deviceHeight/4, rectOfLabel.size.width, rectOfLabel.size.height); 399 | [view addSubview:labelOfText]; 400 | } 401 | 402 | - (void)addText:(NSString *)string inPage:(int)page 403 | { 404 | UIView *view = [self.arrayWithSlides objectAtIndex:page]; 405 | UILabel *labelOfText = [[UILabel alloc] initWithFrame:CGRectMake(25, self.deviceHeight - self.deviceHeight/6, self.deviceWidth - 50, 200)]; 406 | labelOfText.numberOfLines = 10; 407 | labelOfText.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:22]; 408 | labelOfText.textAlignment = NSTextAlignmentCenter; 409 | labelOfText.text = string; 410 | [labelOfText sizeToFit]; 411 | CGRect rectOfLabel = labelOfText.frame; 412 | labelOfText.frame = CGRectMake((self.deviceWidth - rectOfLabel.size.width)/2, self.deviceHeight - rectOfLabel.size.height - self.deviceHeight/4, rectOfLabel.size.width, rectOfLabel.size.height); 413 | [view addSubview:labelOfText]; 414 | } 415 | 416 | - (void)addImage:(UIImage *)image andText:(NSString *)string toPageNumber:(int)page 417 | { 418 | [self loadScrollViewWithPage:page]; 419 | 420 | UIView *view = [self.arrayWithSlides objectAtIndex:page]; 421 | 422 | UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake((self.deviceWidth - (self.deviceWidth/3))/2, self.deviceHeight/2 - self.deviceHeight/3 + 40, self.deviceWidth/3, self.deviceHeight/4)]; 423 | imageView.image = image; 424 | imageView.contentMode = UIViewContentModeScaleAspectFill; 425 | [view addSubview:imageView]; 426 | 427 | UILabel *labelWithText = [[UILabel alloc] initWithFrame:CGRectMake((self.deviceWidth - (self.deviceWidth - 150))/2, self.deviceHeight/2 + 100, self.deviceWidth - 80, 200)]; 428 | labelWithText.textAlignment = NSTextAlignmentCenter; 429 | labelWithText.numberOfLines = 10; 430 | labelWithText.text = string; 431 | labelWithText.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:22]; 432 | [labelWithText sizeToFit]; 433 | labelWithText.frame = CGRectMake((self.deviceWidth - labelWithText.frame.size.width)/2, self.deviceHeight/2 + 75, labelWithText.frame.size.width, labelWithText.frame.size.height); 434 | [view addSubview:labelWithText]; 435 | 436 | [self.arrayWithSlides replaceObjectAtIndex:page withObject:view]; 437 | } 438 | 439 | - (void)onDismissButtonPressed 440 | { 441 | [UIView animateWithDuration:0.5 animations:^{ 442 | if (self.staticImageView) { 443 | self.staticImageView.transform = CGAffineTransformMakeScale(3, 3); 444 | self.staticImageView.alpha = 0; 445 | } 446 | 447 | if (self.staticImageViewSecond) { 448 | self.staticImageViewSecond.transform = CGAffineTransformMakeScale(3, 3); 449 | self.staticImageViewSecond.alpha = 0; 450 | } 451 | 452 | if (self.imageViewThatMoves) { 453 | self.imageViewThatMoves.transform = CGAffineTransformMakeScale(3, 3); 454 | self.imageViewThatMoves.alpha = 0; 455 | } 456 | 457 | self.transform = CGAffineTransformMakeScale(3, 3); 458 | self.alpha = 0; 459 | } completion:^(BOOL finished) { 460 | if (self.staticImageView) { 461 | [self.staticImageView removeFromSuperview]; 462 | } 463 | 464 | if (self.staticImageViewSecond) { 465 | [self.staticImageViewSecond removeFromSuperview]; 466 | } 467 | 468 | if (self.imageViewThatMoves) { 469 | [self.imageViewThatMoves removeFromSuperview]; 470 | } 471 | 472 | [self removeFromSuperview]; 473 | }]; 474 | } 475 | 476 | - (void)applyAnimationNumber:(int)animation toGoFromPage:(int)page 477 | { 478 | [self.arrayOfAnimations replaceObjectAtIndex:page withObject:[NSNumber numberWithInt:animation]]; 479 | } 480 | 481 | - (void)loadScrollViewWithPage:(NSUInteger)page 482 | { 483 | if (page >= self.numberOfPages) return; 484 | 485 | UIView *view = [self.arrayWithSlides objectAtIndex:page]; 486 | 487 | if ((NSNull *)view == [NSNull null]) { 488 | view = [UIView new]; 489 | [self.arrayWithSlides replaceObjectAtIndex:page withObject:view]; 490 | } 491 | 492 | if (view.superview == nil) 493 | { 494 | CGRect frame = self.frame; 495 | frame.origin.x = CGRectGetWidth(frame) * page; 496 | frame.origin.y = 0; 497 | view.frame = frame; 498 | 499 | [self addSubview:view]; 500 | } 501 | 502 | if ((int)(page + 1) == (int)self.arrayWithSlides.count) { 503 | if (!self.buttonDismiss) { 504 | self.buttonDismiss = [[UIButton alloc] initWithFrame:CGRectMake(50, self.deviceHeight - self.deviceHeight/5.5, self.deviceWidth - 100, 65)]; 505 | self.buttonDismiss.layer.cornerRadius = 7.5; 506 | self.buttonDismiss.layer.borderColor = [UIColor darkGrayColor].CGColor; 507 | self.buttonDismiss.layer.borderWidth = 2; 508 | self.buttonDismiss.titleLabel.font = [UIFont fontWithName:@"Avenir" size:26]; 509 | [self.buttonDismiss setTitle:@"Start this journey" forState:UIControlStateNormal]; 510 | [self.buttonDismiss setTitleColor:[UIColor darkGrayColor] forState:UIControlStateNormal]; 511 | [self.buttonDismiss addTarget:self action:@selector(onDismissButtonPressed) forControlEvents:UIControlEventTouchUpInside]; 512 | self.buttonDismiss.alpha = 0; 513 | [view addSubview:self.buttonDismiss]; 514 | } 515 | } 516 | } 517 | 518 | #pragma mark - Delegate methods 519 | 520 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView 521 | { 522 | CGFloat pageWidth = CGRectGetWidth(self.frame); 523 | NSUInteger page = floor((self.contentOffset.x - pageWidth) / pageWidth) + 1; 524 | 525 | CGFloat realLocation = scrollView.contentOffset.x - self.deviceWidth * page; 526 | 527 | self.scrollOffset = realLocation; 528 | 529 | if ((int)page < 0) return; 530 | 531 | UIView *view = [self.arrayWithSlides objectAtIndex:page]; 532 | UIView *viewSecond = [UIView new]; 533 | 534 | if (page + 1 < self.arrayWithSlides.count) { 535 | viewSecond = [self.arrayWithSlides objectAtIndex:(page + 1)]; 536 | } 537 | 538 | UIImageView *imageViewToAnimate = [UIImageView new]; 539 | UILabel *labelToAnimate = [UILabel new]; 540 | UIImageView *imageViewToAnimateFollowingPage = [UIImageView new]; 541 | UILabel *labelToAnimateFollowingPage = [UILabel new]; 542 | 543 | if (view.subviews.count > 0) { 544 | for (UIView *viewWeTake in view.subviews) { 545 | if ([viewWeTake isKindOfClass:[UILabel class]]) { 546 | labelToAnimate = (UILabel *)viewWeTake; 547 | } else if ([viewWeTake isKindOfClass:[UIImageView class]]) { 548 | imageViewToAnimate = (UIImageView *)viewWeTake; 549 | } 550 | } 551 | } 552 | 553 | if (![viewSecond isKindOfClass:[NSNull class]]) { 554 | for (UIView *viewWeTake in viewSecond.subviews) { 555 | if ([viewWeTake isKindOfClass:[UILabel class]]) { 556 | labelToAnimateFollowingPage = (UILabel *)viewWeTake; 557 | } else if ([viewWeTake isKindOfClass:[UIImageView class]]) { 558 | imageViewToAnimateFollowingPage = (UIImageView *)viewWeTake; 559 | } 560 | } 561 | } 562 | 563 | for (NSNumber *number in self.arrayWithImagesPages) { 564 | if ([number intValue] == page) { 565 | int indexOfPage = (int)[self.arrayWithImagesPages indexOfObject:number]; 566 | UIImageView *imageView = self.arrayWithImages[indexOfPage]; 567 | 568 | if ([self.arrayWithImagesAnimation[indexOfPage] isEqual:[NSNumber numberWithInt:0]]) { 569 | imageView.frame = CGRectMake([self.arrayOfFramesX[indexOfPage] floatValue] + self.scrollOffset/1.5, [self.arrayOfFrames[indexOfPage] floatValue] - self.scrollOffset*1.5, imageView.frame.size.width, imageView.frame.size.height); 570 | } 571 | } else if ([number intValue] == page + 1) { 572 | int indexOfPage = (int)[self.arrayWithImagesPages indexOfObject:number]; 573 | UIImageView *imageView = self.arrayWithImages[indexOfPage]; 574 | 575 | if ([self.arrayWithImagesAnimation[indexOfPage] isEqual:[NSNumber numberWithInt:0]]) { 576 | imageView.frame = CGRectMake([self.arrayOfFramesX[indexOfPage] floatValue] - (self.frame.size.width - self.scrollOffset)/1.5, [self.arrayOfFrames[indexOfPage] floatValue] - (self.frame.size.width - self.scrollOffset)*1.5, imageView.frame.size.width, imageView.frame.size.height); 577 | } 578 | } 579 | } 580 | 581 | if (self.pageToPerformSecondAnimation == (int)page) { 582 | CGFloat floatValue = (self.frameToGo.origin.y - self.initialFrame.origin.y)/self.frame.size.width; 583 | CGFloat floatValueX = (self.frameToGo.origin.x - self.initialFrame.origin.x)/self.frame.size.width; 584 | CGFloat floatValueHeight = (self.frameToGo.size.height - self.initialFrame.size.height)/self.frame.size.width; 585 | CGFloat floatValueWidth = (self.frameToGo.size.width - self.initialFrame.size.width)/self.frame.size.width; 586 | 587 | self.imageViewThatMoves.frame = CGRectMake(self.initialFrame.origin.x + self.scrollOffset*floatValueX, self.initialFrame.origin.y + self.scrollOffset*floatValue, self.initialFrame.size.width + self.scrollOffset*floatValueWidth, self.initialFrame.size.height + self.scrollOffset*floatValueHeight); 588 | } 589 | 590 | if (self.pageToPerformThirdAnimation == (int)page) { 591 | CGFloat floatValue = (self.frameToGo.origin.y - self.finalFrameOnceAnimationDone.origin.y)/self.frame.size.width; 592 | CGFloat floatValueX = (self.frameToGo.origin.x - self.finalFrameOnceAnimationDone.origin.x)/self.frame.size.width; 593 | CGFloat floatValueHeight = (self.frameToGo.size.height - self.finalFrameOnceAnimationDone.size.height)/self.frame.size.width; 594 | CGFloat floatValueWidth = (self.frameToGo.size.width - self.finalFrameOnceAnimationDone.size.width)/self.frame.size.width; 595 | 596 | self.imageViewThatMoves.frame = CGRectMake(self.frameToGo.origin.x - self.scrollOffset*floatValueX, self.frameToGo.origin.y - self.scrollOffset*floatValue, self.frameToGo.size.width - self.scrollOffset*floatValueWidth, self.frameToGo.size.height - self.scrollOffset*floatValueHeight); 597 | } 598 | 599 | if (![self.arrayOfAnimations[page] isKindOfClass:[NSNull class]]) { 600 | if ([self.arrayOfAnimations[page] intValue] == 0) { 601 | imageViewToAnimate.frame = CGRectMake((self.deviceWidth - (self.deviceWidth/3))/2 + self.scrollOffset/1.5, self.deviceHeight/2 - self.deviceHeight/3 + 40 - realLocation, imageViewToAnimate.frame.size.width, imageViewToAnimate.frame.size.height); 602 | 603 | if (imageViewToAnimateFollowingPage && (self.arrayOfAnimations.count >= page + 2)) { 604 | if (![self.arrayOfAnimations[page + 1] isKindOfClass:[NSNull class]]) { 605 | if ([self.arrayOfAnimations[page + 1] intValue] == 0) { 606 | if (self.scrollOffset + 20 > self.frame.size.width) { 607 | imageViewToAnimateFollowingPage.frame = CGRectMake(imageViewToAnimateFollowingPage.frame.origin.x, self.deviceHeight/2 - self.deviceHeight/3 + 40, imageViewToAnimateFollowingPage.frame.size.width, imageViewToAnimateFollowingPage.frame.size.height); 608 | } else { 609 | imageViewToAnimateFollowingPage.frame = CGRectMake(imageViewToAnimateFollowingPage.frame.origin.x, - self.frame.size.width + self.scrollOffset * 1.5, imageViewToAnimateFollowingPage.frame.size.width, imageViewToAnimateFollowingPage.frame.size.height); 610 | } 611 | } else if ([self.arrayOfAnimations[page + 1] intValue] == 1) { 612 | if (self.scrollOffset > self.frame.size.width) { 613 | imageViewToAnimateFollowingPage.transform = CGAffineTransformMakeScale(1 - (realLocation/self.frame.size.width), 1 - (realLocation/self.frame.size.width)); 614 | imageViewToAnimateFollowingPage.frame = CGRectMake((self.deviceWidth - (self.deviceWidth/3))/2 + realLocation/1.5, imageViewToAnimateFollowingPage.frame.origin.y, imageViewToAnimateFollowingPage.frame.size.width, imageViewToAnimateFollowingPage.frame.size.height); 615 | } else { 616 | imageViewToAnimateFollowingPage.transform = CGAffineTransformMakeScale(realLocation/self.frame.size.width, realLocation/self.frame.size.width); 617 | imageViewToAnimateFollowingPage.frame = CGRectMake((self.deviceWidth - (self.deviceWidth/3))/2 - realLocation/1.5, imageViewToAnimateFollowingPage.frame.origin.y, imageViewToAnimateFollowingPage.frame.size.width, imageViewToAnimateFollowingPage.frame.size.height); 618 | } 619 | } 620 | } 621 | } 622 | } else if ([self.arrayOfAnimations[page] intValue] == 1) { 623 | if (self.scrollOffset > self.frame.size.width) { 624 | imageViewToAnimate.transform = CGAffineTransformMakeScale(realLocation/self.frame.size.width, realLocation/self.frame.size.width); 625 | imageViewToAnimate.frame = CGRectMake((self.deviceWidth - (self.deviceWidth/3))/2 + realLocation/1.5, imageViewToAnimate.frame.origin.y, imageViewToAnimate.frame.size.width, imageViewToAnimate.frame.size.height); 626 | 627 | imageViewToAnimateFollowingPage.transform = CGAffineTransformMakeScale(1 - (realLocation/self.frame.size.width), 1 - (realLocation/self.frame.size.width)); 628 | imageViewToAnimateFollowingPage.frame = CGRectMake((self.deviceWidth - (self.deviceWidth/3))/2 + realLocation/1.5, imageViewToAnimateFollowingPage.frame.origin.y, imageViewToAnimateFollowingPage.frame.size.width, imageViewToAnimateFollowingPage.frame.size.height); 629 | } else { 630 | imageViewToAnimate.transform = CGAffineTransformMakeScale(1 - (realLocation/self.frame.size.width), 1 - (realLocation/self.frame.size.width)); 631 | } 632 | 633 | if (imageViewToAnimateFollowingPage && (self.arrayOfAnimations.count >= page + 2)) { 634 | if ([self.arrayOfAnimations[page + 1] intValue] == 0) { 635 | if (self.scrollOffset + 20 > self.frame.size.width) { 636 | imageViewToAnimateFollowingPage.frame = CGRectMake(imageViewToAnimateFollowingPage.frame.origin.x, self.deviceHeight/2 - self.deviceHeight/3 + 40, imageViewToAnimateFollowingPage.frame.size.width, imageViewToAnimateFollowingPage.frame.size.height); 637 | } else { 638 | imageViewToAnimateFollowingPage.frame = CGRectMake(imageViewToAnimateFollowingPage.frame.origin.x, - self.frame.size.width + self.scrollOffset * 1.5, imageViewToAnimateFollowingPage.frame.size.width, imageViewToAnimateFollowingPage.frame.size.height); 639 | } 640 | } else if ([self.arrayOfAnimations[page + 1] intValue] == 1) { 641 | if (self.scrollOffset > self.frame.size.width) { 642 | imageViewToAnimateFollowingPage.transform = CGAffineTransformMakeScale(1 - (realLocation/self.frame.size.width), 1 - (realLocation/self.frame.size.width)); 643 | imageViewToAnimateFollowingPage.frame = CGRectMake((self.deviceWidth - (self.deviceWidth/3))/2 + realLocation/1.5, imageViewToAnimateFollowingPage.frame.origin.y, imageViewToAnimateFollowingPage.frame.size.width, imageViewToAnimateFollowingPage.frame.size.height); 644 | } else { 645 | imageViewToAnimateFollowingPage.transform = CGAffineTransformMakeScale(realLocation/self.frame.size.width, realLocation/self.frame.size.width); 646 | } 647 | } 648 | } 649 | } 650 | } 651 | 652 | if ((int)(page + 2) == (int)self.arrayWithSlides.count) { 653 | self.pageControl.alpha = (self.frame.size.width - self.scrollOffset)/self.frame.size.width; 654 | self.buttonDismiss.alpha = self.scrollOffset/self.frame.size.width; 655 | } 656 | } 657 | 658 | - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView 659 | { 660 | self.scrollOffset = 0; 661 | 662 | CGFloat pageWidth = CGRectGetWidth(self.frame); 663 | NSUInteger page = floor((self.contentOffset.x - pageWidth / 2) / pageWidth) + 1; 664 | self.pageControl.currentPage = page; 665 | 666 | if (self.pageToPerformFirstAnimation == (int)page && ![self.viewMain.subviews containsObject:self.imageViewThatMoves]) { 667 | [self.viewMain addSubview:self.imageViewThatMoves]; 668 | self.imageViewThatMoves.alpha = 0; 669 | 670 | self.imageViewThatMoves.transform = CGAffineTransformMakeScale(0, 0); 671 | [UIView animateWithDuration:0.3 animations:^{ 672 | self.imageViewThatMoves.alpha = 1; 673 | self.imageViewThatMoves.transform = CGAffineTransformMakeScale(1.2, 1.2); 674 | } completion:^(BOOL finished) { 675 | [UIView animateWithDuration:0.2 animations:^{ 676 | self.imageViewThatMoves.transform = CGAffineTransformMakeScale(1, 1); 677 | }]; 678 | }]; 679 | } 680 | 681 | if ((int)page < self.pageToPerformFirstAnimation) { 682 | self.imageViewThatMoves.transform = CGAffineTransformMakeScale(1, 1); 683 | [UIView animateWithDuration:0.2 animations:^{ 684 | self.imageViewThatMoves.transform = CGAffineTransformMakeScale(1.1, 1.1); 685 | } completion:^(BOOL finished) { 686 | [UIView animateWithDuration:1.4 animations:^{ 687 | self.imageViewThatMoves.transform = CGAffineTransformMakeScale(0, 0); 688 | self.imageViewThatMoves.alpha = 0; 689 | } completion:^(BOOL finished) { 690 | [self.imageViewThatMoves removeFromSuperview]; 691 | }]; 692 | }]; 693 | } 694 | 695 | [self loadScrollViewWithPage:page - 1]; 696 | [self loadScrollViewWithPage:page]; 697 | [self loadScrollViewWithPage:page + 1]; 698 | [self loadScrollViewWithPage:page + 2]; 699 | [self loadScrollViewWithPage:page + 3]; 700 | 701 | if ([self.firstPageSecond intValue] == (int)page) { 702 | [self.staticImageView removeFromSuperview]; 703 | } else if ([self.firstPageFirst intValue] == (int)page) { 704 | [self.mainView addSubview:self.staticImageView]; 705 | self.staticImageView.alpha = 0; 706 | 707 | if (self.animationStaticImage == 0) { 708 | self.staticImageView.transform = CGAffineTransformMakeScale(0, 0); 709 | [UIView animateWithDuration:0.3 animations:^{ 710 | self.staticImageView.alpha = 1; 711 | self.staticImageView.transform = CGAffineTransformMakeScale(1.2, 1.2); 712 | } completion:^(BOOL finished) { 713 | [UIView animateWithDuration:0.2 animations:^{ 714 | self.staticImageView.transform = CGAffineTransformMakeScale(1, 1); 715 | }]; 716 | }]; 717 | } else if (self.animationStaticImage == 1) { 718 | self.staticImageView.transform = CGAffineTransformMakeTranslation(10, -500); 719 | [UIView animateWithDuration:0.3 animations:^{ 720 | self.staticImageView.alpha = 1; 721 | self.staticImageView.transform = CGAffineTransformMakeTranslation(0, 20); 722 | } completion:^(BOOL finished) { 723 | [UIView animateWithDuration:0.2 animations:^{ 724 | self.staticImageView.transform = CGAffineTransformMakeTranslation(0, 0); 725 | }]; 726 | }]; 727 | } else { 728 | self.staticImageView.alpha = 1; 729 | } 730 | 731 | if ([self.mainView.subviews containsObject:self.staticImageViewSecond]) { 732 | [self.staticImageViewSecond removeFromSuperview]; 733 | } 734 | } 735 | 736 | if ([self.secondPageFirst intValue] == (int)page && ![self.mainView.subviews containsObject:self.staticImageViewSecond]) { 737 | [self.mainView addSubview:self.staticImageViewSecond]; 738 | self.staticImageViewSecond.alpha = 0; 739 | 740 | if (self.animationStaticImageSecond == 0) { 741 | self.staticImageViewSecond.transform = CGAffineTransformMakeScale(0, 0); 742 | [UIView animateWithDuration:0.3 animations:^{ 743 | self.staticImageViewSecond.alpha = 1; 744 | self.staticImageViewSecond.transform = CGAffineTransformMakeScale(1.2, 1.2); 745 | } completion:^(BOOL finished) { 746 | [UIView animateWithDuration:0.2 animations:^{ 747 | self.staticImageViewSecond.transform = CGAffineTransformMakeScale(1, 1); 748 | }]; 749 | }]; 750 | } else if (self.animationStaticImageSecond == 1) { 751 | self.staticImageViewSecond.transform = CGAffineTransformMakeTranslation(10, -500); 752 | [UIView animateWithDuration:0.3 animations:^{ 753 | self.staticImageViewSecond.alpha = 1; 754 | self.staticImageViewSecond.transform = CGAffineTransformMakeTranslation(0, 20); 755 | } completion:^(BOOL finished) { 756 | [UIView animateWithDuration:0.2 animations:^{ 757 | self.staticImageViewSecond.transform = CGAffineTransformMakeTranslation(0, 0); 758 | }]; 759 | }]; 760 | } else { 761 | self.staticImageViewSecond.alpha = 1; 762 | } 763 | } else if ([self.secondPageSecond intValue] == (int)page) { 764 | [self.staticImageViewSecond removeFromSuperview]; 765 | } 766 | } 767 | 768 | #pragma mark - Helper methods 769 | 770 | - (void)getPageControlColorFromBackgroundColor:(UIColor *)backgroundColor 771 | { 772 | CGFloat hue = 0; 773 | CGFloat saturation = 0; 774 | CGFloat brightness = 0; 775 | CGFloat alpha = 0; 776 | [backgroundColor getHue:&hue saturation:&saturation brightness:&brightness alpha:&alpha]; 777 | self.pageControl.currentPageIndicatorTintColor = [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:alpha-0.3]; 778 | self.pageControl.pageIndicatorTintColor = [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:alpha-0.5]; 779 | } 780 | 781 | @end 782 | -------------------------------------------------------------------------------- /RGDynamicOnboard.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "RGDynamicOnboard" 3 | s.version = "0.1" 4 | s.summary = "Custom slideshows made easy." 5 | s.homepage = "https://github.com/RamonGilabert/RGDynamicOnboard" 6 | s.license = { 7 | :type => 'MIT', 8 | :file => 'Resources/LICENSE.md' 9 | } 10 | s.author = { "Ramon Gilabert" => "contact@ramongilabert.com" } 11 | s.social_media_url = "http://twitter.com/RamonGilabert" 12 | s.platform = :ios, '8.0' 13 | s.source = { 14 | :git => 'https://github.com/RamonGilabert/RGDynamicOnboard.git', 15 | :tag => s.version.to_s 16 | } 17 | s.source_files = '*.{h,m}' 18 | s.frameworks = 'Foundation' 19 | s.requires_arc = true 20 | 21 | end 22 | -------------------------------------------------------------------------------- /Resources/AppFirst.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonGilabert/RGDynamicOnboard/abb8ad876da3c997da5fb73e905b152ba667464c/Resources/AppFirst.gif -------------------------------------------------------------------------------- /Resources/AppSecond.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonGilabert/RGDynamicOnboard/abb8ad876da3c997da5fb73e905b152ba667464c/Resources/AppSecond.gif -------------------------------------------------------------------------------- /Resources/Header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonGilabert/RGDynamicOnboard/abb8ad876da3c997da5fb73e905b152ba667464c/Resources/Header.png -------------------------------------------------------------------------------- /Resources/LICENSE.md: -------------------------------------------------------------------------------- 1 | Licensed under the **MIT** license 2 | 3 | > Copyright (c) 2015 Ramon Gilabert 4 | > 5 | > Permission is hereby granted, free of charge, to any person obtaining 6 | > a copy of this software and associated documentation files (the 7 | > "Software"), to deal in the Software without restriction, including 8 | > without limitation the rights to use, copy, modify, merge, publish, 9 | > distribute, sublicense, and/or sell copies of the Software, and to 10 | > permit persons to whom the Software is furnished to do so, subject to 11 | > the following conditions: 12 | > 13 | > The above copyright notice and this permission notice shall be 14 | > included in all copies or substantial portions of the Software. 15 | > 16 | > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | > EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | > MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | > IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | > CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | > TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | > SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /Resources/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonGilabert/RGDynamicOnboard/abb8ad876da3c997da5fb73e905b152ba667464c/Resources/background.png --------------------------------------------------------------------------------