├── Charging Animation.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── Scientist.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── Scientist.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── Charging Animation.xcscheme │ └── xcschememanagement.plist ├── Charging Animation ├── AppDelegate.swift ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── ChargerController.swift ├── GradientBackgroundView.swift ├── Info.plist ├── RingView.swift ├── TitilliumWeb-Light.ttf ├── Utils.swift ├── WaterWave.swift ├── ic_chevron_right.png └── oldrepublic.ttf ├── README.md ├── ios_charging_animation.mov ├── screenshot.gif └── screenshot.png /Charging Animation.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0724958421C7850F0059FC23 /* RingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0724958321C7850F0059FC23 /* RingView.swift */; }; 11 | 072A13A91E58EBB70029FC30 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 072A13A81E58EBB70029FC30 /* AppDelegate.swift */; }; 12 | 072A13AB1E58EBB70029FC30 /* ChargerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 072A13AA1E58EBB70029FC30 /* ChargerController.swift */; }; 13 | 072A13AE1E58EBB70029FC30 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 072A13AC1E58EBB70029FC30 /* Main.storyboard */; }; 14 | 072A13B01E58EBB70029FC30 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 072A13AF1E58EBB70029FC30 /* Assets.xcassets */; }; 15 | 072A13B31E58EBB70029FC30 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 072A13B11E58EBB70029FC30 /* LaunchScreen.storyboard */; }; 16 | 072A13BB1E58EE440029FC30 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 072A13BA1E58EE440029FC30 /* Utils.swift */; }; 17 | 073FCCF81E6CE3E5002A035C /* TitilliumWeb-Light.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 073FCCF71E6CE3E5002A035C /* TitilliumWeb-Light.ttf */; }; 18 | 07996EE920C1FD6900FB3488 /* GradientBackgroundView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07996EE820C1FD6900FB3488 /* GradientBackgroundView.swift */; }; 19 | 079FD74A1E64F9A500DC5221 /* WaterWave.swift in Sources */ = {isa = PBXBuildFile; fileRef = 079FD7491E64F9A500DC5221 /* WaterWave.swift */; }; 20 | 079FD7501E65DB0B00DC5221 /* oldrepublic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 079FD74F1E65D92B00DC5221 /* oldrepublic.ttf */; }; 21 | 07FB60F01E59A3CE0084A6DC /* ic_chevron_right.png in Resources */ = {isa = PBXBuildFile; fileRef = 07FB60EF1E59A3CE0084A6DC /* ic_chevron_right.png */; }; 22 | /* End PBXBuildFile section */ 23 | 24 | /* Begin PBXFileReference section */ 25 | 0724958321C7850F0059FC23 /* RingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RingView.swift; sourceTree = ""; }; 26 | 072A13A51E58EBB70029FC30 /* Charging Animation.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Charging Animation.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 27 | 072A13A81E58EBB70029FC30 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 28 | 072A13AA1E58EBB70029FC30 /* ChargerController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChargerController.swift; sourceTree = ""; }; 29 | 072A13AD1E58EBB70029FC30 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 30 | 072A13AF1E58EBB70029FC30 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 31 | 072A13B21E58EBB70029FC30 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 32 | 072A13B41E58EBB70029FC30 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 33 | 072A13BA1E58EE440029FC30 /* Utils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Utils.swift; sourceTree = ""; }; 34 | 073FCCF71E6CE3E5002A035C /* TitilliumWeb-Light.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "TitilliumWeb-Light.ttf"; sourceTree = ""; }; 35 | 07996EE820C1FD6900FB3488 /* GradientBackgroundView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GradientBackgroundView.swift; sourceTree = ""; }; 36 | 079FD7491E64F9A500DC5221 /* WaterWave.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WaterWave.swift; sourceTree = ""; }; 37 | 079FD74F1E65D92B00DC5221 /* oldrepublic.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = oldrepublic.ttf; sourceTree = ""; }; 38 | 07FB60EF1E59A3CE0084A6DC /* ic_chevron_right.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = ic_chevron_right.png; sourceTree = ""; }; 39 | /* End PBXFileReference section */ 40 | 41 | /* Begin PBXFrameworksBuildPhase section */ 42 | 072A13A21E58EBB60029FC30 /* Frameworks */ = { 43 | isa = PBXFrameworksBuildPhase; 44 | buildActionMask = 2147483647; 45 | files = ( 46 | ); 47 | runOnlyForDeploymentPostprocessing = 0; 48 | }; 49 | /* End PBXFrameworksBuildPhase section */ 50 | 51 | /* Begin PBXGroup section */ 52 | 072A139C1E58EBB60029FC30 = { 53 | isa = PBXGroup; 54 | children = ( 55 | 072A13A71E58EBB70029FC30 /* Charging Animation */, 56 | 072A13A61E58EBB70029FC30 /* Products */, 57 | ); 58 | sourceTree = ""; 59 | }; 60 | 072A13A61E58EBB70029FC30 /* Products */ = { 61 | isa = PBXGroup; 62 | children = ( 63 | 072A13A51E58EBB70029FC30 /* Charging Animation.app */, 64 | ); 65 | name = Products; 66 | sourceTree = ""; 67 | }; 68 | 072A13A71E58EBB70029FC30 /* Charging Animation */ = { 69 | isa = PBXGroup; 70 | children = ( 71 | 0736BB001E6B76EF00FA5298 /* classes */, 72 | 0736BAFF1E6B76E300FA5298 /* fonts */, 73 | 0736BAFE1E6B76DA00FA5298 /* images */, 74 | 072A13AF1E58EBB70029FC30 /* Assets.xcassets */, 75 | 072A13AC1E58EBB70029FC30 /* Main.storyboard */, 76 | 072A13B11E58EBB70029FC30 /* LaunchScreen.storyboard */, 77 | 072A13B41E58EBB70029FC30 /* Info.plist */, 78 | ); 79 | path = "Charging Animation"; 80 | sourceTree = ""; 81 | }; 82 | 0736BAFE1E6B76DA00FA5298 /* images */ = { 83 | isa = PBXGroup; 84 | children = ( 85 | 07FB60EF1E59A3CE0084A6DC /* ic_chevron_right.png */, 86 | ); 87 | name = images; 88 | sourceTree = ""; 89 | }; 90 | 0736BAFF1E6B76E300FA5298 /* fonts */ = { 91 | isa = PBXGroup; 92 | children = ( 93 | 079FD74F1E65D92B00DC5221 /* oldrepublic.ttf */, 94 | 073FCCF71E6CE3E5002A035C /* TitilliumWeb-Light.ttf */, 95 | ); 96 | name = fonts; 97 | sourceTree = ""; 98 | }; 99 | 0736BB001E6B76EF00FA5298 /* classes */ = { 100 | isa = PBXGroup; 101 | children = ( 102 | 072A13A81E58EBB70029FC30 /* AppDelegate.swift */, 103 | 072A13AA1E58EBB70029FC30 /* ChargerController.swift */, 104 | 072A13BA1E58EE440029FC30 /* Utils.swift */, 105 | 079FD7491E64F9A500DC5221 /* WaterWave.swift */, 106 | 07996EE820C1FD6900FB3488 /* GradientBackgroundView.swift */, 107 | 0724958321C7850F0059FC23 /* RingView.swift */, 108 | ); 109 | name = classes; 110 | sourceTree = ""; 111 | }; 112 | /* End PBXGroup section */ 113 | 114 | /* Begin PBXNativeTarget section */ 115 | 072A13A41E58EBB60029FC30 /* Charging Animation */ = { 116 | isa = PBXNativeTarget; 117 | buildConfigurationList = 072A13B71E58EBB70029FC30 /* Build configuration list for PBXNativeTarget "Charging Animation" */; 118 | buildPhases = ( 119 | 072A13A11E58EBB60029FC30 /* Sources */, 120 | 072A13A21E58EBB60029FC30 /* Frameworks */, 121 | 072A13A31E58EBB60029FC30 /* Resources */, 122 | ); 123 | buildRules = ( 124 | ); 125 | dependencies = ( 126 | ); 127 | name = "Charging Animation"; 128 | productName = "Charging Animation"; 129 | productReference = 072A13A51E58EBB70029FC30 /* Charging Animation.app */; 130 | productType = "com.apple.product-type.application"; 131 | }; 132 | /* End PBXNativeTarget section */ 133 | 134 | /* Begin PBXProject section */ 135 | 072A139D1E58EBB60029FC30 /* Project object */ = { 136 | isa = PBXProject; 137 | attributes = { 138 | LastSwiftUpdateCheck = 0820; 139 | LastUpgradeCheck = 0820; 140 | ORGANIZATIONNAME = "Adeyinka Adediji"; 141 | TargetAttributes = { 142 | 072A13A41E58EBB60029FC30 = { 143 | CreatedOnToolsVersion = 8.2.1; 144 | DevelopmentTeam = MDCJGSLNV9; 145 | LastSwiftMigration = 0820; 146 | ProvisioningStyle = Automatic; 147 | }; 148 | }; 149 | }; 150 | buildConfigurationList = 072A13A01E58EBB60029FC30 /* Build configuration list for PBXProject "Charging Animation" */; 151 | compatibilityVersion = "Xcode 3.2"; 152 | developmentRegion = English; 153 | hasScannedForEncodings = 0; 154 | knownRegions = ( 155 | en, 156 | Base, 157 | ); 158 | mainGroup = 072A139C1E58EBB60029FC30; 159 | productRefGroup = 072A13A61E58EBB70029FC30 /* Products */; 160 | projectDirPath = ""; 161 | projectRoot = ""; 162 | targets = ( 163 | 072A13A41E58EBB60029FC30 /* Charging Animation */, 164 | ); 165 | }; 166 | /* End PBXProject section */ 167 | 168 | /* Begin PBXResourcesBuildPhase section */ 169 | 072A13A31E58EBB60029FC30 /* Resources */ = { 170 | isa = PBXResourcesBuildPhase; 171 | buildActionMask = 2147483647; 172 | files = ( 173 | 07FB60F01E59A3CE0084A6DC /* ic_chevron_right.png in Resources */, 174 | 072A13B31E58EBB70029FC30 /* LaunchScreen.storyboard in Resources */, 175 | 079FD7501E65DB0B00DC5221 /* oldrepublic.ttf in Resources */, 176 | 073FCCF81E6CE3E5002A035C /* TitilliumWeb-Light.ttf in Resources */, 177 | 072A13B01E58EBB70029FC30 /* Assets.xcassets in Resources */, 178 | 072A13AE1E58EBB70029FC30 /* Main.storyboard in Resources */, 179 | ); 180 | runOnlyForDeploymentPostprocessing = 0; 181 | }; 182 | /* End PBXResourcesBuildPhase section */ 183 | 184 | /* Begin PBXSourcesBuildPhase section */ 185 | 072A13A11E58EBB60029FC30 /* Sources */ = { 186 | isa = PBXSourcesBuildPhase; 187 | buildActionMask = 2147483647; 188 | files = ( 189 | 079FD74A1E64F9A500DC5221 /* WaterWave.swift in Sources */, 190 | 072A13AB1E58EBB70029FC30 /* ChargerController.swift in Sources */, 191 | 072A13A91E58EBB70029FC30 /* AppDelegate.swift in Sources */, 192 | 0724958421C7850F0059FC23 /* RingView.swift in Sources */, 193 | 072A13BB1E58EE440029FC30 /* Utils.swift in Sources */, 194 | 07996EE920C1FD6900FB3488 /* GradientBackgroundView.swift in Sources */, 195 | ); 196 | runOnlyForDeploymentPostprocessing = 0; 197 | }; 198 | /* End PBXSourcesBuildPhase section */ 199 | 200 | /* Begin PBXVariantGroup section */ 201 | 072A13AC1E58EBB70029FC30 /* Main.storyboard */ = { 202 | isa = PBXVariantGroup; 203 | children = ( 204 | 072A13AD1E58EBB70029FC30 /* Base */, 205 | ); 206 | name = Main.storyboard; 207 | sourceTree = ""; 208 | }; 209 | 072A13B11E58EBB70029FC30 /* LaunchScreen.storyboard */ = { 210 | isa = PBXVariantGroup; 211 | children = ( 212 | 072A13B21E58EBB70029FC30 /* Base */, 213 | ); 214 | name = LaunchScreen.storyboard; 215 | sourceTree = ""; 216 | }; 217 | /* End PBXVariantGroup section */ 218 | 219 | /* Begin XCBuildConfiguration section */ 220 | 072A13B51E58EBB70029FC30 /* Debug */ = { 221 | isa = XCBuildConfiguration; 222 | buildSettings = { 223 | ALWAYS_SEARCH_USER_PATHS = NO; 224 | CLANG_ANALYZER_NONNULL = YES; 225 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 226 | CLANG_CXX_LIBRARY = "libc++"; 227 | CLANG_ENABLE_MODULES = YES; 228 | CLANG_ENABLE_OBJC_ARC = YES; 229 | CLANG_WARN_BOOL_CONVERSION = YES; 230 | CLANG_WARN_CONSTANT_CONVERSION = YES; 231 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 232 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 233 | CLANG_WARN_EMPTY_BODY = YES; 234 | CLANG_WARN_ENUM_CONVERSION = YES; 235 | CLANG_WARN_INFINITE_RECURSION = YES; 236 | CLANG_WARN_INT_CONVERSION = YES; 237 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 238 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 239 | CLANG_WARN_UNREACHABLE_CODE = YES; 240 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 241 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 242 | COPY_PHASE_STRIP = NO; 243 | DEBUG_INFORMATION_FORMAT = dwarf; 244 | ENABLE_STRICT_OBJC_MSGSEND = YES; 245 | ENABLE_TESTABILITY = YES; 246 | GCC_C_LANGUAGE_STANDARD = gnu99; 247 | GCC_DYNAMIC_NO_PIC = NO; 248 | GCC_NO_COMMON_BLOCKS = YES; 249 | GCC_OPTIMIZATION_LEVEL = 0; 250 | GCC_PREPROCESSOR_DEFINITIONS = ( 251 | "DEBUG=1", 252 | "$(inherited)", 253 | ); 254 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 255 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 256 | GCC_WARN_UNDECLARED_SELECTOR = YES; 257 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 258 | GCC_WARN_UNUSED_FUNCTION = YES; 259 | GCC_WARN_UNUSED_VARIABLE = YES; 260 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 261 | MTL_ENABLE_DEBUG_INFO = YES; 262 | ONLY_ACTIVE_ARCH = YES; 263 | SDKROOT = iphoneos; 264 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 265 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 266 | TARGETED_DEVICE_FAMILY = "1,2"; 267 | }; 268 | name = Debug; 269 | }; 270 | 072A13B61E58EBB70029FC30 /* Release */ = { 271 | isa = XCBuildConfiguration; 272 | buildSettings = { 273 | ALWAYS_SEARCH_USER_PATHS = NO; 274 | CLANG_ANALYZER_NONNULL = YES; 275 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 276 | CLANG_CXX_LIBRARY = "libc++"; 277 | CLANG_ENABLE_MODULES = YES; 278 | CLANG_ENABLE_OBJC_ARC = YES; 279 | CLANG_WARN_BOOL_CONVERSION = YES; 280 | CLANG_WARN_CONSTANT_CONVERSION = YES; 281 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 282 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 283 | CLANG_WARN_EMPTY_BODY = YES; 284 | CLANG_WARN_ENUM_CONVERSION = YES; 285 | CLANG_WARN_INFINITE_RECURSION = YES; 286 | CLANG_WARN_INT_CONVERSION = YES; 287 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 288 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 289 | CLANG_WARN_UNREACHABLE_CODE = YES; 290 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 291 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 292 | COPY_PHASE_STRIP = NO; 293 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 294 | ENABLE_NS_ASSERTIONS = NO; 295 | ENABLE_STRICT_OBJC_MSGSEND = YES; 296 | GCC_C_LANGUAGE_STANDARD = gnu99; 297 | GCC_NO_COMMON_BLOCKS = YES; 298 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 299 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 300 | GCC_WARN_UNDECLARED_SELECTOR = YES; 301 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 302 | GCC_WARN_UNUSED_FUNCTION = YES; 303 | GCC_WARN_UNUSED_VARIABLE = YES; 304 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 305 | MTL_ENABLE_DEBUG_INFO = NO; 306 | SDKROOT = iphoneos; 307 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 308 | TARGETED_DEVICE_FAMILY = "1,2"; 309 | VALIDATE_PRODUCT = YES; 310 | }; 311 | name = Release; 312 | }; 313 | 072A13B81E58EBB70029FC30 /* Debug */ = { 314 | isa = XCBuildConfiguration; 315 | buildSettings = { 316 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 317 | CLANG_ENABLE_MODULES = YES; 318 | DEVELOPMENT_TEAM = MDCJGSLNV9; 319 | INFOPLIST_FILE = "Charging Animation/Info.plist"; 320 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 321 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 322 | PRODUCT_BUNDLE_IDENTIFIER = com.tdscientist.charging.animation; 323 | PRODUCT_NAME = "$(TARGET_NAME)"; 324 | SWIFT_OBJC_BRIDGING_HEADER = ""; 325 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 326 | SWIFT_VERSION = 4.2; 327 | TARGETED_DEVICE_FAMILY = "1,2"; 328 | }; 329 | name = Debug; 330 | }; 331 | 072A13B91E58EBB70029FC30 /* Release */ = { 332 | isa = XCBuildConfiguration; 333 | buildSettings = { 334 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 335 | CLANG_ENABLE_MODULES = YES; 336 | DEVELOPMENT_TEAM = MDCJGSLNV9; 337 | INFOPLIST_FILE = "Charging Animation/Info.plist"; 338 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 339 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 340 | PRODUCT_BUNDLE_IDENTIFIER = com.tdscientist.charging.animation; 341 | PRODUCT_NAME = "$(TARGET_NAME)"; 342 | SWIFT_OBJC_BRIDGING_HEADER = ""; 343 | SWIFT_VERSION = 4.2; 344 | TARGETED_DEVICE_FAMILY = "1,2"; 345 | }; 346 | name = Release; 347 | }; 348 | /* End XCBuildConfiguration section */ 349 | 350 | /* Begin XCConfigurationList section */ 351 | 072A13A01E58EBB60029FC30 /* Build configuration list for PBXProject "Charging Animation" */ = { 352 | isa = XCConfigurationList; 353 | buildConfigurations = ( 354 | 072A13B51E58EBB70029FC30 /* Debug */, 355 | 072A13B61E58EBB70029FC30 /* Release */, 356 | ); 357 | defaultConfigurationIsVisible = 0; 358 | defaultConfigurationName = Release; 359 | }; 360 | 072A13B71E58EBB70029FC30 /* Build configuration list for PBXNativeTarget "Charging Animation" */ = { 361 | isa = XCConfigurationList; 362 | buildConfigurations = ( 363 | 072A13B81E58EBB70029FC30 /* Debug */, 364 | 072A13B91E58EBB70029FC30 /* Release */, 365 | ); 366 | defaultConfigurationIsVisible = 0; 367 | defaultConfigurationName = Release; 368 | }; 369 | /* End XCConfigurationList section */ 370 | }; 371 | rootObject = 072A139D1E58EBB60029FC30 /* Project object */; 372 | } 373 | -------------------------------------------------------------------------------- /Charging Animation.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Charging Animation.xcodeproj/project.xcworkspace/xcuserdata/Scientist.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tdscientist/ChargingIndicator/9ff7f722eec8e1b97d2b754d84ec6fc754ef9f15/Charging Animation.xcodeproj/project.xcworkspace/xcuserdata/Scientist.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Charging Animation.xcodeproj/xcuserdata/Scientist.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /Charging Animation.xcodeproj/xcuserdata/Scientist.xcuserdatad/xcschemes/Charging Animation.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /Charging Animation.xcodeproj/xcuserdata/Scientist.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Charging Animation.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 072A13A41E58EBB60029FC30 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Charging Animation/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Charging Animation 4 | // 5 | // Created by Adeyinka Adediji on 18/02/2017. 6 | // Copyright © 2017 Adeyinka Adediji. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /Charging Animation/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /Charging Animation/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Charging Animation/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | TitilliumWeb-Light 15 | 16 | 17 | OldRepublic 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 77 | 86 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | -------------------------------------------------------------------------------- /Charging Animation/ChargerController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ChargerController.swift 3 | // Charging Animation 4 | // 5 | // Created by Adeyinka Adediji on 18/02/2017. 6 | // Copyright © 2017 Adeyinka Adediji. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ChargerController: UIViewController { 12 | var waterWave: WaterWave! 13 | @IBOutlet var chargingFigure: UILabel! 14 | @IBOutlet var chargingLabel: UILabel! 15 | @IBOutlet var estimateFigure: UILabel! 16 | @IBOutlet var estimateLabel: UILabel! 17 | @IBOutlet var slideText: UILabel! 18 | @IBOutlet var slideBar: UIView! 19 | @IBOutlet var waterWaveMother: UIView! 20 | @IBOutlet var backgroundMarginTop: NSLayoutConstraint! 21 | @IBOutlet var backgroundMarginBottom: NSLayoutConstraint! 22 | @IBOutlet var percentageLabelMarginLeft: NSLayoutConstraint! 23 | var flashTimer = Timer() 24 | let flashTimerInterval = Double(0.01) 25 | let flashDelay = Double(2) 26 | var lengthOfTextToColor = 0 27 | let flashTextCharacterCount = 3 28 | let slide_to_speed_up = "slide to speed up" 29 | lazy var slideTextString = NSMutableAttributedString(string: slide_to_speed_up) 30 | 31 | override func viewDidAppear(_ animated: Bool) { 32 | super.viewDidAppear(animated) 33 | backgroundMarginTop.constant = -UIApplication.shared.statusBarFrame.height 34 | backgroundMarginBottom.constant = -UIApplication.shared.statusBarFrame.height 35 | } 36 | 37 | override func viewDidLoad() { 38 | super.viewDidLoad() 39 | UIDevice.current.isBatteryMonitoringEnabled = true 40 | NotificationCenter.default.addObserver(self, selector: #selector(batteryStateDidChange(_:)), name: UIDevice.batteryStateDidChangeNotification, object: nil) 41 | NotificationCenter.default.addObserver(self, selector: #selector(batteryLevelDidChange(_:)), name: UIDevice.batteryLevelDidChangeNotification, object: nil) 42 | waterWave = WaterWave(frame: waterWaveMother.bounds) 43 | waterWaveMother.addSubview(waterWave) 44 | waterWaveMother.mask = chargingFigure 45 | setChargingProgress(percentageProgress: batteryLevelPercent) 46 | slideBar.layer.cornerRadius = slideBar.frame.height / 2 47 | slideText.textColor = slideTextAlphaWhiteColor() 48 | initializeFlashTimer() 49 | } 50 | 51 | // return the current battery level of the device. 52 | // pls, note that iOS simulators always return -1 for battery level. 53 | // use a real device to get real figures. 54 | var batteryLevelPercent: Int { 55 | return UIDevice.current.batteryLevel == -1 ? 89 : Int(UIDevice.current.batteryLevel * 100) 56 | } 57 | 58 | // callback to monitor change in battery state 59 | @objc func batteryStateDidChange(_ a: AnyObject) { 60 | // will be used later 61 | } 62 | 63 | // callback to monitor change in battery level 64 | @objc func batteryLevelDidChange(_ a: AnyObject) { 65 | setChargingProgress(percentageProgress: batteryLevelPercent) 66 | } 67 | 68 | // adjust the waterwave progress(height) 69 | func setChargingProgress(percentageProgress: Int) { 70 | percentageLabelMarginLeft.constant = percentageProgress == 100 ? 0 : -25 71 | chargingLabel.text = percentageProgress >= 100 ? "Charged" : "Charging ..." 72 | estimateFigure.isHidden = percentageProgress >= 100 73 | estimateLabel.isHidden = percentageProgress >= 100 74 | slideBar.isHidden = percentageProgress >= 100 75 | chargingFigure.text = String(describing: percentageProgress) 76 | waterWave.setWavePercentage(CGFloat(percentageProgress)) 77 | } 78 | 79 | // create animation for the "slide to speed up" text 80 | @objc fileprivate func flashSlideText() { 81 | if lengthOfTextToColor <= slideTextString.length - flashTextCharacterCount { 82 | lengthOfTextToColor += 1 83 | 84 | let range = NSMakeRange(lengthOfTextToColor - 1, flashTextCharacterCount) 85 | let textAttribute = [NSAttributedString.Key.font: slideTextFont(), NSAttributedString.Key.foregroundColor: UIColor.white] 86 | slideTextString.addAttributes(textAttribute, range: range) 87 | 88 | let cleanUpRange = NSMakeRange(0, lengthOfTextToColor - 1) 89 | let cleanUpTextAttribute = [NSAttributedString.Key.font: slideTextFont(), NSAttributedString.Key.foregroundColor: slideTextAlphaWhiteColor()] 90 | slideTextString.addAttributes(cleanUpTextAttribute, range: cleanUpRange) 91 | 92 | } else if lengthOfTextToColor == slideTextString.length - 2 { 93 | let range = NSMakeRange(0, slideTextString.length) 94 | let textAttribute = [NSAttributedString.Key.font: slideTextFont(), NSAttributedString.Key.foregroundColor: slideTextAlphaWhiteColor()] 95 | slideTextString.addAttributes(textAttribute, range: range) 96 | 97 | flashTimer.invalidate() 98 | Utils().delay(flashDelay) { 99 | self.lengthOfTextToColor = 0 100 | self.initializeFlashTimer() 101 | } 102 | } 103 | slideText.attributedText = slideTextString 104 | } 105 | 106 | // initialize timer to animate the slide text 107 | fileprivate func initializeFlashTimer() { 108 | flashTimer = Timer.scheduledTimer(timeInterval: flashTimerInterval, target: self, selector: #selector(flashSlideText), userInfo: nil, repeats: true) 109 | } 110 | 111 | fileprivate func slideTextFont() -> UIFont { 112 | return slideText.font 113 | } 114 | 115 | // 50% transparent white UIColor for the slide text animation 116 | fileprivate func slideTextAlphaWhiteColor() -> UIColor { 117 | return UIColor("#ffffff", alpha: 0.5) 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /Charging Animation/GradientBackgroundView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GradientBackgroundView.swift 3 | // Charging Animation 4 | // 5 | // Created by Adeyinka Adediji on 01/06/2018. 6 | // Copyright © 2018 Adeyinka Adediji. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @IBDesignable 12 | class GradientBackgroundView: UIView { 13 | public override init(frame: CGRect) { 14 | super.init(frame: frame) 15 | updateView() 16 | } 17 | 18 | public required init(coder aDecoder: NSCoder) { 19 | super.init(coder: aDecoder)! 20 | updateView() 21 | } 22 | 23 | override func layoutSubviews() { 24 | super.layoutSubviews() 25 | updateView() 26 | } 27 | 28 | override class var layerClass: AnyClass { 29 | return CAGradientLayer.self 30 | } 31 | 32 | private func updateView() { 33 | 34 | if let sublayers = self.layer.sublayers { 35 | for layer in sublayers { 36 | layer.removeFromSuperlayer() 37 | } 38 | } 39 | 40 | let colorLayer = CAGradientLayer() 41 | colorLayer.frame = frame 42 | colorLayer.colors = [UIColor.DARK_TURQUOISE.cgColor, UIColor.BLUE_VIOLET.cgColor] 43 | colorLayer.startPoint = CGPoint(x: 1.0, y: 0.5) 44 | colorLayer.endPoint = CGPoint(x: 0.5, y: 1.0) 45 | 46 | layer.addSublayer(colorLayer) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Charging Animation/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.1 19 | CFBundleVersion 20 | 2 21 | LSRequiresIPhoneOS 22 | 23 | UIAppFonts 24 | 25 | oldrepublic.ttf 26 | TitilliumWeb-Light.ttf 27 | 28 | UILaunchStoryboardName 29 | LaunchScreen 30 | UIMainStoryboardFile 31 | Main 32 | UIRequiredDeviceCapabilities 33 | 34 | armv7 35 | 36 | UIStatusBarStyle 37 | UIStatusBarStyleLightContent 38 | UISupportedInterfaceOrientations 39 | 40 | UIInterfaceOrientationPortrait 41 | UIInterfaceOrientationPortraitUpsideDown 42 | 43 | UISupportedInterfaceOrientations~ipad 44 | 45 | UIInterfaceOrientationPortrait 46 | UIInterfaceOrientationPortraitUpsideDown 47 | 48 | UIViewControllerBasedStatusBarAppearance 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /Charging Animation/RingView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RingView.swift 3 | // Charging Animation 4 | // 5 | // Created by Adeyinka Adediji on 17/12/2018. 6 | // Copyright © 2018 Adeyinka Adediji. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @IBDesignable 12 | class RingView: UIView { 13 | public override init(frame: CGRect) { 14 | super.init(frame: frame) 15 | updateView() 16 | } 17 | 18 | public required init(coder aDecoder: NSCoder) { 19 | super.init(coder: aDecoder)! 20 | updateView() 21 | } 22 | 23 | override func layoutSubviews() { 24 | super.layoutSubviews() 25 | updateView() 26 | } 27 | 28 | override class var layerClass: AnyClass { 29 | return CAGradientLayer.self 30 | } 31 | 32 | fileprivate func updateView() { 33 | if let sublayers = self.layer.sublayers { 34 | for layer in sublayers { 35 | layer.removeFromSuperlayer() 36 | } 37 | } 38 | 39 | let width = frame.width 40 | 41 | let slideRing = UIView(frame: CGRect(x: 0, y: 0, width: width, height: width)) 42 | slideRing.layer.borderWidth = 2.5 43 | slideRing.layer.borderColor = UIColor("#ffffff", alpha: 0.3).cgColor 44 | slideRing.layer.cornerRadius = slideRing.frame.width / 2 45 | addSubview(slideRing) 46 | 47 | let slideRingImageWidth = width - 6 48 | let slideRingImage = UIImageView(frame: CGRect(x: (width - slideRingImageWidth) / 2, y: (width - slideRingImageWidth) / 2, width: slideRingImageWidth, height: slideRingImageWidth)) 49 | slideRingImage.image = UIImage(named: "ic_chevron_right.png") 50 | slideRingImage.tint(color: UIColor("#ffffff", alpha: 0.5)) 51 | addSubview(slideRingImage) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Charging Animation/TitilliumWeb-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tdscientist/ChargingIndicator/9ff7f722eec8e1b97d2b754d84ec6fc754ef9f15/Charging Animation/TitilliumWeb-Light.ttf -------------------------------------------------------------------------------- /Charging Animation/Utils.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Utils.swift 3 | // Charging Animation 4 | // 5 | // Created by Adeyinka Adediji on 18/02/2017. 6 | // Copyright © 2017 Adeyinka Adediji. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension UIImageView { 12 | func tint(color: UIColor) { 13 | self.image = self.image!.withRenderingMode(UIImage.RenderingMode.alwaysTemplate) 14 | self.tintColor = color 15 | } 16 | } 17 | 18 | extension UIColor { 19 | static let BLUE_VIOLET = UIColor("#9F36F8") 20 | static let DARK_TURQUOISE = UIColor("#15D1DE") 21 | 22 | convenience init(_ hex: String) { 23 | var cString = hex.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines).uppercased() 24 | 25 | if cString.hasPrefix("#") { 26 | cString = String(cString.suffix(from: cString.index(cString.startIndex, offsetBy: 1))) 27 | } 28 | 29 | var rgbValue: UInt32 = 0 30 | Scanner(string: cString).scanHexInt32(&rgbValue) 31 | 32 | let components = ( 33 | R: CGFloat((rgbValue & 0xFF0000) >> 16) / 255, 34 | G: CGFloat((rgbValue & 0x00FF00) >> 8) / 255, 35 | B: CGFloat(rgbValue & 0x0000FF) / 255 36 | ) 37 | self.init(red: components.R, green: components.G, blue: components.B, alpha: 1) 38 | } 39 | 40 | convenience init(_ hex: String, alpha: CGFloat) { 41 | var cString = hex.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines).uppercased() 42 | 43 | if cString.hasPrefix("#") { 44 | cString = String(cString.suffix(from: cString.index(cString.startIndex, offsetBy: 1))) 45 | } 46 | 47 | var rgbValue: UInt32 = 0 48 | Scanner(string: cString).scanHexInt32(&rgbValue) 49 | 50 | let components = ( 51 | R: CGFloat((rgbValue & 0xFF0000) >> 16) / 255, 52 | G: CGFloat((rgbValue & 0x00FF00) >> 8) / 255, 53 | B: CGFloat(rgbValue & 0x0000FF) / 255 54 | ) 55 | self.init(red: components.R, green: components.G, blue: components.B, alpha: alpha) 56 | } 57 | } 58 | 59 | class Utils { 60 | func delay(_ delay: Double, closure: @escaping () -> ()) { 61 | DispatchQueue.main.asyncAfter( 62 | deadline: DispatchTime.now() + Double(Int64(delay * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC), 63 | execute: closure 64 | ) 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Charging Animation/WaterWave.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WaterWave.swift 3 | // Charging Animation 4 | // 5 | // Created by Adeyinka Adediji on 28/02/2017. 6 | // Copyright © 2017 Adeyinka Adediji. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class WaterWave: UIView { 12 | lazy var waveDisplaylink = CADisplayLink() 13 | lazy var waveLayer = CAShapeLayer() 14 | fileprivate var waveWidth: CGFloat! 15 | fileprivate var waveHeight: CGFloat! 16 | private var waveAmplitude: CGFloat = 8 17 | fileprivate var waveSpeed = CGFloat(0.05) 18 | private var offsetX: CGFloat = 0 19 | 20 | required init?(coder aDecoder: NSCoder) { 21 | super.init(coder: aDecoder) 22 | } 23 | 24 | override init(frame: CGRect) { 25 | super.init(frame: frame) 26 | waveWidth = 2 * CGFloat(Double.pi) / bounds.size.width 27 | waveHeight = bounds.size.height * 0.5 28 | waveLayer.fillColor = UIColor.white.cgColor 29 | layer.addSublayer(waveLayer) 30 | waveDisplaylink = CADisplayLink(target: self, selector: #selector(getCurrentWave)) 31 | waveDisplaylink.add(to: RunLoop.current, forMode: RunLoop.Mode.common) 32 | } 33 | 34 | deinit { 35 | waveDisplaylink.invalidate() 36 | } 37 | 38 | @objc fileprivate func getCurrentWave() { 39 | offsetX += waveSpeed 40 | setCurrentStatusWavePath() 41 | } 42 | 43 | fileprivate func setCurrentStatusWavePath() { 44 | let path = CGMutablePath() 45 | var y = bounds.size.width / 2 46 | path.move(to: CGPoint(x: 0, y: y)) 47 | for i in 0...Int(bounds.size.width) { 48 | y = waveAmplitude * sin(waveWidth * CGFloat(i) + offsetX) + waveHeight 49 | path.addLine(to: CGPoint(x: CGFloat(i), y: y)) 50 | } 51 | 52 | path.addLine(to: CGPoint(x: bounds.size.width, y: bounds.size.height)) 53 | path.addLine(to: CGPoint(x: 0, y: bounds.size.height)) 54 | path.closeSubpath() 55 | waveLayer.path = path 56 | } 57 | 58 | func setWavePercentage(_ percentage: CGFloat) { 59 | waveHeight = bounds.size.height * (1 - (percentage / 100)) 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Charging Animation/ic_chevron_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tdscientist/ChargingIndicator/9ff7f722eec8e1b97d2b754d84ec6fc754ef9f15/Charging Animation/ic_chevron_right.png -------------------------------------------------------------------------------- /Charging Animation/oldrepublic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tdscientist/ChargingIndicator/9ff7f722eec8e1b97d2b754d84ec6fc754ef9f15/Charging Animation/oldrepublic.ttf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## ChargingIndicator ## 2 | 3 | *iOS charging indicator inspired by [Charging Animation](https://ios.uplabs.com/posts/charging-animation)* 4 | 5 | 6 | 7 | [](https://youtu.be/9UFvToBWTOA) 8 | 9 | click image to watch video 10 | 11 |
12 | 13 | #### Requirements #### 14 | ---- 15 | 16 | * xCode 10.1 17 | * Siwft 4.2 18 | * iPhone or iPad, running on iOS 9 and above 19 | 20 | 21 |
22 | 23 | #### Todo #### 24 | ---- 25 | 26 | - [x] iPhone support 27 | - [x] iPad support 28 | - [x] use autoLayout 29 | - [ ] real estimated charging time 30 | - [ ] convert to a library 31 |
32 | 33 |
34 | 35 | #### Note #### 36 | ---- 37 | iOS simulator always return -1 for battery level. Run the project on a real device to get real figures 38 | 39 |
40 | 41 | #### License #### 42 | ---- 43 | ``` 44 | Copyright 2018 Adeyinka Adediji 45 | 46 | Licensed under the Apache License, Version 2.0 (the "License"); 47 | you may not use this file except in compliance with the License. 48 | You may obtain a copy of the License at 49 | 50 | http://www.apache.org/licenses/LICENSE-2.0 51 | 52 | Unless required by applicable law or agreed to in writing, software 53 | distributed under the License is distributed on an "AS IS" BASIS, 54 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 55 | See the License for the specific language governing permissions and 56 | limitations under the License. 57 | ``` 58 | 59 |
60 | 61 | #### Contributions & Bug Reporting #### 62 | --- 63 | tdscientist@gmail.com 64 | 65 | 66 |
67 | 68 | #### Credits #### 69 | --- 70 | * [WaterWave](https://github.com/WSmalan/iOS-Swift-waterWave) 71 | -------------------------------------------------------------------------------- /ios_charging_animation.mov: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tdscientist/ChargingIndicator/9ff7f722eec8e1b97d2b754d84ec6fc754ef9f15/ios_charging_animation.mov -------------------------------------------------------------------------------- /screenshot.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tdscientist/ChargingIndicator/9ff7f722eec8e1b97d2b754d84ec6fc754ef9f15/screenshot.gif -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tdscientist/ChargingIndicator/9ff7f722eec8e1b97d2b754d84ec6fc754ef9f15/screenshot.png --------------------------------------------------------------------------------