├── HWLoadingAnimation-OC ├── HWLoadingAnimation.gif ├── HWLoadingAnimation_OC.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcuserdata │ │ │ ├── HenryCheng.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ │ │ └── chenghongwei.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ ├── HenryCheng.xcuserdatad │ │ └── xcschemes │ │ │ ├── HWLoadingAnimation_OC.xcscheme │ │ │ └── xcschememanagement.plist │ │ └── chenghongwei.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ ├── HWLoadingAnimation_OC.xcscheme │ │ └── xcschememanagement.plist ├── HWLoadingAnimation_OC │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── HWView │ │ ├── AnimatiomView.h │ │ ├── AnimatiomView.m │ │ └── HWLayer │ │ │ ├── CircleLayer.h │ │ │ ├── CircleLayer.m │ │ │ ├── RectangleLayer.h │ │ │ ├── RectangleLayer.m │ │ │ ├── TriangleLayer.h │ │ │ ├── TriangleLayer.m │ │ │ ├── WaveLayer.h │ │ │ └── WaveLayer.m │ ├── Info.plist │ ├── Others │ │ ├── UIColor+Hex.h │ │ └── UIColor+Hex.m │ ├── ViewController.h │ ├── ViewController.m │ └── main.m ├── HWLoadingAnimation_OCTests │ ├── HWLoadingAnimation_OCTests.m │ └── Info.plist └── HWLoadingAnimation_OCUITests │ ├── HWLoadingAnimation_OCUITests.m │ └── Info.plist ├── HWLoadingAnimation-Swift ├── HWLoadingAnimation.gif ├── HWLoadingAnimation.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcuserdata │ │ │ ├── HenryCheng.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ │ │ └── chenghongwei.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ ├── HenryCheng.xcuserdatad │ │ ├── xcdebugger │ │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ │ ├── HWLoadingAnimation.xcscheme │ │ │ └── xcschememanagement.plist │ │ └── chenghongwei.xcuserdatad │ │ └── xcschemes │ │ ├── HWLoadingAnimation.xcscheme │ │ └── xcschememanagement.plist ├── HWLoadingAnimation │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── HWView │ │ ├── AnimationView.swift │ │ └── Layer │ │ │ ├── CircleLayer.swift │ │ │ ├── RectangleLayer.swift │ │ │ ├── TriangleLayer.swift │ │ │ └── WaveLayer.swift │ ├── Info.plist │ ├── Others │ │ └── Extension.swift │ └── ViewController.swift ├── HWLoadingAnimationTests │ ├── HWLoadingAnimationTests.swift │ └── Info.plist └── HWLoadingAnimationUITests │ ├── HWLoadingAnimationUITests.swift │ └── Info.plist └── README.md /HWLoadingAnimation-OC/HWLoadingAnimation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/loveway/HWLoadingAnimation/059dce17cfe534f839fbafd8f6f7ef600794b832/HWLoadingAnimation-OC/HWLoadingAnimation.gif -------------------------------------------------------------------------------- /HWLoadingAnimation-OC/HWLoadingAnimation_OC.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 215C04791D0EFF2F00B2F364 /* TriangleLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 215C04781D0EFF2F00B2F364 /* TriangleLayer.m */; }; 11 | 215C047C1D0F0B9400B2F364 /* RectangleLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 215C047B1D0F0B9400B2F364 /* RectangleLayer.m */; }; 12 | 215C047F1D0F0FB500B2F364 /* WaveLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 215C047E1D0F0FB500B2F364 /* WaveLayer.m */; }; 13 | 21F4EB061D0EF049009380CD /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 21F4EB051D0EF049009380CD /* main.m */; }; 14 | 21F4EB091D0EF049009380CD /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 21F4EB081D0EF049009380CD /* AppDelegate.m */; }; 15 | 21F4EB0C1D0EF049009380CD /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 21F4EB0B1D0EF049009380CD /* ViewController.m */; }; 16 | 21F4EB0F1D0EF049009380CD /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 21F4EB0D1D0EF049009380CD /* Main.storyboard */; }; 17 | 21F4EB111D0EF049009380CD /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 21F4EB101D0EF049009380CD /* Assets.xcassets */; }; 18 | 21F4EB141D0EF049009380CD /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 21F4EB121D0EF049009380CD /* LaunchScreen.storyboard */; }; 19 | 21F4EB1F1D0EF049009380CD /* HWLoadingAnimation_OCTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 21F4EB1E1D0EF049009380CD /* HWLoadingAnimation_OCTests.m */; }; 20 | 21F4EB2A1D0EF049009380CD /* HWLoadingAnimation_OCUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 21F4EB291D0EF049009380CD /* HWLoadingAnimation_OCUITests.m */; }; 21 | 21F4EB3A1D0EF08A009380CD /* UIColor+Hex.m in Sources */ = {isa = PBXBuildFile; fileRef = 21F4EB391D0EF08A009380CD /* UIColor+Hex.m */; }; 22 | 21F4EB3E1D0EF1B1009380CD /* AnimatiomView.m in Sources */ = {isa = PBXBuildFile; fileRef = 21F4EB3D1D0EF1B1009380CD /* AnimatiomView.m */; }; 23 | 21F4EB421D0EF216009380CD /* CircleLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 21F4EB411D0EF216009380CD /* CircleLayer.m */; }; 24 | /* End PBXBuildFile section */ 25 | 26 | /* Begin PBXContainerItemProxy section */ 27 | 21F4EB1B1D0EF049009380CD /* PBXContainerItemProxy */ = { 28 | isa = PBXContainerItemProxy; 29 | containerPortal = 21F4EAF91D0EF049009380CD /* Project object */; 30 | proxyType = 1; 31 | remoteGlobalIDString = 21F4EB001D0EF049009380CD; 32 | remoteInfo = HWLoadingAnimation_OC; 33 | }; 34 | 21F4EB261D0EF049009380CD /* PBXContainerItemProxy */ = { 35 | isa = PBXContainerItemProxy; 36 | containerPortal = 21F4EAF91D0EF049009380CD /* Project object */; 37 | proxyType = 1; 38 | remoteGlobalIDString = 21F4EB001D0EF049009380CD; 39 | remoteInfo = HWLoadingAnimation_OC; 40 | }; 41 | /* End PBXContainerItemProxy section */ 42 | 43 | /* Begin PBXFileReference section */ 44 | 215C04771D0EFF2F00B2F364 /* TriangleLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TriangleLayer.h; sourceTree = ""; }; 45 | 215C04781D0EFF2F00B2F364 /* TriangleLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TriangleLayer.m; sourceTree = ""; }; 46 | 215C047A1D0F0B9400B2F364 /* RectangleLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RectangleLayer.h; sourceTree = ""; }; 47 | 215C047B1D0F0B9400B2F364 /* RectangleLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RectangleLayer.m; sourceTree = ""; }; 48 | 215C047D1D0F0FB500B2F364 /* WaveLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WaveLayer.h; sourceTree = ""; }; 49 | 215C047E1D0F0FB500B2F364 /* WaveLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WaveLayer.m; sourceTree = ""; }; 50 | 21F4EB011D0EF049009380CD /* HWLoadingAnimation_OC.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HWLoadingAnimation_OC.app; sourceTree = BUILT_PRODUCTS_DIR; }; 51 | 21F4EB051D0EF049009380CD /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 52 | 21F4EB071D0EF049009380CD /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 53 | 21F4EB081D0EF049009380CD /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 54 | 21F4EB0A1D0EF049009380CD /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 55 | 21F4EB0B1D0EF049009380CD /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 56 | 21F4EB0E1D0EF049009380CD /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 57 | 21F4EB101D0EF049009380CD /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 58 | 21F4EB131D0EF049009380CD /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 59 | 21F4EB151D0EF049009380CD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 60 | 21F4EB1A1D0EF049009380CD /* HWLoadingAnimation_OCTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HWLoadingAnimation_OCTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 61 | 21F4EB1E1D0EF049009380CD /* HWLoadingAnimation_OCTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HWLoadingAnimation_OCTests.m; sourceTree = ""; }; 62 | 21F4EB201D0EF049009380CD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 63 | 21F4EB251D0EF049009380CD /* HWLoadingAnimation_OCUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HWLoadingAnimation_OCUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 64 | 21F4EB291D0EF049009380CD /* HWLoadingAnimation_OCUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HWLoadingAnimation_OCUITests.m; sourceTree = ""; }; 65 | 21F4EB2B1D0EF049009380CD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 66 | 21F4EB381D0EF08A009380CD /* UIColor+Hex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIColor+Hex.h"; sourceTree = ""; }; 67 | 21F4EB391D0EF08A009380CD /* UIColor+Hex.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIColor+Hex.m"; sourceTree = ""; }; 68 | 21F4EB3C1D0EF1B1009380CD /* AnimatiomView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnimatiomView.h; sourceTree = ""; }; 69 | 21F4EB3D1D0EF1B1009380CD /* AnimatiomView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AnimatiomView.m; sourceTree = ""; }; 70 | 21F4EB401D0EF216009380CD /* CircleLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CircleLayer.h; sourceTree = ""; }; 71 | 21F4EB411D0EF216009380CD /* CircleLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CircleLayer.m; sourceTree = ""; }; 72 | /* End PBXFileReference section */ 73 | 74 | /* Begin PBXFrameworksBuildPhase section */ 75 | 21F4EAFE1D0EF049009380CD /* Frameworks */ = { 76 | isa = PBXFrameworksBuildPhase; 77 | buildActionMask = 2147483647; 78 | files = ( 79 | ); 80 | runOnlyForDeploymentPostprocessing = 0; 81 | }; 82 | 21F4EB171D0EF049009380CD /* Frameworks */ = { 83 | isa = PBXFrameworksBuildPhase; 84 | buildActionMask = 2147483647; 85 | files = ( 86 | ); 87 | runOnlyForDeploymentPostprocessing = 0; 88 | }; 89 | 21F4EB221D0EF049009380CD /* Frameworks */ = { 90 | isa = PBXFrameworksBuildPhase; 91 | buildActionMask = 2147483647; 92 | files = ( 93 | ); 94 | runOnlyForDeploymentPostprocessing = 0; 95 | }; 96 | /* End PBXFrameworksBuildPhase section */ 97 | 98 | /* Begin PBXGroup section */ 99 | 21F4EAF81D0EF049009380CD = { 100 | isa = PBXGroup; 101 | children = ( 102 | 21F4EB031D0EF049009380CD /* HWLoadingAnimation_OC */, 103 | 21F4EB1D1D0EF049009380CD /* HWLoadingAnimation_OCTests */, 104 | 21F4EB281D0EF049009380CD /* HWLoadingAnimation_OCUITests */, 105 | 21F4EB021D0EF049009380CD /* Products */, 106 | ); 107 | sourceTree = ""; 108 | }; 109 | 21F4EB021D0EF049009380CD /* Products */ = { 110 | isa = PBXGroup; 111 | children = ( 112 | 21F4EB011D0EF049009380CD /* HWLoadingAnimation_OC.app */, 113 | 21F4EB1A1D0EF049009380CD /* HWLoadingAnimation_OCTests.xctest */, 114 | 21F4EB251D0EF049009380CD /* HWLoadingAnimation_OCUITests.xctest */, 115 | ); 116 | name = Products; 117 | sourceTree = ""; 118 | }; 119 | 21F4EB031D0EF049009380CD /* HWLoadingAnimation_OC */ = { 120 | isa = PBXGroup; 121 | children = ( 122 | 21F4EB071D0EF049009380CD /* AppDelegate.h */, 123 | 21F4EB081D0EF049009380CD /* AppDelegate.m */, 124 | 21F4EB0A1D0EF049009380CD /* ViewController.h */, 125 | 21F4EB0B1D0EF049009380CD /* ViewController.m */, 126 | 21F4EB3B1D0EF19C009380CD /* HWView */, 127 | 21F4EB371D0EF07A009380CD /* Others */, 128 | 21F4EB0D1D0EF049009380CD /* Main.storyboard */, 129 | 21F4EB101D0EF049009380CD /* Assets.xcassets */, 130 | 21F4EB121D0EF049009380CD /* LaunchScreen.storyboard */, 131 | 21F4EB151D0EF049009380CD /* Info.plist */, 132 | 21F4EB041D0EF049009380CD /* Supporting Files */, 133 | ); 134 | path = HWLoadingAnimation_OC; 135 | sourceTree = ""; 136 | }; 137 | 21F4EB041D0EF049009380CD /* Supporting Files */ = { 138 | isa = PBXGroup; 139 | children = ( 140 | 21F4EB051D0EF049009380CD /* main.m */, 141 | ); 142 | name = "Supporting Files"; 143 | sourceTree = ""; 144 | }; 145 | 21F4EB1D1D0EF049009380CD /* HWLoadingAnimation_OCTests */ = { 146 | isa = PBXGroup; 147 | children = ( 148 | 21F4EB1E1D0EF049009380CD /* HWLoadingAnimation_OCTests.m */, 149 | 21F4EB201D0EF049009380CD /* Info.plist */, 150 | ); 151 | path = HWLoadingAnimation_OCTests; 152 | sourceTree = ""; 153 | }; 154 | 21F4EB281D0EF049009380CD /* HWLoadingAnimation_OCUITests */ = { 155 | isa = PBXGroup; 156 | children = ( 157 | 21F4EB291D0EF049009380CD /* HWLoadingAnimation_OCUITests.m */, 158 | 21F4EB2B1D0EF049009380CD /* Info.plist */, 159 | ); 160 | path = HWLoadingAnimation_OCUITests; 161 | sourceTree = ""; 162 | }; 163 | 21F4EB371D0EF07A009380CD /* Others */ = { 164 | isa = PBXGroup; 165 | children = ( 166 | 21F4EB381D0EF08A009380CD /* UIColor+Hex.h */, 167 | 21F4EB391D0EF08A009380CD /* UIColor+Hex.m */, 168 | ); 169 | path = Others; 170 | sourceTree = ""; 171 | }; 172 | 21F4EB3B1D0EF19C009380CD /* HWView */ = { 173 | isa = PBXGroup; 174 | children = ( 175 | 21F4EB3C1D0EF1B1009380CD /* AnimatiomView.h */, 176 | 21F4EB3D1D0EF1B1009380CD /* AnimatiomView.m */, 177 | 21F4EB3F1D0EF1FA009380CD /* HWLayer */, 178 | ); 179 | path = HWView; 180 | sourceTree = ""; 181 | }; 182 | 21F4EB3F1D0EF1FA009380CD /* HWLayer */ = { 183 | isa = PBXGroup; 184 | children = ( 185 | 21F4EB401D0EF216009380CD /* CircleLayer.h */, 186 | 21F4EB411D0EF216009380CD /* CircleLayer.m */, 187 | 215C04771D0EFF2F00B2F364 /* TriangleLayer.h */, 188 | 215C04781D0EFF2F00B2F364 /* TriangleLayer.m */, 189 | 215C047A1D0F0B9400B2F364 /* RectangleLayer.h */, 190 | 215C047B1D0F0B9400B2F364 /* RectangleLayer.m */, 191 | 215C047D1D0F0FB500B2F364 /* WaveLayer.h */, 192 | 215C047E1D0F0FB500B2F364 /* WaveLayer.m */, 193 | ); 194 | path = HWLayer; 195 | sourceTree = ""; 196 | }; 197 | /* End PBXGroup section */ 198 | 199 | /* Begin PBXNativeTarget section */ 200 | 21F4EB001D0EF049009380CD /* HWLoadingAnimation_OC */ = { 201 | isa = PBXNativeTarget; 202 | buildConfigurationList = 21F4EB2E1D0EF049009380CD /* Build configuration list for PBXNativeTarget "HWLoadingAnimation_OC" */; 203 | buildPhases = ( 204 | 21F4EAFD1D0EF049009380CD /* Sources */, 205 | 21F4EAFE1D0EF049009380CD /* Frameworks */, 206 | 21F4EAFF1D0EF049009380CD /* Resources */, 207 | ); 208 | buildRules = ( 209 | ); 210 | dependencies = ( 211 | ); 212 | name = HWLoadingAnimation_OC; 213 | productName = HWLoadingAnimation_OC; 214 | productReference = 21F4EB011D0EF049009380CD /* HWLoadingAnimation_OC.app */; 215 | productType = "com.apple.product-type.application"; 216 | }; 217 | 21F4EB191D0EF049009380CD /* HWLoadingAnimation_OCTests */ = { 218 | isa = PBXNativeTarget; 219 | buildConfigurationList = 21F4EB311D0EF049009380CD /* Build configuration list for PBXNativeTarget "HWLoadingAnimation_OCTests" */; 220 | buildPhases = ( 221 | 21F4EB161D0EF049009380CD /* Sources */, 222 | 21F4EB171D0EF049009380CD /* Frameworks */, 223 | 21F4EB181D0EF049009380CD /* Resources */, 224 | ); 225 | buildRules = ( 226 | ); 227 | dependencies = ( 228 | 21F4EB1C1D0EF049009380CD /* PBXTargetDependency */, 229 | ); 230 | name = HWLoadingAnimation_OCTests; 231 | productName = HWLoadingAnimation_OCTests; 232 | productReference = 21F4EB1A1D0EF049009380CD /* HWLoadingAnimation_OCTests.xctest */; 233 | productType = "com.apple.product-type.bundle.unit-test"; 234 | }; 235 | 21F4EB241D0EF049009380CD /* HWLoadingAnimation_OCUITests */ = { 236 | isa = PBXNativeTarget; 237 | buildConfigurationList = 21F4EB341D0EF049009380CD /* Build configuration list for PBXNativeTarget "HWLoadingAnimation_OCUITests" */; 238 | buildPhases = ( 239 | 21F4EB211D0EF049009380CD /* Sources */, 240 | 21F4EB221D0EF049009380CD /* Frameworks */, 241 | 21F4EB231D0EF049009380CD /* Resources */, 242 | ); 243 | buildRules = ( 244 | ); 245 | dependencies = ( 246 | 21F4EB271D0EF049009380CD /* PBXTargetDependency */, 247 | ); 248 | name = HWLoadingAnimation_OCUITests; 249 | productName = HWLoadingAnimation_OCUITests; 250 | productReference = 21F4EB251D0EF049009380CD /* HWLoadingAnimation_OCUITests.xctest */; 251 | productType = "com.apple.product-type.bundle.ui-testing"; 252 | }; 253 | /* End PBXNativeTarget section */ 254 | 255 | /* Begin PBXProject section */ 256 | 21F4EAF91D0EF049009380CD /* Project object */ = { 257 | isa = PBXProject; 258 | attributes = { 259 | LastUpgradeCheck = 0730; 260 | ORGANIZATIONNAME = HenryCheng; 261 | TargetAttributes = { 262 | 21F4EB001D0EF049009380CD = { 263 | CreatedOnToolsVersion = 7.3.1; 264 | }; 265 | 21F4EB191D0EF049009380CD = { 266 | CreatedOnToolsVersion = 7.3.1; 267 | TestTargetID = 21F4EB001D0EF049009380CD; 268 | }; 269 | 21F4EB241D0EF049009380CD = { 270 | CreatedOnToolsVersion = 7.3.1; 271 | TestTargetID = 21F4EB001D0EF049009380CD; 272 | }; 273 | }; 274 | }; 275 | buildConfigurationList = 21F4EAFC1D0EF049009380CD /* Build configuration list for PBXProject "HWLoadingAnimation_OC" */; 276 | compatibilityVersion = "Xcode 3.2"; 277 | developmentRegion = English; 278 | hasScannedForEncodings = 0; 279 | knownRegions = ( 280 | en, 281 | Base, 282 | ); 283 | mainGroup = 21F4EAF81D0EF049009380CD; 284 | productRefGroup = 21F4EB021D0EF049009380CD /* Products */; 285 | projectDirPath = ""; 286 | projectRoot = ""; 287 | targets = ( 288 | 21F4EB001D0EF049009380CD /* HWLoadingAnimation_OC */, 289 | 21F4EB191D0EF049009380CD /* HWLoadingAnimation_OCTests */, 290 | 21F4EB241D0EF049009380CD /* HWLoadingAnimation_OCUITests */, 291 | ); 292 | }; 293 | /* End PBXProject section */ 294 | 295 | /* Begin PBXResourcesBuildPhase section */ 296 | 21F4EAFF1D0EF049009380CD /* Resources */ = { 297 | isa = PBXResourcesBuildPhase; 298 | buildActionMask = 2147483647; 299 | files = ( 300 | 21F4EB141D0EF049009380CD /* LaunchScreen.storyboard in Resources */, 301 | 21F4EB111D0EF049009380CD /* Assets.xcassets in Resources */, 302 | 21F4EB0F1D0EF049009380CD /* Main.storyboard in Resources */, 303 | ); 304 | runOnlyForDeploymentPostprocessing = 0; 305 | }; 306 | 21F4EB181D0EF049009380CD /* Resources */ = { 307 | isa = PBXResourcesBuildPhase; 308 | buildActionMask = 2147483647; 309 | files = ( 310 | ); 311 | runOnlyForDeploymentPostprocessing = 0; 312 | }; 313 | 21F4EB231D0EF049009380CD /* Resources */ = { 314 | isa = PBXResourcesBuildPhase; 315 | buildActionMask = 2147483647; 316 | files = ( 317 | ); 318 | runOnlyForDeploymentPostprocessing = 0; 319 | }; 320 | /* End PBXResourcesBuildPhase section */ 321 | 322 | /* Begin PBXSourcesBuildPhase section */ 323 | 21F4EAFD1D0EF049009380CD /* Sources */ = { 324 | isa = PBXSourcesBuildPhase; 325 | buildActionMask = 2147483647; 326 | files = ( 327 | 21F4EB0C1D0EF049009380CD /* ViewController.m in Sources */, 328 | 21F4EB3A1D0EF08A009380CD /* UIColor+Hex.m in Sources */, 329 | 215C047F1D0F0FB500B2F364 /* WaveLayer.m in Sources */, 330 | 21F4EB091D0EF049009380CD /* AppDelegate.m in Sources */, 331 | 21F4EB421D0EF216009380CD /* CircleLayer.m in Sources */, 332 | 215C04791D0EFF2F00B2F364 /* TriangleLayer.m in Sources */, 333 | 215C047C1D0F0B9400B2F364 /* RectangleLayer.m in Sources */, 334 | 21F4EB061D0EF049009380CD /* main.m in Sources */, 335 | 21F4EB3E1D0EF1B1009380CD /* AnimatiomView.m in Sources */, 336 | ); 337 | runOnlyForDeploymentPostprocessing = 0; 338 | }; 339 | 21F4EB161D0EF049009380CD /* Sources */ = { 340 | isa = PBXSourcesBuildPhase; 341 | buildActionMask = 2147483647; 342 | files = ( 343 | 21F4EB1F1D0EF049009380CD /* HWLoadingAnimation_OCTests.m in Sources */, 344 | ); 345 | runOnlyForDeploymentPostprocessing = 0; 346 | }; 347 | 21F4EB211D0EF049009380CD /* Sources */ = { 348 | isa = PBXSourcesBuildPhase; 349 | buildActionMask = 2147483647; 350 | files = ( 351 | 21F4EB2A1D0EF049009380CD /* HWLoadingAnimation_OCUITests.m in Sources */, 352 | ); 353 | runOnlyForDeploymentPostprocessing = 0; 354 | }; 355 | /* End PBXSourcesBuildPhase section */ 356 | 357 | /* Begin PBXTargetDependency section */ 358 | 21F4EB1C1D0EF049009380CD /* PBXTargetDependency */ = { 359 | isa = PBXTargetDependency; 360 | target = 21F4EB001D0EF049009380CD /* HWLoadingAnimation_OC */; 361 | targetProxy = 21F4EB1B1D0EF049009380CD /* PBXContainerItemProxy */; 362 | }; 363 | 21F4EB271D0EF049009380CD /* PBXTargetDependency */ = { 364 | isa = PBXTargetDependency; 365 | target = 21F4EB001D0EF049009380CD /* HWLoadingAnimation_OC */; 366 | targetProxy = 21F4EB261D0EF049009380CD /* PBXContainerItemProxy */; 367 | }; 368 | /* End PBXTargetDependency section */ 369 | 370 | /* Begin PBXVariantGroup section */ 371 | 21F4EB0D1D0EF049009380CD /* Main.storyboard */ = { 372 | isa = PBXVariantGroup; 373 | children = ( 374 | 21F4EB0E1D0EF049009380CD /* Base */, 375 | ); 376 | name = Main.storyboard; 377 | sourceTree = ""; 378 | }; 379 | 21F4EB121D0EF049009380CD /* LaunchScreen.storyboard */ = { 380 | isa = PBXVariantGroup; 381 | children = ( 382 | 21F4EB131D0EF049009380CD /* Base */, 383 | ); 384 | name = LaunchScreen.storyboard; 385 | sourceTree = ""; 386 | }; 387 | /* End PBXVariantGroup section */ 388 | 389 | /* Begin XCBuildConfiguration section */ 390 | 21F4EB2C1D0EF049009380CD /* Debug */ = { 391 | isa = XCBuildConfiguration; 392 | buildSettings = { 393 | ALWAYS_SEARCH_USER_PATHS = NO; 394 | CLANG_ANALYZER_NONNULL = YES; 395 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 396 | CLANG_CXX_LIBRARY = "libc++"; 397 | CLANG_ENABLE_MODULES = YES; 398 | CLANG_ENABLE_OBJC_ARC = YES; 399 | CLANG_WARN_BOOL_CONVERSION = YES; 400 | CLANG_WARN_CONSTANT_CONVERSION = YES; 401 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 402 | CLANG_WARN_EMPTY_BODY = YES; 403 | CLANG_WARN_ENUM_CONVERSION = YES; 404 | CLANG_WARN_INT_CONVERSION = YES; 405 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 406 | CLANG_WARN_UNREACHABLE_CODE = YES; 407 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 408 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 409 | COPY_PHASE_STRIP = NO; 410 | DEBUG_INFORMATION_FORMAT = dwarf; 411 | ENABLE_STRICT_OBJC_MSGSEND = YES; 412 | ENABLE_TESTABILITY = YES; 413 | GCC_C_LANGUAGE_STANDARD = gnu99; 414 | GCC_DYNAMIC_NO_PIC = NO; 415 | GCC_NO_COMMON_BLOCKS = YES; 416 | GCC_OPTIMIZATION_LEVEL = 0; 417 | GCC_PREPROCESSOR_DEFINITIONS = ( 418 | "DEBUG=1", 419 | "$(inherited)", 420 | ); 421 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 422 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 423 | GCC_WARN_UNDECLARED_SELECTOR = YES; 424 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 425 | GCC_WARN_UNUSED_FUNCTION = YES; 426 | GCC_WARN_UNUSED_VARIABLE = YES; 427 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 428 | MTL_ENABLE_DEBUG_INFO = YES; 429 | ONLY_ACTIVE_ARCH = YES; 430 | SDKROOT = iphoneos; 431 | TARGETED_DEVICE_FAMILY = "1,2"; 432 | }; 433 | name = Debug; 434 | }; 435 | 21F4EB2D1D0EF049009380CD /* Release */ = { 436 | isa = XCBuildConfiguration; 437 | buildSettings = { 438 | ALWAYS_SEARCH_USER_PATHS = NO; 439 | CLANG_ANALYZER_NONNULL = YES; 440 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 441 | CLANG_CXX_LIBRARY = "libc++"; 442 | CLANG_ENABLE_MODULES = YES; 443 | CLANG_ENABLE_OBJC_ARC = YES; 444 | CLANG_WARN_BOOL_CONVERSION = YES; 445 | CLANG_WARN_CONSTANT_CONVERSION = YES; 446 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 447 | CLANG_WARN_EMPTY_BODY = YES; 448 | CLANG_WARN_ENUM_CONVERSION = YES; 449 | CLANG_WARN_INT_CONVERSION = YES; 450 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 451 | CLANG_WARN_UNREACHABLE_CODE = YES; 452 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 453 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 454 | COPY_PHASE_STRIP = NO; 455 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 456 | ENABLE_NS_ASSERTIONS = NO; 457 | ENABLE_STRICT_OBJC_MSGSEND = YES; 458 | GCC_C_LANGUAGE_STANDARD = gnu99; 459 | GCC_NO_COMMON_BLOCKS = YES; 460 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 461 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 462 | GCC_WARN_UNDECLARED_SELECTOR = YES; 463 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 464 | GCC_WARN_UNUSED_FUNCTION = YES; 465 | GCC_WARN_UNUSED_VARIABLE = YES; 466 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 467 | MTL_ENABLE_DEBUG_INFO = NO; 468 | SDKROOT = iphoneos; 469 | TARGETED_DEVICE_FAMILY = "1,2"; 470 | VALIDATE_PRODUCT = YES; 471 | }; 472 | name = Release; 473 | }; 474 | 21F4EB2F1D0EF049009380CD /* Debug */ = { 475 | isa = XCBuildConfiguration; 476 | buildSettings = { 477 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 478 | INFOPLIST_FILE = HWLoadingAnimation_OC/Info.plist; 479 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 480 | PRODUCT_BUNDLE_IDENTIFIER = "Loveway.HWLoadingAnimation-OC"; 481 | PRODUCT_NAME = "$(TARGET_NAME)"; 482 | }; 483 | name = Debug; 484 | }; 485 | 21F4EB301D0EF049009380CD /* Release */ = { 486 | isa = XCBuildConfiguration; 487 | buildSettings = { 488 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 489 | INFOPLIST_FILE = HWLoadingAnimation_OC/Info.plist; 490 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 491 | PRODUCT_BUNDLE_IDENTIFIER = "Loveway.HWLoadingAnimation-OC"; 492 | PRODUCT_NAME = "$(TARGET_NAME)"; 493 | }; 494 | name = Release; 495 | }; 496 | 21F4EB321D0EF049009380CD /* Debug */ = { 497 | isa = XCBuildConfiguration; 498 | buildSettings = { 499 | BUNDLE_LOADER = "$(TEST_HOST)"; 500 | INFOPLIST_FILE = HWLoadingAnimation_OCTests/Info.plist; 501 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 502 | PRODUCT_BUNDLE_IDENTIFIER = "Loveway.HWLoadingAnimation-OCTests"; 503 | PRODUCT_NAME = "$(TARGET_NAME)"; 504 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/HWLoadingAnimation_OC.app/HWLoadingAnimation_OC"; 505 | }; 506 | name = Debug; 507 | }; 508 | 21F4EB331D0EF049009380CD /* Release */ = { 509 | isa = XCBuildConfiguration; 510 | buildSettings = { 511 | BUNDLE_LOADER = "$(TEST_HOST)"; 512 | INFOPLIST_FILE = HWLoadingAnimation_OCTests/Info.plist; 513 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 514 | PRODUCT_BUNDLE_IDENTIFIER = "Loveway.HWLoadingAnimation-OCTests"; 515 | PRODUCT_NAME = "$(TARGET_NAME)"; 516 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/HWLoadingAnimation_OC.app/HWLoadingAnimation_OC"; 517 | }; 518 | name = Release; 519 | }; 520 | 21F4EB351D0EF049009380CD /* Debug */ = { 521 | isa = XCBuildConfiguration; 522 | buildSettings = { 523 | INFOPLIST_FILE = HWLoadingAnimation_OCUITests/Info.plist; 524 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 525 | PRODUCT_BUNDLE_IDENTIFIER = "Loveway.HWLoadingAnimation-OCUITests"; 526 | PRODUCT_NAME = "$(TARGET_NAME)"; 527 | TEST_TARGET_NAME = HWLoadingAnimation_OC; 528 | }; 529 | name = Debug; 530 | }; 531 | 21F4EB361D0EF049009380CD /* Release */ = { 532 | isa = XCBuildConfiguration; 533 | buildSettings = { 534 | INFOPLIST_FILE = HWLoadingAnimation_OCUITests/Info.plist; 535 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 536 | PRODUCT_BUNDLE_IDENTIFIER = "Loveway.HWLoadingAnimation-OCUITests"; 537 | PRODUCT_NAME = "$(TARGET_NAME)"; 538 | TEST_TARGET_NAME = HWLoadingAnimation_OC; 539 | }; 540 | name = Release; 541 | }; 542 | /* End XCBuildConfiguration section */ 543 | 544 | /* Begin XCConfigurationList section */ 545 | 21F4EAFC1D0EF049009380CD /* Build configuration list for PBXProject "HWLoadingAnimation_OC" */ = { 546 | isa = XCConfigurationList; 547 | buildConfigurations = ( 548 | 21F4EB2C1D0EF049009380CD /* Debug */, 549 | 21F4EB2D1D0EF049009380CD /* Release */, 550 | ); 551 | defaultConfigurationIsVisible = 0; 552 | defaultConfigurationName = Release; 553 | }; 554 | 21F4EB2E1D0EF049009380CD /* Build configuration list for PBXNativeTarget "HWLoadingAnimation_OC" */ = { 555 | isa = XCConfigurationList; 556 | buildConfigurations = ( 557 | 21F4EB2F1D0EF049009380CD /* Debug */, 558 | 21F4EB301D0EF049009380CD /* Release */, 559 | ); 560 | defaultConfigurationIsVisible = 0; 561 | defaultConfigurationName = Release; 562 | }; 563 | 21F4EB311D0EF049009380CD /* Build configuration list for PBXNativeTarget "HWLoadingAnimation_OCTests" */ = { 564 | isa = XCConfigurationList; 565 | buildConfigurations = ( 566 | 21F4EB321D0EF049009380CD /* Debug */, 567 | 21F4EB331D0EF049009380CD /* Release */, 568 | ); 569 | defaultConfigurationIsVisible = 0; 570 | defaultConfigurationName = Release; 571 | }; 572 | 21F4EB341D0EF049009380CD /* Build configuration list for PBXNativeTarget "HWLoadingAnimation_OCUITests" */ = { 573 | isa = XCConfigurationList; 574 | buildConfigurations = ( 575 | 21F4EB351D0EF049009380CD /* Debug */, 576 | 21F4EB361D0EF049009380CD /* Release */, 577 | ); 578 | defaultConfigurationIsVisible = 0; 579 | defaultConfigurationName = Release; 580 | }; 581 | /* End XCConfigurationList section */ 582 | }; 583 | rootObject = 21F4EAF91D0EF049009380CD /* Project object */; 584 | } 585 | -------------------------------------------------------------------------------- /HWLoadingAnimation-OC/HWLoadingAnimation_OC.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /HWLoadingAnimation-OC/HWLoadingAnimation_OC.xcodeproj/project.xcworkspace/xcuserdata/HenryCheng.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/loveway/HWLoadingAnimation/059dce17cfe534f839fbafd8f6f7ef600794b832/HWLoadingAnimation-OC/HWLoadingAnimation_OC.xcodeproj/project.xcworkspace/xcuserdata/HenryCheng.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /HWLoadingAnimation-OC/HWLoadingAnimation_OC.xcodeproj/project.xcworkspace/xcuserdata/chenghongwei.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/loveway/HWLoadingAnimation/059dce17cfe534f839fbafd8f6f7ef600794b832/HWLoadingAnimation-OC/HWLoadingAnimation_OC.xcodeproj/project.xcworkspace/xcuserdata/chenghongwei.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /HWLoadingAnimation-OC/HWLoadingAnimation_OC.xcodeproj/xcuserdata/HenryCheng.xcuserdatad/xcschemes/HWLoadingAnimation_OC.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 74 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /HWLoadingAnimation-OC/HWLoadingAnimation_OC.xcodeproj/xcuserdata/HenryCheng.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | HWLoadingAnimation_OC.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 21F4EB001D0EF049009380CD 16 | 17 | primary 18 | 19 | 20 | 21F4EB191D0EF049009380CD 21 | 22 | primary 23 | 24 | 25 | 21F4EB241D0EF049009380CD 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /HWLoadingAnimation-OC/HWLoadingAnimation_OC.xcodeproj/xcuserdata/chenghongwei.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /HWLoadingAnimation-OC/HWLoadingAnimation_OC.xcodeproj/xcuserdata/chenghongwei.xcuserdatad/xcschemes/HWLoadingAnimation_OC.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 74 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /HWLoadingAnimation-OC/HWLoadingAnimation_OC.xcodeproj/xcuserdata/chenghongwei.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | HWLoadingAnimation_OC.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 21F4EB001D0EF049009380CD 16 | 17 | primary 18 | 19 | 20 | 21F4EB191D0EF049009380CD 21 | 22 | primary 23 | 24 | 25 | 21F4EB241D0EF049009380CD 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /HWLoadingAnimation-OC/HWLoadingAnimation_OC/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // HWLoadingAnimation_OC 4 | // 5 | // Created by HenryCheng on 16/6/13. 6 | // Copyright © 2016年 HenryCheng. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /HWLoadingAnimation-OC/HWLoadingAnimation_OC/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // HWLoadingAnimation_OC 4 | // 5 | // Created by HenryCheng on 16/6/13. 6 | // Copyright © 2016年 HenryCheng. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | - (void)applicationWillResignActive:(UIApplication *)application { 24 | // 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. 25 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 26 | } 27 | 28 | - (void)applicationDidEnterBackground:(UIApplication *)application { 29 | // 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. 30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 31 | } 32 | 33 | - (void)applicationWillEnterForeground:(UIApplication *)application { 34 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 35 | } 36 | 37 | - (void)applicationDidBecomeActive:(UIApplication *)application { 38 | // 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. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application { 42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /HWLoadingAnimation-OC/HWLoadingAnimation_OC/Assets.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 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /HWLoadingAnimation-OC/HWLoadingAnimation_OC/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 | -------------------------------------------------------------------------------- /HWLoadingAnimation-OC/HWLoadingAnimation_OC/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 | -------------------------------------------------------------------------------- /HWLoadingAnimation-OC/HWLoadingAnimation_OC/HWView/AnimatiomView.h: -------------------------------------------------------------------------------- 1 | // 2 | // AnimatiomView.h 3 | // HWLoadingAnimation_OC 4 | // 5 | // Created by HenryCheng on 16/6/13. 6 | // Copyright © 2016年 HenryCheng. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @protocol AnimatiomViewDelegate 12 | 13 | - (void)completeAnimation; 14 | 15 | @end 16 | 17 | @interface AnimatiomView : UIView 18 | 19 | @property (assign, nonatomic) CGRect parentFrame; 20 | @property (weak, nonatomic) iddelegate; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /HWLoadingAnimation-OC/HWLoadingAnimation_OC/HWView/AnimatiomView.m: -------------------------------------------------------------------------------- 1 | // 2 | // AnimatiomView.m 3 | // HWLoadingAnimation_OC 4 | // 5 | // Created by HenryCheng on 16/6/13. 6 | // Copyright © 2016年 HenryCheng. All rights reserved. 7 | // 8 | 9 | #import "AnimatiomView.h" 10 | #import "UIColor+Hex.h" 11 | #import "CircleLayer.h" 12 | #import "TriangleLayer.h" 13 | #import "RectangleLayer.h" 14 | #import "WaveLayer.h" 15 | 16 | @interface AnimatiomView () 17 | 18 | @property (strong, nonatomic) CircleLayer *circleLayer; 19 | @property (strong, nonatomic) TriangleLayer *triangleLayer; 20 | @property (strong, nonatomic) RectangleLayer *redRectangleLayer; 21 | @property (strong, nonatomic) RectangleLayer *blueRectangleLayer; 22 | @property (strong, nonatomic) WaveLayer *waveLayer; 23 | 24 | @end 25 | 26 | @implementation AnimatiomView 27 | 28 | - (instancetype) initWithFrame:(CGRect)frame { 29 | if (self == [super initWithFrame:frame]) { 30 | self.backgroundColor = [UIColor clearColor]; 31 | [self addCircleLayer]; 32 | } 33 | return self; 34 | } 35 | 36 | - (CircleLayer *)circleLayer { 37 | if (!_circleLayer) { 38 | _circleLayer = [[CircleLayer alloc] init]; 39 | } 40 | return _circleLayer; 41 | } 42 | 43 | - (TriangleLayer *)triangleLayer { 44 | if (!_triangleLayer) { 45 | _triangleLayer = [[TriangleLayer alloc] init]; 46 | } 47 | return _triangleLayer; 48 | } 49 | 50 | - (RectangleLayer *)redRectangleLayer { 51 | if (!_redRectangleLayer) { 52 | _redRectangleLayer = [[RectangleLayer alloc] init]; 53 | } 54 | return _redRectangleLayer; 55 | } 56 | 57 | - (RectangleLayer *)blueRectangleLayer { 58 | if (!_blueRectangleLayer) { 59 | _blueRectangleLayer = [[RectangleLayer alloc] init]; 60 | } 61 | return _blueRectangleLayer; 62 | } 63 | 64 | - (WaveLayer *)waveLayer { 65 | if (!_waveLayer) { 66 | _waveLayer = [[WaveLayer alloc] init]; 67 | } 68 | return _waveLayer; 69 | } 70 | 71 | - (void)addCircleLayer { 72 | [self.layer addSublayer:self.circleLayer]; 73 | [_circleLayer expand]; 74 | [NSTimer scheduledTimerWithTimeInterval:0.3 target:self selector:@selector(wobbleCircleLayer) userInfo:nil repeats:NO]; 75 | } 76 | 77 | - (void)wobbleCircleLayer { 78 | [_circleLayer wobbleAnimation]; 79 | [self.layer addSublayer:self.triangleLayer]; 80 | [NSTimer scheduledTimerWithTimeInterval:0.9 target:self selector:@selector(showTriangleAnimation) userInfo:nil repeats:NO]; 81 | } 82 | 83 | - (void)showTriangleAnimation { 84 | [_triangleLayer triangleAnimate]; 85 | [NSTimer scheduledTimerWithTimeInterval:0.9 target:self selector:@selector(transformAnima) userInfo:nil repeats:NO]; 86 | } 87 | 88 | - (void)transformAnima { 89 | [self transformRotationZ]; 90 | [_circleLayer contract]; 91 | [NSTimer scheduledTimerWithTimeInterval:0.4 target:self selector:@selector(drawRedRectangleAnimation) userInfo:nil repeats:NO]; 92 | [NSTimer scheduledTimerWithTimeInterval:0.8 target:self selector:@selector(drawBlueRectangleAnimation) userInfo:nil repeats:NO]; 93 | } 94 | 95 | - (void)transformRotationZ { 96 | self.layer.anchorPoint = CGPointMake(0.5, 0.65); 97 | CABasicAnimation *rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; 98 | rotationAnimation.toValue = @(M_PI * 2); 99 | rotationAnimation.duration = 0.45; 100 | rotationAnimation.removedOnCompletion = true; 101 | [self.layer addAnimation:rotationAnimation forKey:nil]; 102 | } 103 | 104 | - (void)drawRedRectangleAnimation { 105 | [self.layer addSublayer:self.redRectangleLayer]; 106 | [_redRectangleLayer strokeChangeWithColor:[UIColor colorWithHexString:@"#da70d6"]]; 107 | 108 | } 109 | 110 | - (void)drawBlueRectangleAnimation { 111 | [self.layer addSublayer:self.blueRectangleLayer]; 112 | [_redRectangleLayer strokeChangeWithColor:[UIColor colorWithHexString:@"#40e0b0"]]; 113 | [NSTimer scheduledTimerWithTimeInterval:0.4 target:self selector:@selector(drawWaveAnimation) userInfo:nil repeats:NO]; 114 | } 115 | 116 | - (void)drawWaveAnimation { 117 | [self.layer addSublayer:self.waveLayer]; 118 | [_waveLayer waveAnimate]; 119 | [NSTimer scheduledTimerWithTimeInterval:0.9 target:self selector:@selector(expandView) userInfo:nil repeats:NO]; 120 | } 121 | 122 | - (void)expandView { 123 | self.backgroundColor = [UIColor colorWithHexString:@"#40e0b0"]; 124 | self.frame = CGRectMake(self.frame.origin.x - self.blueRectangleLayer.lineWidth, 125 | self.frame.origin.y - self.blueRectangleLayer.lineWidth, 126 | self.frame.size.width + self.blueRectangleLayer.lineWidth * 2, 127 | self.frame.size.height + self.blueRectangleLayer.lineWidth * 2); 128 | self.layer.sublayers = nil; 129 | [UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ 130 | self.frame = self.parentFrame; 131 | 132 | } completion:^(BOOL finished) { 133 | if (_delegate && [_delegate respondsToSelector:@selector(completeAnimation)]) { 134 | [_delegate completeAnimation]; 135 | } 136 | }]; 137 | } 138 | 139 | @end 140 | -------------------------------------------------------------------------------- /HWLoadingAnimation-OC/HWLoadingAnimation_OC/HWView/HWLayer/CircleLayer.h: -------------------------------------------------------------------------------- 1 | // 2 | // CircleLayer.h 3 | // HWLoadingAnimation_OC 4 | // 5 | // Created by HenryCheng on 16/6/13. 6 | // Copyright © 2016年 HenryCheng. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CircleLayer : CAShapeLayer 12 | 13 | /** 14 | * Wobble group animation 15 | */ 16 | - (void)wobbleAnimation; 17 | 18 | /** 19 | * Expend animation for circle layer 20 | */ 21 | - (void)expand; 22 | 23 | /** 24 | * Contract animation for circle layer 25 | */ 26 | - (void)contract; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /HWLoadingAnimation-OC/HWLoadingAnimation_OC/HWView/HWLayer/CircleLayer.m: -------------------------------------------------------------------------------- 1 | // 2 | // CircleLayer.m 3 | // HWLoadingAnimation_OC 4 | // 5 | // Created by HenryCheng on 16/6/13. 6 | // Copyright © 2016年 HenryCheng. All rights reserved. 7 | // 8 | 9 | #import "CircleLayer.h" 10 | #import "UIColor+Hex.h" 11 | 12 | @interface CircleLayer () 13 | 14 | @property (strong, nonatomic) UIBezierPath *circleSmallPath; 15 | @property (strong, nonatomic) UIBezierPath *circleBigPath; 16 | @property (strong, nonatomic) UIBezierPath *circleVerticalSquishPath; 17 | @property (strong, nonatomic) UIBezierPath *circleHorizontalSquishPath; 18 | 19 | @end 20 | 21 | static const NSTimeInterval KAnimationDuration = 0.3; 22 | static const NSTimeInterval KAnimationBeginTime = 0.0; 23 | 24 | @implementation CircleLayer 25 | 26 | - (instancetype)init { 27 | 28 | if (self == [super init]) { 29 | self.fillColor = [UIColor colorWithHexString:@"#da70d6"].CGColor; 30 | self.path = self.circleSmallPath.CGPath; 31 | } 32 | return self; 33 | } 34 | 35 | - (UIBezierPath *)circleSmallPath { 36 | if (!_circleSmallPath) { 37 | _circleSmallPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(50.0, 50.0, 0.0, 0.0)]; 38 | } 39 | return _circleSmallPath; 40 | } 41 | - (UIBezierPath *)circleBigPath { 42 | if (!_circleBigPath) { 43 | _circleBigPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(2.5, 17.5, 95.0, 95.0)]; 44 | } 45 | return _circleBigPath; 46 | } 47 | - (UIBezierPath *)circleVerticalSquishPath { 48 | if (!_circleVerticalSquishPath) { 49 | _circleVerticalSquishPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(2.5, 20.0, 95.0, 90.0)]; 50 | } 51 | return _circleVerticalSquishPath; 52 | } 53 | - (UIBezierPath *)circleHorizontalSquishPath { 54 | if (!_circleHorizontalSquishPath) { 55 | _circleHorizontalSquishPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(5.0, 20.0, 90.0, 90.0)]; 56 | } 57 | return _circleHorizontalSquishPath; 58 | } 59 | 60 | - (void)wobbleAnimation { 61 | // 1 62 | CABasicAnimation *animation1 = [CABasicAnimation animationWithKeyPath:@"path"]; 63 | animation1.fromValue = (__bridge id _Nullable)(self.circleBigPath.CGPath); 64 | animation1.toValue = (__bridge id _Nullable)(self.circleVerticalSquishPath.CGPath); 65 | animation1.beginTime = KAnimationBeginTime; 66 | animation1.duration = KAnimationDuration; 67 | // 2 68 | CABasicAnimation *animation2 = [CABasicAnimation animationWithKeyPath:@"path"]; 69 | animation2.fromValue = (__bridge id _Nullable)(self.circleVerticalSquishPath.CGPath); 70 | animation2.toValue = (__bridge id _Nullable)(self.circleHorizontalSquishPath.CGPath); 71 | animation2.beginTime = animation1.beginTime + animation1.duration; 72 | animation2.duration = KAnimationDuration; 73 | // 3 74 | CABasicAnimation *animation3 = [CABasicAnimation animationWithKeyPath:@"path"]; 75 | animation3.fromValue = (__bridge id _Nullable)(self.circleHorizontalSquishPath.CGPath); 76 | animation3.toValue = (__bridge id _Nullable)(self.circleVerticalSquishPath.CGPath); 77 | animation3.beginTime = animation2.beginTime + animation2.duration; 78 | animation3.duration = KAnimationDuration; 79 | // 4 80 | CABasicAnimation *animation4 = [CABasicAnimation animationWithKeyPath:@"path"]; 81 | animation4.fromValue = (__bridge id _Nullable)(self.circleVerticalSquishPath.CGPath); 82 | animation4.toValue = (__bridge id _Nullable)(self.circleBigPath.CGPath); 83 | animation4.beginTime = animation3.beginTime + animation3.duration; 84 | animation4.duration = KAnimationDuration; 85 | // 5 86 | CAAnimationGroup *animationGroup = [[CAAnimationGroup alloc] init]; 87 | animationGroup.animations = @[animation1, animation2, animation3, animation4]; 88 | animationGroup.duration = 4 * KAnimationDuration; 89 | animationGroup.repeatCount = 2; 90 | [self addAnimation:animationGroup forKey:nil]; 91 | 92 | } 93 | 94 | - (void)expand { 95 | CABasicAnimation *expandAnimation = [CABasicAnimation animationWithKeyPath:@"path"]; 96 | expandAnimation.fromValue = (__bridge id _Nullable)(self.circleSmallPath.CGPath); 97 | expandAnimation.toValue = (__bridge id _Nullable)(self.circleBigPath.CGPath); 98 | expandAnimation.duration = KAnimationDuration; 99 | expandAnimation.fillMode = kCAFillModeForwards; 100 | expandAnimation.removedOnCompletion = NO; 101 | [self addAnimation:expandAnimation forKey:nil]; 102 | 103 | } 104 | 105 | - (void)contract { 106 | CABasicAnimation *expandAnimation = [CABasicAnimation animationWithKeyPath:@"path"]; 107 | expandAnimation.fromValue = (__bridge id _Nullable)(self.circleBigPath.CGPath); 108 | expandAnimation.toValue = (__bridge id _Nullable)(self.circleSmallPath.CGPath); 109 | expandAnimation.duration = KAnimationDuration; 110 | expandAnimation.fillMode = kCAFillModeForwards; 111 | expandAnimation.removedOnCompletion = NO; 112 | [self addAnimation:expandAnimation forKey:nil]; 113 | } 114 | 115 | @end 116 | -------------------------------------------------------------------------------- /HWLoadingAnimation-OC/HWLoadingAnimation_OC/HWView/HWLayer/RectangleLayer.h: -------------------------------------------------------------------------------- 1 | // 2 | // RectangleLayer.h 3 | // HWLoadingAnimation_OC 4 | // 5 | // Created by HenryCheng on 16/6/13. 6 | // Copyright © 2016年 HenryCheng. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface RectangleLayer : CAShapeLayer 13 | 14 | /** 15 | * Change line stroke color with custon color 16 | * 17 | * @param color custom color 18 | */ 19 | - (void)strokeChangeWithColor:(UIColor *)color; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /HWLoadingAnimation-OC/HWLoadingAnimation_OC/HWView/HWLayer/RectangleLayer.m: -------------------------------------------------------------------------------- 1 | // 2 | // RectangleLayer.m 3 | // HWLoadingAnimation_OC 4 | // 5 | // Created by HenryCheng on 16/6/13. 6 | // Copyright © 2016年 HenryCheng. All rights reserved. 7 | // 8 | 9 | #import "RectangleLayer.h" 10 | 11 | @interface RectangleLayer () 12 | 13 | @property (strong, nonatomic) UIBezierPath *rectangleFullPath; 14 | 15 | @end 16 | 17 | static const CGFloat KLineWidth = 5.0; 18 | 19 | @implementation RectangleLayer 20 | 21 | - (instancetype)init { 22 | if (self == [super init]) { 23 | self.fillColor = [UIColor clearColor].CGColor; 24 | self.lineWidth = KLineWidth; 25 | self.path = self.rectangleFullPath.CGPath; 26 | } 27 | return self; 28 | } 29 | 30 | - (UIBezierPath *)rectangleFullPath { 31 | if (!_rectangleFullPath) { 32 | _rectangleFullPath = [[UIBezierPath alloc] init]; 33 | [_rectangleFullPath moveToPoint:CGPointMake(0.0, 100.0)]; 34 | [_rectangleFullPath addLineToPoint:CGPointMake(0.0, -KLineWidth)]; 35 | [_rectangleFullPath addLineToPoint:CGPointMake(100.0, -KLineWidth)]; 36 | [_rectangleFullPath addLineToPoint:CGPointMake(100.0, 100.0)]; 37 | [_rectangleFullPath addLineToPoint:CGPointMake(-KLineWidth / 2, 100.0)]; 38 | [_rectangleFullPath closePath]; 39 | } 40 | return _rectangleFullPath; 41 | } 42 | 43 | - (void)strokeChangeWithColor:(UIColor *)color { 44 | self.strokeColor = color.CGColor; 45 | CABasicAnimation *strokeAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; 46 | strokeAnimation.fromValue = @0.0; 47 | strokeAnimation.toValue = @1.0; 48 | strokeAnimation.duration = 0.4; 49 | [self addAnimation:strokeAnimation forKey:nil]; 50 | } 51 | @end 52 | -------------------------------------------------------------------------------- /HWLoadingAnimation-OC/HWLoadingAnimation_OC/HWView/HWLayer/TriangleLayer.h: -------------------------------------------------------------------------------- 1 | // 2 | // TriangleLayer.h 3 | // HWLoadingAnimation_OC 4 | // 5 | // Created by HenryCheng on 16/6/13. 6 | // Copyright © 2016年 HenryCheng. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TriangleLayer : CAShapeLayer 12 | 13 | /** 14 | * Complete animation with triangle 15 | */ 16 | - (void)triangleAnimate; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /HWLoadingAnimation-OC/HWLoadingAnimation_OC/HWView/HWLayer/TriangleLayer.m: -------------------------------------------------------------------------------- 1 | // 2 | // TriangleLayer.m 3 | // HWLoadingAnimation_OC 4 | // 5 | // Created by HenryCheng on 16/6/13. 6 | // Copyright © 2016年 HenryCheng. All rights reserved. 7 | // 8 | 9 | #import "TriangleLayer.h" 10 | #import "UIColor+Hex.h" 11 | 12 | @interface TriangleLayer () 13 | 14 | @property (strong, nonatomic) UIBezierPath *smallTrianglePath; 15 | @property (strong, nonatomic) UIBezierPath *leftTrianglePath; 16 | @property (strong, nonatomic) UIBezierPath *rightTrianglePath; 17 | @property (strong, nonatomic) UIBezierPath *topTrianglePath; 18 | 19 | @end 20 | 21 | static const CGFloat paddingSpace = 30.0; 22 | 23 | @implementation TriangleLayer 24 | 25 | - (instancetype)init { 26 | if (self == [super init]) { 27 | self.fillColor = [UIColor colorWithHexString:@"#da70d6"].CGColor; 28 | self.strokeColor = [UIColor colorWithHexString:@"#da70d6"].CGColor; 29 | self.lineWidth = 7.0; 30 | self.lineCap = kCALineCapRound; 31 | self.lineJoin = kCALineJoinRound; 32 | self.path = self.smallTrianglePath.CGPath; 33 | } 34 | return self; 35 | } 36 | 37 | - (UIBezierPath *)smallTrianglePath { 38 | if (!_smallTrianglePath) { 39 | _smallTrianglePath = [[UIBezierPath alloc] init]; 40 | [_smallTrianglePath moveToPoint:CGPointMake(5.0 + paddingSpace, 95.0)]; 41 | [_smallTrianglePath addLineToPoint:CGPointMake(50.0, 12.5 + paddingSpace)]; 42 | [_smallTrianglePath addLineToPoint:CGPointMake(95.0 - paddingSpace, 95.0)]; 43 | [_smallTrianglePath closePath]; 44 | } 45 | return _smallTrianglePath; 46 | } 47 | 48 | - (UIBezierPath *)leftTrianglePath { 49 | if (!_leftTrianglePath) { 50 | _leftTrianglePath = [[UIBezierPath alloc] init]; 51 | [_leftTrianglePath moveToPoint:CGPointMake(5.0, 95.0)]; 52 | [_leftTrianglePath addLineToPoint:CGPointMake(50.0, 12.5 + paddingSpace)]; 53 | [_leftTrianglePath addLineToPoint:CGPointMake(95.0 - paddingSpace, 95.0)]; 54 | [_leftTrianglePath closePath]; 55 | } 56 | return _leftTrianglePath; 57 | } 58 | 59 | - (UIBezierPath *)rightTrianglePath { 60 | if (!_rightTrianglePath) { 61 | _rightTrianglePath = [[UIBezierPath alloc] init]; 62 | [_rightTrianglePath moveToPoint:CGPointMake(5.0, 95.0)]; 63 | [_rightTrianglePath addLineToPoint:CGPointMake(50.0, 12.5 + paddingSpace)]; 64 | [_rightTrianglePath addLineToPoint:CGPointMake(95.0, 95.0)]; 65 | [_rightTrianglePath closePath]; 66 | } 67 | return _rightTrianglePath; 68 | } 69 | 70 | - (UIBezierPath *)topTrianglePath { 71 | if (!_topTrianglePath) { 72 | _topTrianglePath = [[UIBezierPath alloc] init]; 73 | [_topTrianglePath moveToPoint:CGPointMake(5.0, 95.0)]; 74 | [_topTrianglePath addLineToPoint:CGPointMake(50.0, 12.5)]; 75 | [_topTrianglePath addLineToPoint:CGPointMake(95.0, 95.0)]; 76 | [_topTrianglePath closePath]; 77 | } 78 | return _topTrianglePath; 79 | } 80 | 81 | - (void)triangleAnimate { 82 | // left 83 | CABasicAnimation *triangleAnimationLeft = [CABasicAnimation animationWithKeyPath:@"path"]; 84 | triangleAnimationLeft.fromValue = (__bridge id _Nullable)(self.smallTrianglePath.CGPath); 85 | triangleAnimationLeft.toValue = (__bridge id _Nullable)(self.leftTrianglePath.CGPath); 86 | triangleAnimationLeft.beginTime = 0.0; 87 | triangleAnimationLeft.duration = 0.3; 88 | // right 89 | CABasicAnimation *triangleAnimationRight = [CABasicAnimation animationWithKeyPath:@"path"]; 90 | triangleAnimationRight.fromValue = (__bridge id _Nullable)(self.leftTrianglePath.CGPath); 91 | triangleAnimationRight.toValue = (__bridge id _Nullable)(self.rightTrianglePath.CGPath); 92 | triangleAnimationRight.beginTime = triangleAnimationLeft.beginTime + triangleAnimationLeft.duration; 93 | triangleAnimationRight.duration = 0.25; 94 | // top 95 | CABasicAnimation *triangleAnimationTop = [CABasicAnimation animationWithKeyPath:@"path"]; 96 | triangleAnimationTop.fromValue = (__bridge id _Nullable)(self.rightTrianglePath.CGPath); 97 | triangleAnimationTop.toValue = (__bridge id _Nullable)(self.topTrianglePath.CGPath); 98 | triangleAnimationTop.beginTime = triangleAnimationRight.beginTime + triangleAnimationRight.duration; 99 | triangleAnimationTop.duration = 0.2; 100 | // group 101 | CAAnimationGroup *animationGroup = [[CAAnimationGroup alloc] init]; 102 | animationGroup.animations = @[triangleAnimationLeft, triangleAnimationRight, triangleAnimationTop]; 103 | animationGroup.duration = triangleAnimationTop.beginTime + triangleAnimationTop.duration; 104 | animationGroup.fillMode = kCAFillModeForwards; 105 | animationGroup.removedOnCompletion = NO; 106 | [self addAnimation:animationGroup forKey:nil]; 107 | } 108 | 109 | @end 110 | -------------------------------------------------------------------------------- /HWLoadingAnimation-OC/HWLoadingAnimation_OC/HWView/HWLayer/WaveLayer.h: -------------------------------------------------------------------------------- 1 | // 2 | // WaveLayer.h 3 | // HWLoadingAnimation_OC 4 | // 5 | // Created by HenryCheng on 16/6/13. 6 | // Copyright © 2016年 HenryCheng. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WaveLayer : CAShapeLayer 12 | 13 | /** 14 | * Complete a wave animation 15 | */ 16 | - (void)waveAnimate; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /HWLoadingAnimation-OC/HWLoadingAnimation_OC/HWView/HWLayer/WaveLayer.m: -------------------------------------------------------------------------------- 1 | // 2 | // WaveLayer.m 3 | // HWLoadingAnimation_OC 4 | // 5 | // Created by HenryCheng on 16/6/13. 6 | // Copyright © 2016年 HenryCheng. All rights reserved. 7 | // 8 | 9 | #import "WaveLayer.h" 10 | #import "UIColor+Hex.h" 11 | 12 | @interface WaveLayer () 13 | 14 | @property (strong, nonatomic) UIBezierPath *wavePathPre; 15 | @property (strong, nonatomic) UIBezierPath *wavePathStarting; 16 | @property (strong, nonatomic) UIBezierPath *wavePathLow; 17 | @property (strong, nonatomic) UIBezierPath *wavePathMid; 18 | @property (strong, nonatomic) UIBezierPath *wavePathHigh; 19 | @property (strong, nonatomic) UIBezierPath *wavePathComplete; 20 | 21 | @end 22 | 23 | static const NSTimeInterval KAnimationDuration = 0.18; 24 | 25 | @implementation WaveLayer 26 | 27 | - (instancetype)init { 28 | if (self == [super init]) { 29 | self.fillColor = [UIColor colorWithHexString:@"#40e0b0"].CGColor; 30 | self.path = self.wavePathStarting.CGPath; 31 | } 32 | return self; 33 | } 34 | 35 | - (UIBezierPath *)wavePathPre { 36 | if (!_wavePathPre) { 37 | _wavePathPre = [[UIBezierPath alloc] init]; 38 | [_wavePathPre moveToPoint:CGPointMake(0.0, 100.0)]; 39 | [_wavePathPre addLineToPoint:CGPointMake(0.0, 99.0)]; 40 | [_wavePathPre addLineToPoint:CGPointMake(100.0, 99.0)]; 41 | [_wavePathPre addLineToPoint:CGPointMake(100.0, 100.0)]; 42 | [_wavePathPre addLineToPoint:CGPointMake(0.0, 100.0)]; 43 | [_wavePathPre closePath]; 44 | } 45 | return _wavePathPre; 46 | } 47 | 48 | - (UIBezierPath *)wavePathStarting { 49 | if (!_wavePathStarting) { 50 | _wavePathStarting = [[UIBezierPath alloc] init]; 51 | [_wavePathStarting moveToPoint:CGPointMake(0.0, 100.0)]; 52 | [_wavePathStarting addLineToPoint:CGPointMake(0.0, 80.0)]; 53 | [_wavePathStarting addCurveToPoint:CGPointMake(100.0, 80.0) controlPoint1:CGPointMake(30.0, 70.0) controlPoint2:CGPointMake(40.0, 90.0)]; 54 | [_wavePathStarting addLineToPoint:CGPointMake(100.0, 100.0)]; 55 | [_wavePathStarting addLineToPoint:CGPointMake(0, 100.0)]; 56 | [_wavePathStarting closePath]; 57 | } 58 | return _wavePathStarting; 59 | } 60 | 61 | - (UIBezierPath *)wavePathLow { 62 | if (!_wavePathLow) { 63 | _wavePathLow = [[UIBezierPath alloc] init]; 64 | [_wavePathLow moveToPoint:CGPointMake(0.0, 100.0)]; 65 | [_wavePathLow addLineToPoint:CGPointMake(0.0, 60.0)]; 66 | [_wavePathLow addCurveToPoint:CGPointMake(100.0, 60.0) controlPoint1:CGPointMake(30.0, 65.0) controlPoint2:CGPointMake(40.0, 50.0)]; 67 | [_wavePathLow addLineToPoint:CGPointMake(100.0, 100.0)]; 68 | [_wavePathLow addLineToPoint:CGPointMake(0.0, 100.0)]; 69 | [_wavePathLow closePath]; 70 | } 71 | return _wavePathLow; 72 | } 73 | 74 | - (UIBezierPath *)wavePathMid { 75 | if (!_wavePathMid) { 76 | _wavePathMid = [[UIBezierPath alloc] init]; 77 | [_wavePathMid moveToPoint:CGPointMake(0.0, 100.0)]; 78 | [_wavePathMid addLineToPoint:CGPointMake(0.0, 40.0)]; 79 | [_wavePathMid addCurveToPoint:CGPointMake(100.0, 40.0) controlPoint1:CGPointMake(30.0, 30.0) controlPoint2:CGPointMake(40.0, 50.0)]; 80 | [_wavePathMid addLineToPoint:CGPointMake(100.0, 100.0)]; 81 | [_wavePathMid addLineToPoint:CGPointMake(0.0, 100.0)]; 82 | [_wavePathMid closePath]; 83 | } 84 | return _wavePathMid; 85 | } 86 | 87 | - (UIBezierPath *)wavePathHigh { 88 | if (!_wavePathHigh) { 89 | _wavePathHigh = [[UIBezierPath alloc] init]; 90 | [_wavePathHigh moveToPoint:CGPointMake(0.0, 100.0)]; 91 | [_wavePathHigh addLineToPoint:CGPointMake(0.0, 20.0)]; 92 | [_wavePathHigh addCurveToPoint:CGPointMake(100.0, 20.0) controlPoint1:CGPointMake(30.0, 25.0) controlPoint2:CGPointMake(40.0, 10.0)]; 93 | [_wavePathHigh addLineToPoint:CGPointMake(100.0, 100.0)]; 94 | [_wavePathHigh addLineToPoint:CGPointMake(0.0, 100.0)]; 95 | [_wavePathHigh closePath]; 96 | } 97 | return _wavePathHigh; 98 | } 99 | 100 | - (UIBezierPath *)wavePathComplete { 101 | if (!_wavePathComplete) { 102 | _wavePathComplete = [[UIBezierPath alloc] init]; 103 | [_wavePathComplete moveToPoint:CGPointMake(0.0, 100.0)]; 104 | [_wavePathComplete addLineToPoint:CGPointMake(0.0, -5.0)]; 105 | [_wavePathComplete addLineToPoint:CGPointMake(100.0, -5.0)]; 106 | [_wavePathComplete addLineToPoint:CGPointMake(100.0, 100.0)]; 107 | [_wavePathComplete addLineToPoint:CGPointMake(0.0, 100.0)]; 108 | [_wavePathComplete closePath]; 109 | } 110 | return _wavePathComplete; 111 | } 112 | 113 | - (void)waveAnimate { 114 | // 1 115 | CABasicAnimation *waveAnimationPre = [CABasicAnimation animationWithKeyPath:@"path"]; 116 | waveAnimationPre.fromValue = (__bridge id _Nullable)(self.wavePathPre.CGPath); 117 | waveAnimationPre.toValue = (__bridge id _Nullable)(self.wavePathStarting.CGPath); 118 | waveAnimationPre.beginTime = 0.0; 119 | waveAnimationPre.duration = KAnimationDuration; 120 | // 2 121 | CABasicAnimation *waveAnimationLow = [CABasicAnimation animationWithKeyPath:@"path"]; 122 | waveAnimationLow.fromValue = (__bridge id _Nullable)(self.wavePathStarting.CGPath); 123 | waveAnimationLow.toValue = (__bridge id _Nullable)(self.wavePathLow.CGPath); 124 | waveAnimationLow.beginTime = waveAnimationPre.beginTime + waveAnimationPre.duration; 125 | waveAnimationLow.duration = KAnimationDuration; 126 | // 3 127 | CABasicAnimation *waveAnimationMid = [CABasicAnimation animationWithKeyPath:@"path"]; 128 | waveAnimationMid.fromValue = (__bridge id _Nullable)(self.wavePathLow.CGPath); 129 | waveAnimationMid.toValue = (__bridge id _Nullable)(self.wavePathMid.CGPath); 130 | waveAnimationMid.beginTime = waveAnimationLow.beginTime + waveAnimationLow.duration; 131 | waveAnimationMid.duration = KAnimationDuration; 132 | // 4 133 | CABasicAnimation *waveAnimationHigh = [CABasicAnimation animationWithKeyPath:@"path"]; 134 | waveAnimationHigh.fromValue = (__bridge id _Nullable)(self.wavePathMid.CGPath); 135 | waveAnimationHigh.toValue = (__bridge id _Nullable)(self.wavePathHigh.CGPath); 136 | waveAnimationHigh.beginTime = waveAnimationMid.beginTime + waveAnimationMid.duration; 137 | waveAnimationHigh.duration = KAnimationDuration; 138 | // 5 139 | CABasicAnimation *waveAnimationComplete = [CABasicAnimation animationWithKeyPath:@"path"]; 140 | waveAnimationComplete.fromValue = (__bridge id _Nullable)(self.wavePathHigh.CGPath); 141 | waveAnimationComplete.toValue = (__bridge id _Nullable)(self.wavePathComplete.CGPath); 142 | waveAnimationComplete.beginTime = waveAnimationHigh.beginTime + waveAnimationHigh.duration; 143 | waveAnimationComplete.duration = KAnimationDuration; 144 | // 6 145 | CAAnimationGroup *animationGroup = [[CAAnimationGroup alloc] init]; 146 | animationGroup.animations = @[waveAnimationPre, waveAnimationLow, waveAnimationMid, waveAnimationHigh, waveAnimationComplete]; 147 | animationGroup.duration = waveAnimationComplete.beginTime + waveAnimationComplete.duration; 148 | animationGroup.fillMode = kCAFillModeForwards; 149 | animationGroup.removedOnCompletion = NO; 150 | [self addAnimation:animationGroup forKey:nil]; 151 | } 152 | 153 | @end 154 | -------------------------------------------------------------------------------- /HWLoadingAnimation-OC/HWLoadingAnimation_OC/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.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 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /HWLoadingAnimation-OC/HWLoadingAnimation_OC/Others/UIColor+Hex.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+Hex.h 3 | // HWLoadingAnimation_OC 4 | // 5 | // Created by HenryCheng on 16/6/13. 6 | // Copyright © 2016年 HenryCheng. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIColor (Hex) 12 | 13 | /** 14 | * Create a new UIColor instance using a hex string input 15 | * 16 | * @param hexString color hexString 17 | * 18 | * @return color 19 | */ 20 | + (UIColor *)colorWithHexString:(id)hexString; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /HWLoadingAnimation-OC/HWLoadingAnimation_OC/Others/UIColor+Hex.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+Hex.m 3 | // HWLoadingAnimation_OC 4 | // 5 | // Created by HenryCheng on 16/6/13. 6 | // Copyright © 2016年 HenryCheng. All rights reserved. 7 | // 8 | 9 | #import "UIColor+Hex.h" 10 | 11 | @implementation UIColor (Hex) 12 | 13 | // 0xff,即二进制的1序列比如11111111,是滤码。 14 | //(0xABCDEF &0xFF0000 ) >> 16 15 | //(0xABCDEF &0xFF00) >> 8 16 | // 0xABCDEF &0xFF 17 | //分别获得原数据的AB、CD、EF不同位置的数据 18 | //分别对应RGB三色中的红色 R 为AB,绿色 G 为CD,蓝色 B 为EF 19 | 20 | + (UIColor *)colorWithHexString:(id)hexString { 21 | if (![hexString isKindOfClass:[NSString class]] || [hexString length] == 0) { 22 | return [UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:1.0f]; 23 | } 24 | 25 | const char *s = [hexString cStringUsingEncoding:NSASCIIStringEncoding]; 26 | if (*s == '#') { 27 | ++s; 28 | } 29 | unsigned long long value = strtoll(s, nil, 16); 30 | int r, g, b, a; 31 | switch (strlen(s)) { 32 | case 2: 33 | // xx 34 | r = g = b = (int)value; 35 | a = 255; 36 | break; 37 | case 3: 38 | // RGB 39 | r = ((value & 0xf00) >> 8); 40 | g = ((value & 0x0f0) >> 4); 41 | b = ((value & 0x00f) >> 0); 42 | r = r * 16 + r; 43 | g = g * 16 + g; 44 | b = b * 16 + b; 45 | a = 255; 46 | break; 47 | case 6: 48 | // RRGGBB 49 | r = (value & 0xff0000) >> 16; 50 | g = (value & 0x00ff00) >> 8; 51 | b = (value & 0x0000ff) >> 0; 52 | a = 255; 53 | break; 54 | default: 55 | // RRGGBBAA 56 | r = (value & 0xff000000) >> 24; 57 | g = (value & 0x00ff0000) >> 16; 58 | b = (value & 0x0000ff00) >> 8; 59 | a = (value & 0x000000ff) >> 0; 60 | break; 61 | } 62 | return [UIColor colorWithRed:r/255.0f green:g/255.0f blue:b/255.0f alpha:a/255.0f]; 63 | } 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /HWLoadingAnimation-OC/HWLoadingAnimation_OC/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // HWLoadingAnimation_OC 4 | // 5 | // Created by HenryCheng on 16/6/13. 6 | // Copyright © 2016年 HenryCheng. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | @end 14 | 15 | -------------------------------------------------------------------------------- /HWLoadingAnimation-OC/HWLoadingAnimation_OC/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // HWLoadingAnimation_OC 4 | // 5 | // Created by HenryCheng on 16/6/13. 6 | // Copyright © 2016年 HenryCheng. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "AnimatiomView.h" 11 | #import "UIColor+Hex.h" 12 | 13 | @interface ViewController () 14 | 15 | @property (strong, nonatomic) AnimatiomView *animationView; 16 | 17 | @end 18 | 19 | @implementation ViewController 20 | 21 | - (void)viewDidLoad { 22 | [super viewDidLoad]; 23 | [self _initAnimationView]; 24 | } 25 | 26 | - (void)_initAnimationView { 27 | CGFloat size = 100.0; 28 | self.animationView = [[AnimatiomView alloc] initWithFrame:CGRectMake(CGRectGetWidth(self.view.frame)/2 - size/2, CGRectGetHeight(self.view.frame)/2 - size/2, size, size)]; 29 | _animationView.delegate = self; 30 | _animationView.parentFrame = self.view.frame; 31 | [self.view addSubview:_animationView]; 32 | } 33 | 34 | #pragma mark - 35 | #pragma mark AnimatiomViewDelegate 36 | 37 | - (void)completeAnimation { 38 | [_animationView removeFromSuperview]; 39 | self.view.backgroundColor = [UIColor colorWithHexString:@"#40e0b0"]; 40 | 41 | // 2 42 | UILabel *label = [[UILabel alloc] initWithFrame:self.view.frame]; 43 | label.textColor = [UIColor whiteColor]; 44 | label.font = [UIFont fontWithName:@"HelveticaNeue-Thin" size:50.0]; 45 | label.textAlignment = NSTextAlignmentCenter; 46 | label.text = @"Welcome"; 47 | label.transform = CGAffineTransformScale(label.transform, 0.25, 0.25); 48 | [self.view addSubview:label]; 49 | 50 | [UIView animateWithDuration:0.4 delay:0.0 usingSpringWithDamping:0.7 initialSpringVelocity:0.1 options:UIViewAnimationOptionCurveEaseInOut animations:^{ 51 | 52 | label.transform = CGAffineTransformScale(label.transform, 4.0, 4.0); 53 | 54 | } completion:^(BOOL finished) { 55 | [self addTouchButton]; 56 | }]; 57 | } 58 | 59 | - (void)addTouchButton { 60 | UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; 61 | btn.frame = CGRectMake(0.0, 0.0, CGRectGetWidth(self.view.frame), CGRectGetHeight(self.view.frame)); 62 | [btn addTarget:self action:@selector(btnClick) forControlEvents:UIControlEventTouchUpInside]; 63 | [self.view addSubview:btn]; 64 | } 65 | 66 | - (void)btnClick { 67 | self.view.backgroundColor = [UIColor whiteColor]; 68 | for (UIView *view in self.view.subviews) { 69 | [view removeFromSuperview]; 70 | } 71 | self.animationView = nil; 72 | [self _initAnimationView]; 73 | } 74 | 75 | - (void)didReceiveMemoryWarning { 76 | [super didReceiveMemoryWarning]; 77 | // Dispose of any resources that can be recreated. 78 | } 79 | 80 | @end 81 | -------------------------------------------------------------------------------- /HWLoadingAnimation-OC/HWLoadingAnimation_OC/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // HWLoadingAnimation_OC 4 | // 5 | // Created by HenryCheng on 16/6/13. 6 | // Copyright © 2016年 HenryCheng. 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 | -------------------------------------------------------------------------------- /HWLoadingAnimation-OC/HWLoadingAnimation_OCTests/HWLoadingAnimation_OCTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // HWLoadingAnimation_OCTests.m 3 | // HWLoadingAnimation_OCTests 4 | // 5 | // Created by HenryCheng on 16/6/13. 6 | // Copyright © 2016年 HenryCheng. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface HWLoadingAnimation_OCTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation HWLoadingAnimation_OCTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /HWLoadingAnimation-OC/HWLoadingAnimation_OCTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /HWLoadingAnimation-OC/HWLoadingAnimation_OCUITests/HWLoadingAnimation_OCUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // HWLoadingAnimation_OCUITests.m 3 | // HWLoadingAnimation_OCUITests 4 | // 5 | // Created by HenryCheng on 16/6/13. 6 | // Copyright © 2016年 HenryCheng. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface HWLoadingAnimation_OCUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation HWLoadingAnimation_OCUITests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | 22 | // In UI tests it is usually best to stop immediately when a failure occurs. 23 | self.continueAfterFailure = NO; 24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 25 | [[[XCUIApplication alloc] init] launch]; 26 | 27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 28 | } 29 | 30 | - (void)tearDown { 31 | // Put teardown code here. This method is called after the invocation of each test method in the class. 32 | [super tearDown]; 33 | } 34 | 35 | - (void)testExample { 36 | // Use recording to get started writing UI tests. 37 | // Use XCTAssert and related functions to verify your tests produce the correct results. 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /HWLoadingAnimation-OC/HWLoadingAnimation_OCUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /HWLoadingAnimation-Swift/HWLoadingAnimation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/loveway/HWLoadingAnimation/059dce17cfe534f839fbafd8f6f7ef600794b832/HWLoadingAnimation-Swift/HWLoadingAnimation.gif -------------------------------------------------------------------------------- /HWLoadingAnimation-Swift/HWLoadingAnimation.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 9240D78A1D0E6DD300B045BA /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9240D7891D0E6DD300B045BA /* AppDelegate.swift */; }; 11 | 9240D78C1D0E6DD300B045BA /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9240D78B1D0E6DD300B045BA /* ViewController.swift */; }; 12 | 9240D78F1D0E6DD300B045BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9240D78D1D0E6DD300B045BA /* Main.storyboard */; }; 13 | 9240D7911D0E6DD300B045BA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9240D7901D0E6DD300B045BA /* Assets.xcassets */; }; 14 | 9240D7941D0E6DD300B045BA /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9240D7921D0E6DD300B045BA /* LaunchScreen.storyboard */; }; 15 | 92C624B31D10144D005431AD /* CircleLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92C624AE1D10144D005431AD /* CircleLayer.swift */; }; 16 | 92C624B41D10144D005431AD /* RectangleLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92C624AF1D10144D005431AD /* RectangleLayer.swift */; }; 17 | 92C624B51D10144D005431AD /* TriangleLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92C624B01D10144D005431AD /* TriangleLayer.swift */; }; 18 | 92C624B61D10144D005431AD /* WaveLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92C624B11D10144D005431AD /* WaveLayer.swift */; }; 19 | 92C624B81D101467005431AD /* AnimationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92C624B71D101467005431AD /* AnimationView.swift */; }; 20 | 92C624C11D101F77005431AD /* Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92C624C01D101F77005431AD /* Extension.swift */; }; 21 | /* End PBXBuildFile section */ 22 | 23 | /* Begin PBXFileReference section */ 24 | 9240D7861D0E6DD200B045BA /* HWLoadingAnimation.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HWLoadingAnimation.app; sourceTree = BUILT_PRODUCTS_DIR; }; 25 | 9240D7891D0E6DD300B045BA /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 26 | 9240D78B1D0E6DD300B045BA /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 27 | 9240D78E1D0E6DD300B045BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 28 | 9240D7901D0E6DD300B045BA /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 29 | 9240D7931D0E6DD300B045BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 30 | 9240D7951D0E6DD300B045BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 31 | 9240D79E1D0E6DD300B045BA /* HWLoadingAnimationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HWLoadingAnimationTests.swift; sourceTree = ""; }; 32 | 9240D7A01D0E6DD300B045BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 33 | 9240D7A91D0E6DD300B045BA /* HWLoadingAnimationUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HWLoadingAnimationUITests.swift; sourceTree = ""; }; 34 | 9240D7AB1D0E6DD300B045BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 35 | 92C624AE1D10144D005431AD /* CircleLayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CircleLayer.swift; sourceTree = ""; }; 36 | 92C624AF1D10144D005431AD /* RectangleLayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RectangleLayer.swift; sourceTree = ""; }; 37 | 92C624B01D10144D005431AD /* TriangleLayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TriangleLayer.swift; sourceTree = ""; }; 38 | 92C624B11D10144D005431AD /* WaveLayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WaveLayer.swift; sourceTree = ""; }; 39 | 92C624B71D101467005431AD /* AnimationView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnimationView.swift; sourceTree = ""; }; 40 | 92C624C01D101F77005431AD /* Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Extension.swift; sourceTree = ""; }; 41 | /* End PBXFileReference section */ 42 | 43 | /* Begin PBXFrameworksBuildPhase section */ 44 | 9240D7831D0E6DD200B045BA /* Frameworks */ = { 45 | isa = PBXFrameworksBuildPhase; 46 | buildActionMask = 2147483647; 47 | files = ( 48 | ); 49 | runOnlyForDeploymentPostprocessing = 0; 50 | }; 51 | /* End PBXFrameworksBuildPhase section */ 52 | 53 | /* Begin PBXGroup section */ 54 | 9240D77D1D0E6DD200B045BA = { 55 | isa = PBXGroup; 56 | children = ( 57 | 9240D7881D0E6DD200B045BA /* HWLoadingAnimation */, 58 | 9240D79D1D0E6DD300B045BA /* HWLoadingAnimationTests */, 59 | 9240D7A81D0E6DD300B045BA /* HWLoadingAnimationUITests */, 60 | 9240D7871D0E6DD200B045BA /* Products */, 61 | ); 62 | sourceTree = ""; 63 | }; 64 | 9240D7871D0E6DD200B045BA /* Products */ = { 65 | isa = PBXGroup; 66 | children = ( 67 | 9240D7861D0E6DD200B045BA /* HWLoadingAnimation.app */, 68 | ); 69 | name = Products; 70 | sourceTree = ""; 71 | }; 72 | 9240D7881D0E6DD200B045BA /* HWLoadingAnimation */ = { 73 | isa = PBXGroup; 74 | children = ( 75 | 9240D7891D0E6DD300B045BA /* AppDelegate.swift */, 76 | 9240D78B1D0E6DD300B045BA /* ViewController.swift */, 77 | 9240D7B71D0E718100B045BA /* HWView */, 78 | 92C624B91D10168E005431AD /* Others */, 79 | 9240D78D1D0E6DD300B045BA /* Main.storyboard */, 80 | 9240D7901D0E6DD300B045BA /* Assets.xcassets */, 81 | 9240D7921D0E6DD300B045BA /* LaunchScreen.storyboard */, 82 | 9240D7951D0E6DD300B045BA /* Info.plist */, 83 | ); 84 | path = HWLoadingAnimation; 85 | sourceTree = ""; 86 | }; 87 | 9240D79D1D0E6DD300B045BA /* HWLoadingAnimationTests */ = { 88 | isa = PBXGroup; 89 | children = ( 90 | 9240D79E1D0E6DD300B045BA /* HWLoadingAnimationTests.swift */, 91 | 9240D7A01D0E6DD300B045BA /* Info.plist */, 92 | ); 93 | path = HWLoadingAnimationTests; 94 | sourceTree = ""; 95 | }; 96 | 9240D7A81D0E6DD300B045BA /* HWLoadingAnimationUITests */ = { 97 | isa = PBXGroup; 98 | children = ( 99 | 9240D7A91D0E6DD300B045BA /* HWLoadingAnimationUITests.swift */, 100 | 9240D7AB1D0E6DD300B045BA /* Info.plist */, 101 | ); 102 | path = HWLoadingAnimationUITests; 103 | sourceTree = ""; 104 | }; 105 | 9240D7B71D0E718100B045BA /* HWView */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | 92C624B71D101467005431AD /* AnimationView.swift */, 109 | 92C624AC1D10144D005431AD /* Layer */, 110 | ); 111 | path = HWView; 112 | sourceTree = ""; 113 | }; 114 | 92C624AC1D10144D005431AD /* Layer */ = { 115 | isa = PBXGroup; 116 | children = ( 117 | 92C624AE1D10144D005431AD /* CircleLayer.swift */, 118 | 92C624AF1D10144D005431AD /* RectangleLayer.swift */, 119 | 92C624B01D10144D005431AD /* TriangleLayer.swift */, 120 | 92C624B11D10144D005431AD /* WaveLayer.swift */, 121 | ); 122 | path = Layer; 123 | sourceTree = ""; 124 | }; 125 | 92C624B91D10168E005431AD /* Others */ = { 126 | isa = PBXGroup; 127 | children = ( 128 | 92C624C01D101F77005431AD /* Extension.swift */, 129 | ); 130 | path = Others; 131 | sourceTree = ""; 132 | }; 133 | /* End PBXGroup section */ 134 | 135 | /* Begin PBXNativeTarget section */ 136 | 9240D7851D0E6DD200B045BA /* HWLoadingAnimation */ = { 137 | isa = PBXNativeTarget; 138 | buildConfigurationList = 9240D7AE1D0E6DD300B045BA /* Build configuration list for PBXNativeTarget "HWLoadingAnimation" */; 139 | buildPhases = ( 140 | 9240D7821D0E6DD200B045BA /* Sources */, 141 | 9240D7831D0E6DD200B045BA /* Frameworks */, 142 | 9240D7841D0E6DD200B045BA /* Resources */, 143 | ); 144 | buildRules = ( 145 | ); 146 | dependencies = ( 147 | ); 148 | name = HWLoadingAnimation; 149 | productName = HWLoadingAnimation; 150 | productReference = 9240D7861D0E6DD200B045BA /* HWLoadingAnimation.app */; 151 | productType = "com.apple.product-type.application"; 152 | }; 153 | /* End PBXNativeTarget section */ 154 | 155 | /* Begin PBXProject section */ 156 | 9240D77E1D0E6DD200B045BA /* Project object */ = { 157 | isa = PBXProject; 158 | attributes = { 159 | LastSwiftUpdateCheck = 0730; 160 | LastUpgradeCheck = 0730; 161 | ORGANIZATIONNAME = HenryCheng; 162 | TargetAttributes = { 163 | 9240D7851D0E6DD200B045BA = { 164 | CreatedOnToolsVersion = 7.3.1; 165 | DevelopmentTeam = G49DMHKN44; 166 | LastSwiftMigration = 0800; 167 | }; 168 | }; 169 | }; 170 | buildConfigurationList = 9240D7811D0E6DD200B045BA /* Build configuration list for PBXProject "HWLoadingAnimation" */; 171 | compatibilityVersion = "Xcode 3.2"; 172 | developmentRegion = English; 173 | hasScannedForEncodings = 0; 174 | knownRegions = ( 175 | English, 176 | en, 177 | Base, 178 | ); 179 | mainGroup = 9240D77D1D0E6DD200B045BA; 180 | productRefGroup = 9240D7871D0E6DD200B045BA /* Products */; 181 | projectDirPath = ""; 182 | projectRoot = ""; 183 | targets = ( 184 | 9240D7851D0E6DD200B045BA /* HWLoadingAnimation */, 185 | ); 186 | }; 187 | /* End PBXProject section */ 188 | 189 | /* Begin PBXResourcesBuildPhase section */ 190 | 9240D7841D0E6DD200B045BA /* Resources */ = { 191 | isa = PBXResourcesBuildPhase; 192 | buildActionMask = 2147483647; 193 | files = ( 194 | 9240D7941D0E6DD300B045BA /* LaunchScreen.storyboard in Resources */, 195 | 9240D7911D0E6DD300B045BA /* Assets.xcassets in Resources */, 196 | 9240D78F1D0E6DD300B045BA /* Main.storyboard in Resources */, 197 | ); 198 | runOnlyForDeploymentPostprocessing = 0; 199 | }; 200 | /* End PBXResourcesBuildPhase section */ 201 | 202 | /* Begin PBXSourcesBuildPhase section */ 203 | 9240D7821D0E6DD200B045BA /* Sources */ = { 204 | isa = PBXSourcesBuildPhase; 205 | buildActionMask = 2147483647; 206 | files = ( 207 | 9240D78C1D0E6DD300B045BA /* ViewController.swift in Sources */, 208 | 92C624B81D101467005431AD /* AnimationView.swift in Sources */, 209 | 92C624B41D10144D005431AD /* RectangleLayer.swift in Sources */, 210 | 92C624B31D10144D005431AD /* CircleLayer.swift in Sources */, 211 | 92C624B51D10144D005431AD /* TriangleLayer.swift in Sources */, 212 | 9240D78A1D0E6DD300B045BA /* AppDelegate.swift in Sources */, 213 | 92C624B61D10144D005431AD /* WaveLayer.swift in Sources */, 214 | 92C624C11D101F77005431AD /* Extension.swift in Sources */, 215 | ); 216 | runOnlyForDeploymentPostprocessing = 0; 217 | }; 218 | /* End PBXSourcesBuildPhase section */ 219 | 220 | /* Begin PBXVariantGroup section */ 221 | 9240D78D1D0E6DD300B045BA /* Main.storyboard */ = { 222 | isa = PBXVariantGroup; 223 | children = ( 224 | 9240D78E1D0E6DD300B045BA /* Base */, 225 | ); 226 | name = Main.storyboard; 227 | sourceTree = ""; 228 | }; 229 | 9240D7921D0E6DD300B045BA /* LaunchScreen.storyboard */ = { 230 | isa = PBXVariantGroup; 231 | children = ( 232 | 9240D7931D0E6DD300B045BA /* Base */, 233 | ); 234 | name = LaunchScreen.storyboard; 235 | sourceTree = ""; 236 | }; 237 | /* End PBXVariantGroup section */ 238 | 239 | /* Begin XCBuildConfiguration section */ 240 | 9240D7AC1D0E6DD300B045BA /* Debug */ = { 241 | isa = XCBuildConfiguration; 242 | buildSettings = { 243 | ALWAYS_SEARCH_USER_PATHS = NO; 244 | CLANG_ANALYZER_NONNULL = YES; 245 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 246 | CLANG_CXX_LIBRARY = "libc++"; 247 | CLANG_ENABLE_MODULES = YES; 248 | CLANG_ENABLE_OBJC_ARC = YES; 249 | CLANG_WARN_BOOL_CONVERSION = YES; 250 | CLANG_WARN_CONSTANT_CONVERSION = YES; 251 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 252 | CLANG_WARN_EMPTY_BODY = YES; 253 | CLANG_WARN_ENUM_CONVERSION = YES; 254 | CLANG_WARN_INT_CONVERSION = YES; 255 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 256 | CLANG_WARN_UNREACHABLE_CODE = YES; 257 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 258 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 259 | COPY_PHASE_STRIP = NO; 260 | DEBUG_INFORMATION_FORMAT = dwarf; 261 | ENABLE_STRICT_OBJC_MSGSEND = YES; 262 | ENABLE_TESTABILITY = YES; 263 | GCC_C_LANGUAGE_STANDARD = gnu99; 264 | GCC_DYNAMIC_NO_PIC = NO; 265 | GCC_NO_COMMON_BLOCKS = YES; 266 | GCC_OPTIMIZATION_LEVEL = 0; 267 | GCC_PREPROCESSOR_DEFINITIONS = ( 268 | "DEBUG=1", 269 | "$(inherited)", 270 | ); 271 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 272 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 273 | GCC_WARN_UNDECLARED_SELECTOR = YES; 274 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 275 | GCC_WARN_UNUSED_FUNCTION = YES; 276 | GCC_WARN_UNUSED_VARIABLE = YES; 277 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 278 | MTL_ENABLE_DEBUG_INFO = YES; 279 | ONLY_ACTIVE_ARCH = YES; 280 | SDKROOT = iphoneos; 281 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 282 | TARGETED_DEVICE_FAMILY = "1,2"; 283 | }; 284 | name = Debug; 285 | }; 286 | 9240D7AD1D0E6DD300B045BA /* Release */ = { 287 | isa = XCBuildConfiguration; 288 | buildSettings = { 289 | ALWAYS_SEARCH_USER_PATHS = NO; 290 | CLANG_ANALYZER_NONNULL = YES; 291 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 292 | CLANG_CXX_LIBRARY = "libc++"; 293 | CLANG_ENABLE_MODULES = YES; 294 | CLANG_ENABLE_OBJC_ARC = YES; 295 | CLANG_WARN_BOOL_CONVERSION = YES; 296 | CLANG_WARN_CONSTANT_CONVERSION = YES; 297 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 298 | CLANG_WARN_EMPTY_BODY = YES; 299 | CLANG_WARN_ENUM_CONVERSION = YES; 300 | CLANG_WARN_INT_CONVERSION = YES; 301 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 302 | CLANG_WARN_UNREACHABLE_CODE = YES; 303 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 304 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 305 | COPY_PHASE_STRIP = NO; 306 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 307 | ENABLE_NS_ASSERTIONS = NO; 308 | ENABLE_STRICT_OBJC_MSGSEND = YES; 309 | GCC_C_LANGUAGE_STANDARD = gnu99; 310 | GCC_NO_COMMON_BLOCKS = YES; 311 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 312 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 313 | GCC_WARN_UNDECLARED_SELECTOR = YES; 314 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 315 | GCC_WARN_UNUSED_FUNCTION = YES; 316 | GCC_WARN_UNUSED_VARIABLE = YES; 317 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 318 | MTL_ENABLE_DEBUG_INFO = NO; 319 | SDKROOT = iphoneos; 320 | TARGETED_DEVICE_FAMILY = "1,2"; 321 | VALIDATE_PRODUCT = YES; 322 | }; 323 | name = Release; 324 | }; 325 | 9240D7AF1D0E6DD300B045BA /* Debug */ = { 326 | isa = XCBuildConfiguration; 327 | buildSettings = { 328 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 329 | CLANG_ENABLE_MODULES = YES; 330 | DEVELOPMENT_TEAM = G49DMHKN44; 331 | INFOPLIST_FILE = HWLoadingAnimation/Info.plist; 332 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 333 | PRODUCT_BUNDLE_IDENTIFIER = Loveway.HWLoadingAnimation; 334 | PRODUCT_NAME = "$(TARGET_NAME)"; 335 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 336 | SWIFT_VERSION = 5.0; 337 | }; 338 | name = Debug; 339 | }; 340 | 9240D7B01D0E6DD300B045BA /* Release */ = { 341 | isa = XCBuildConfiguration; 342 | buildSettings = { 343 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 344 | CLANG_ENABLE_MODULES = YES; 345 | DEVELOPMENT_TEAM = G49DMHKN44; 346 | INFOPLIST_FILE = HWLoadingAnimation/Info.plist; 347 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 348 | PRODUCT_BUNDLE_IDENTIFIER = Loveway.HWLoadingAnimation; 349 | PRODUCT_NAME = "$(TARGET_NAME)"; 350 | SWIFT_VERSION = 5.0; 351 | }; 352 | name = Release; 353 | }; 354 | /* End XCBuildConfiguration section */ 355 | 356 | /* Begin XCConfigurationList section */ 357 | 9240D7811D0E6DD200B045BA /* Build configuration list for PBXProject "HWLoadingAnimation" */ = { 358 | isa = XCConfigurationList; 359 | buildConfigurations = ( 360 | 9240D7AC1D0E6DD300B045BA /* Debug */, 361 | 9240D7AD1D0E6DD300B045BA /* Release */, 362 | ); 363 | defaultConfigurationIsVisible = 0; 364 | defaultConfigurationName = Release; 365 | }; 366 | 9240D7AE1D0E6DD300B045BA /* Build configuration list for PBXNativeTarget "HWLoadingAnimation" */ = { 367 | isa = XCConfigurationList; 368 | buildConfigurations = ( 369 | 9240D7AF1D0E6DD300B045BA /* Debug */, 370 | 9240D7B01D0E6DD300B045BA /* Release */, 371 | ); 372 | defaultConfigurationIsVisible = 0; 373 | defaultConfigurationName = Release; 374 | }; 375 | /* End XCConfigurationList section */ 376 | }; 377 | rootObject = 9240D77E1D0E6DD200B045BA /* Project object */; 378 | } 379 | -------------------------------------------------------------------------------- /HWLoadingAnimation-Swift/HWLoadingAnimation.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /HWLoadingAnimation-Swift/HWLoadingAnimation.xcodeproj/project.xcworkspace/xcuserdata/HenryCheng.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/loveway/HWLoadingAnimation/059dce17cfe534f839fbafd8f6f7ef600794b832/HWLoadingAnimation-Swift/HWLoadingAnimation.xcodeproj/project.xcworkspace/xcuserdata/HenryCheng.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /HWLoadingAnimation-Swift/HWLoadingAnimation.xcodeproj/project.xcworkspace/xcuserdata/chenghongwei.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/loveway/HWLoadingAnimation/059dce17cfe534f839fbafd8f6f7ef600794b832/HWLoadingAnimation-Swift/HWLoadingAnimation.xcodeproj/project.xcworkspace/xcuserdata/chenghongwei.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /HWLoadingAnimation-Swift/HWLoadingAnimation.xcodeproj/xcuserdata/HenryCheng.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /HWLoadingAnimation-Swift/HWLoadingAnimation.xcodeproj/xcuserdata/HenryCheng.xcuserdatad/xcschemes/HWLoadingAnimation.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 74 | 76 | 82 | 83 | 84 | 85 | 89 | 90 | 91 | 92 | 93 | 94 | 100 | 102 | 108 | 109 | 110 | 111 | 113 | 114 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /HWLoadingAnimation-Swift/HWLoadingAnimation.xcodeproj/xcuserdata/HenryCheng.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | HWLoadingAnimation.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 9240D7851D0E6DD200B045BA 16 | 17 | primary 18 | 19 | 20 | 9240D7991D0E6DD300B045BA 21 | 22 | primary 23 | 24 | 25 | 9240D7A41D0E6DD300B045BA 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /HWLoadingAnimation-Swift/HWLoadingAnimation.xcodeproj/xcuserdata/chenghongwei.xcuserdatad/xcschemes/HWLoadingAnimation.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 74 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /HWLoadingAnimation-Swift/HWLoadingAnimation.xcodeproj/xcuserdata/chenghongwei.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | HWLoadingAnimation.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 9240D7851D0E6DD200B045BA 16 | 17 | primary 18 | 19 | 20 | 9240D7991D0E6DD300B045BA 21 | 22 | primary 23 | 24 | 25 | 9240D7A41D0E6DD300B045BA 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /HWLoadingAnimation-Swift/HWLoadingAnimation/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // HWLoadingAnimation 4 | // 5 | // Created by HenryCheng on 16/6/13. 6 | // Copyright © 2016年 HenryCheng. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | private func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | private 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 throttle down OpenGL ES frame rates. Games should use this method to pause the game. 25 | } 26 | 27 | private 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 | private func applicationWillEnterForeground(application: UIApplication) { 33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | private 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 | private 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 | -------------------------------------------------------------------------------- /HWLoadingAnimation-Swift/HWLoadingAnimation/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 | } -------------------------------------------------------------------------------- /HWLoadingAnimation-Swift/HWLoadingAnimation/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 | -------------------------------------------------------------------------------- /HWLoadingAnimation-Swift/HWLoadingAnimation/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 | -------------------------------------------------------------------------------- /HWLoadingAnimation-Swift/HWLoadingAnimation/HWView/AnimationView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AnimationView.swift 3 | // HWLoadingAnimation 4 | // 5 | // Created by HenryCheng on 16/6/13. 6 | // Copyright © 2016年 HenryCheng. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | protocol AnimationViewDelegate: class { 12 | 13 | func completeAnimation() 14 | } 15 | 16 | class AnimationView: UIView { 17 | 18 | let circleLayer = CircleLayer() 19 | let triangleLayer = TriangleLayer() 20 | let redRectangleLayer = RectangleLayer() 21 | let blueRectangleLayer = RectangleLayer() 22 | let waveLayer = WaveLayer() 23 | var parentFrame: CGRect = CGRect.zero 24 | weak var delegate: AnimationViewDelegate? 25 | 26 | 27 | override init(frame: CGRect) { 28 | super.init(frame: frame) 29 | backgroundColor = UIColor.clear 30 | addCircleLayer() 31 | } 32 | 33 | required init?(coder aDecoder: NSCoder) { 34 | super.init(coder: aDecoder) 35 | } 36 | 37 | /** 38 | add circle layer 39 | */ 40 | func addCircleLayer() { 41 | self.layer.addSublayer(circleLayer) 42 | circleLayer.expand() 43 | Timer.scheduledTimer(timeInterval: 0.3, target: self, selector: #selector(wobbleCircleLayer), userInfo: nil, repeats: false) 44 | } 45 | 46 | /** 47 | circle layer wobble animation 48 | */ 49 | @objc func wobbleCircleLayer() { 50 | circleLayer.wobbleAnimate() 51 | layer.addSublayer(triangleLayer) 52 | Timer.scheduledTimer(timeInterval: 0.9, target: self, selector: #selector(showTriangleAnimation), userInfo: nil, repeats: false) 53 | } 54 | 55 | /** 56 | show triangle animation 57 | */ 58 | @objc func showTriangleAnimation() { 59 | triangleLayer.triangleAnimate() 60 | Timer.scheduledTimer(timeInterval: 0.9, target: self, selector: #selector(transformAnima), userInfo: nil, repeats: false) 61 | } 62 | 63 | /** 64 | self transform and add rectangle 65 | */ 66 | @objc func transformAnima() { 67 | transformRotationZ() 68 | circleLayer.contract() 69 | Timer.scheduledTimer(timeInterval: 0.45, target: self, selector: #selector(drawRedRectangleAnimation), userInfo: nil, repeats: false) 70 | Timer.scheduledTimer(timeInterval: 0.65, target: self, selector: #selector(drawBlueRectangleAnimation), userInfo: nil, repeats: false) 71 | } 72 | 73 | /** 74 | self transform z 75 | */ 76 | func transformRotationZ() { 77 | self.layer.anchorPoint = CGPoint(x: 0.5, y: 0.65) 78 | let rotationAnimation: CABasicAnimation = CABasicAnimation(keyPath: "transform.rotation.z") 79 | rotationAnimation.toValue = CGFloat(Double.pi * 2) 80 | rotationAnimation.duration = 0.45 81 | rotationAnimation.isRemovedOnCompletion = true 82 | layer.add(rotationAnimation, forKey: nil) 83 | } 84 | 85 | /** 86 | draw red stroke 87 | */ 88 | @objc func drawRedRectangleAnimation() { 89 | layer.addSublayer(redRectangleLayer) 90 | redRectangleLayer.strokeChangeWithColor(color: UIColor.colorWithHexString(hex: "#da70d6")) 91 | } 92 | 93 | /** 94 | draw blue stroke 95 | */ 96 | @objc func drawBlueRectangleAnimation() { 97 | layer.addSublayer(blueRectangleLayer) 98 | blueRectangleLayer.strokeChangeWithColor(color: UIColor.colorWithHexString(hex: "#40e0b0")) 99 | Timer.scheduledTimer(timeInterval: 0.4, target: self, selector: #selector(drawWaveAnimation), userInfo: nil, repeats: false) 100 | } 101 | 102 | @objc func drawWaveAnimation() { 103 | layer.addSublayer(waveLayer) 104 | waveLayer.animate() 105 | Timer.scheduledTimer(timeInterval: 0.9, target: self, selector: #selector(expandView), userInfo: nil, repeats: false) 106 | } 107 | 108 | @objc func expandView() { 109 | backgroundColor = UIColor.colorWithHexString(hex: "#40e0b0") 110 | frame = CGRect(x: frame.origin.x - blueRectangleLayer.lineWidth, 111 | y: frame.origin.y - blueRectangleLayer.lineWidth, 112 | width: frame.size.width + blueRectangleLayer.lineWidth * 2, 113 | height: frame.size.height + blueRectangleLayer.lineWidth * 2) 114 | layer.sublayers = nil 115 | 116 | UIView.animate(withDuration: 0.3, delay: 0.0, options: UIView.AnimationOptions.curveEaseInOut, animations: { 117 | self.frame = self.parentFrame 118 | }, completion: { finished in 119 | self.delegate?.completeAnimation() 120 | }) 121 | 122 | } 123 | 124 | } 125 | -------------------------------------------------------------------------------- /HWLoadingAnimation-Swift/HWLoadingAnimation/HWView/Layer/CircleLayer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CircleLayer.swift 3 | // HWLoadingAnimation 4 | // 5 | // Created by HenryCheng on 16/6/13. 6 | // Copyright © 2016年 HenryCheng. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class CircleLayer: CAShapeLayer { 12 | 13 | let KAnimationDuration: CFTimeInterval = 0.3 14 | let KAnimationBeginTime: CFTimeInterval = 0.0 15 | 16 | override init() { 17 | super.init() 18 | self.fillColor = UIColor.colorWithHexString(hex: "#da70d6").cgColor 19 | self.path = circleSmallPath.cgPath 20 | } 21 | 22 | required init?(coder aDecoder: NSCoder) { 23 | fatalError("init(coder:) has not been implemented") 24 | } 25 | 26 | /// begin path 27 | var circleSmallPath: UIBezierPath { 28 | return UIBezierPath(ovalIn: CGRect(x: 50.0, y: 50.0, width: 0.0, height: 0.0)) 29 | } 30 | /// end path 31 | var circleBigPath: UIBezierPath { 32 | return UIBezierPath(ovalIn: CGRect(x: 2.5, y: 17.5, width: 95.0, height: 95.0)) 33 | } 34 | /// the path squish circle on vertical 35 | var circleVerticalSquishPath: UIBezierPath { 36 | return UIBezierPath(ovalIn: CGRect(x: 2.5, y: 20.0, width: 95.0, height: 90.0)) 37 | } 38 | /// the path squish circle on horizontal 39 | var circleHorizontalSquishPath: UIBezierPath { 40 | return UIBezierPath(ovalIn: CGRect(x: 5.0, y: 20.0, width: 90.0, height: 90.0)) 41 | } 42 | 43 | /** 44 | wobbl group animation 45 | */ 46 | func wobbleAnimate() { 47 | // 1、animation begin from bigPath to verticalPath 48 | let animation1: CABasicAnimation = CABasicAnimation(keyPath: "path") 49 | animation1.fromValue = circleBigPath.cgPath 50 | animation1.toValue = circleVerticalSquishPath.cgPath 51 | animation1.beginTime = KAnimationBeginTime 52 | animation1.duration = KAnimationDuration 53 | 54 | // 2、animation vertical to horizontal 55 | let animation2: CABasicAnimation = CABasicAnimation(keyPath: "path") 56 | animation2.fromValue = circleVerticalSquishPath.cgPath 57 | animation2.toValue = circleHorizontalSquishPath.cgPath 58 | animation2.beginTime = animation1.beginTime + animation1.duration 59 | animation2.duration = KAnimationDuration 60 | 61 | // 3、animation horizontal to vertical 62 | let animation3: CABasicAnimation = CABasicAnimation(keyPath: "path") 63 | animation3.fromValue = circleHorizontalSquishPath.cgPath 64 | animation3.toValue = circleVerticalSquishPath.cgPath 65 | animation3.beginTime = animation2.beginTime + animation2.duration 66 | animation3.duration = KAnimationDuration 67 | 68 | // 4、animation vertical to bigPath 69 | let animation4: CABasicAnimation = CABasicAnimation(keyPath: "path") 70 | animation4.fromValue = circleVerticalSquishPath.cgPath 71 | animation4.toValue = circleBigPath.cgPath 72 | animation4.beginTime = animation3.beginTime + animation3.duration 73 | animation4.duration = KAnimationDuration 74 | 75 | // 5、group animation 76 | let animationGroup: CAAnimationGroup = CAAnimationGroup() 77 | animationGroup.animations = [animation1, animation2, animation3, animation4] 78 | animationGroup.duration = 4 * KAnimationDuration 79 | animationGroup.repeatCount = 2 80 | add(animationGroup, forKey: nil) 81 | 82 | } 83 | 84 | /** 85 | expand animation function 86 | */ 87 | func expand() { 88 | let expandAnimation: CABasicAnimation = CABasicAnimation(keyPath: "path") 89 | expandAnimation.fromValue = circleSmallPath.cgPath 90 | expandAnimation.toValue = circleBigPath.cgPath 91 | expandAnimation.duration = KAnimationDuration 92 | expandAnimation.fillMode = CAMediaTimingFillMode.forwards 93 | expandAnimation.isRemovedOnCompletion = false 94 | self.add(expandAnimation, forKey: nil) 95 | } 96 | 97 | /** 98 | contract animation function 99 | */ 100 | func contract() { 101 | let contractAnimation: CABasicAnimation = CABasicAnimation(keyPath: "path") 102 | contractAnimation.fromValue = circleBigPath.cgPath 103 | contractAnimation.toValue = circleSmallPath.cgPath 104 | contractAnimation.duration = KAnimationDuration 105 | contractAnimation.fillMode = CAMediaTimingFillMode.forwards 106 | contractAnimation.isRemovedOnCompletion = false 107 | add(contractAnimation, forKey: nil) 108 | } 109 | 110 | } 111 | -------------------------------------------------------------------------------- /HWLoadingAnimation-Swift/HWLoadingAnimation/HWView/Layer/RectangleLayer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RectangleLayer.swift 3 | // HWLoadingAnimation 4 | // 5 | // Created by HenryCheng on 16/6/13. 6 | // Copyright © 2016年 HenryCheng. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class RectangleLayer: CAShapeLayer { 12 | 13 | override init() { 14 | super.init() 15 | fillColor = UIColor.clear.cgColor 16 | lineWidth = 5.0 17 | path = rectangleFullPath.cgPath 18 | } 19 | 20 | required init?(coder aDecoder: NSCoder) { 21 | fatalError("init(coder:) has not been implemented") 22 | } 23 | 24 | var rectangleFullPath: UIBezierPath { 25 | let rectanglePath = UIBezierPath() 26 | rectanglePath.move(to: CGPoint(x: 0.0, y: 100.0)) 27 | rectanglePath.addLine(to: CGPoint(x: 0.0, y: -lineWidth)) 28 | rectanglePath.addLine(to: CGPoint(x: 100.0, y: -lineWidth)) 29 | rectanglePath.addLine(to: CGPoint(x: 100.0, y: 100.0)) 30 | rectanglePath.addLine(to: CGPoint(x: -lineWidth / 2, y: 100.0)) 31 | rectanglePath.close() 32 | return rectanglePath 33 | } 34 | 35 | /** 36 | line stroke color change with custom color 37 | 38 | - parameter color: custom color 39 | */ 40 | func strokeChangeWithColor(color: UIColor) { 41 | strokeColor = color.cgColor 42 | let strokeAnimation: CABasicAnimation = CABasicAnimation(keyPath: "strokeEnd") 43 | strokeAnimation.fromValue = 0.0 44 | strokeAnimation.toValue = 1.0 45 | strokeAnimation.duration = 0.4 46 | add(strokeAnimation, forKey: nil) 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /HWLoadingAnimation-Swift/HWLoadingAnimation/HWView/Layer/TriangleLayer.swift: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // TriangleLayer.swift 4 | // HWLoadingAnimation 5 | // 6 | // Created by HenryCheng on 16/6/13. 7 | // Copyright © 2016年 HenryCheng. All rights reserved. 8 | // 9 | 10 | import UIKit 11 | 12 | class TriangleLayer: CAShapeLayer { 13 | 14 | let paddingSpace: CGFloat = 30.0 15 | 16 | override init() { 17 | super.init() 18 | fillColor = UIColor.colorWithHexString(hex: "#da70d6").cgColor 19 | strokeColor = UIColor.colorWithHexString(hex: "#da70d6").cgColor 20 | lineWidth = 7.0 21 | lineCap = CAShapeLayerLineCap.round 22 | lineJoin = CAShapeLayerLineJoin.round 23 | path = smallTrianglePath.cgPath 24 | } 25 | 26 | required init?(coder aDecoder: NSCoder) { 27 | fatalError("init(coder:) has not been implemented") 28 | } 29 | 30 | var smallTrianglePath: UIBezierPath { 31 | let smallPath = UIBezierPath() 32 | smallPath.move(to: CGPoint(x: 5.0 + paddingSpace,y: 95.0)) 33 | smallPath.addLine(to: CGPoint(x: 50.0,y: 12.5 + paddingSpace)) 34 | smallPath.addLine(to: CGPoint(x: 95.0 - paddingSpace,y: 95.0)) 35 | smallPath.close() 36 | return smallPath 37 | } 38 | 39 | var leftTrianglePath: UIBezierPath { 40 | let trianglePath = UIBezierPath() 41 | trianglePath.move(to: CGPoint(x: 5.0, y: 95.0)) 42 | trianglePath.addLine(to: CGPoint(x: 50.0, y: 12.5 + paddingSpace)) 43 | trianglePath.addLine(to: CGPoint(x: 95.0 - paddingSpace, y: 95.0)) 44 | trianglePath.close() 45 | return trianglePath 46 | } 47 | 48 | var rightTrianglePath: UIBezierPath { 49 | let trianglePath = UIBezierPath() 50 | trianglePath.move(to: CGPoint(x: 5.0, y: 95.0)) 51 | trianglePath.addLine(to: CGPoint(x: 50.0, y: 12.5 + paddingSpace)) 52 | trianglePath.addLine(to: CGPoint(x: 95.0, y: 95.0)) 53 | trianglePath.close() 54 | return trianglePath 55 | } 56 | 57 | var topTrianglePath: UIBezierPath { 58 | let trianglePath = UIBezierPath() 59 | trianglePath.move(to: CGPoint(x: 5.0, y: 95.0)) 60 | trianglePath.addLine(to: CGPoint(x: 50.0, y: 12.5)) 61 | trianglePath.addLine(to: CGPoint(x: 95.0, y: 95.0)) 62 | trianglePath.close() 63 | return trianglePath 64 | } 65 | 66 | /** 67 | triangle animate function 68 | */ 69 | func triangleAnimate() { 70 | // left 71 | let triangleAnimationLeft: CABasicAnimation = CABasicAnimation(keyPath: "path") 72 | triangleAnimationLeft.fromValue = smallTrianglePath.cgPath 73 | triangleAnimationLeft.toValue = leftTrianglePath.cgPath 74 | triangleAnimationLeft.beginTime = 0.0 75 | triangleAnimationLeft.duration = 0.3 76 | // right 77 | let triangleAnimationRight: CABasicAnimation = CABasicAnimation(keyPath: "path") 78 | triangleAnimationRight.fromValue = leftTrianglePath.cgPath 79 | triangleAnimationRight.toValue = rightTrianglePath.cgPath 80 | triangleAnimationRight.beginTime = triangleAnimationLeft.beginTime + triangleAnimationLeft.duration 81 | triangleAnimationRight.duration = 0.25 82 | // top 83 | let triangleAnimationTop: CABasicAnimation = CABasicAnimation(keyPath: "path") 84 | triangleAnimationTop.fromValue = rightTrianglePath.cgPath 85 | triangleAnimationTop.toValue = topTrianglePath.cgPath 86 | triangleAnimationTop.beginTime = triangleAnimationRight.beginTime + triangleAnimationRight.duration 87 | triangleAnimationTop.duration = 0.20 88 | // group 89 | let triangleAnimationGroup: CAAnimationGroup = CAAnimationGroup() 90 | triangleAnimationGroup.animations = [triangleAnimationLeft, triangleAnimationRight, triangleAnimationTop] 91 | triangleAnimationGroup.duration = triangleAnimationTop.beginTime + triangleAnimationTop.duration 92 | triangleAnimationGroup.fillMode = CAMediaTimingFillMode.forwards 93 | triangleAnimationGroup.isRemovedOnCompletion = false 94 | add(triangleAnimationGroup, forKey: nil) 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /HWLoadingAnimation-Swift/HWLoadingAnimation/HWView/Layer/WaveLayer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WaveLayer.swift 3 | // HWLoadingAnimation 4 | // 5 | // Created by HenryCheng on 16/6/13. 6 | // Copyright © 2016年 HenryCheng. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class WaveLayer: CAShapeLayer { 12 | 13 | let KAnimationDuration: CFTimeInterval = 0.18 14 | 15 | override init() { 16 | super.init() 17 | fillColor = UIColor.colorWithHexString(hex: "#40e0b0").cgColor 18 | path = wavePathStarting.cgPath 19 | } 20 | 21 | required init?(coder aDecoder: NSCoder) { 22 | fatalError("init(coder:) has not been implemented") 23 | } 24 | 25 | var wavePathPre: UIBezierPath { 26 | let arcPath = UIBezierPath() 27 | arcPath.move(to: CGPoint(x: 0.0, y: 100.0)) 28 | arcPath.addLine(to: CGPoint(x: 0.0, y: 99.0)) 29 | arcPath.addLine(to: CGPoint(x: 100.0, y: 99.0)) 30 | arcPath.addLine(to: CGPoint(x: 100.0, y: 100.0)) 31 | arcPath.addLine(to: CGPoint(x: 0.0, y: 100.0)) 32 | arcPath.close() 33 | return arcPath 34 | } 35 | 36 | var wavePathStarting: UIBezierPath { 37 | let arcPath = UIBezierPath() 38 | arcPath.move(to: CGPoint(x: 0.0, y: 100.0)) 39 | arcPath.addLine(to: CGPoint(x: 0.0, y: 80.0)) 40 | arcPath.addCurve(to: CGPoint(x: 100.0, y: 80.0), controlPoint1: CGPoint(x: 30.0, y: 70.0), controlPoint2: CGPoint(x: 40.0, y: 90.0)) 41 | arcPath.addLine(to: CGPoint(x: 100.0, y: 100.0)) 42 | arcPath.addLine(to: CGPoint(x: 0.0, y: 100.0)) 43 | arcPath.close() 44 | return arcPath 45 | } 46 | 47 | var wavePathLow: UIBezierPath { 48 | let arcPath = UIBezierPath() 49 | arcPath.move(to: CGPoint(x: 0.0, y: 100.0)) 50 | arcPath.addLine(to: CGPoint(x: 0.0, y: 60.0)) 51 | arcPath.addCurve(to: CGPoint(x: 100.0, y: 60.0), controlPoint1: CGPoint(x: 30.0, y: 65.0), controlPoint2: CGPoint(x: 40.0, y: 50.0)) 52 | arcPath.addLine(to: CGPoint(x: 100.0, y: 100.0)) 53 | arcPath.addLine(to: CGPoint(x: 0.0, y: 100.0)) 54 | arcPath.close() 55 | return arcPath 56 | } 57 | 58 | var wavePathMid: UIBezierPath { 59 | let arcPath = UIBezierPath() 60 | arcPath.move(to: CGPoint(x: 0.0, y: 100.0)) 61 | arcPath.addLine(to: CGPoint(x: 0.0, y: 40.0)) 62 | arcPath.addCurve(to: CGPoint(x: 100.0, y: 40.0), controlPoint1: CGPoint(x: 30.0, y: 30.0), controlPoint2: CGPoint(x: 40.0, y: 50.0)) 63 | arcPath.addLine(to: CGPoint(x: 100.0, y: 100.0)) 64 | arcPath.addLine(to: CGPoint(x: 0.0, y: 100.0)) 65 | arcPath.close() 66 | return arcPath 67 | } 68 | 69 | var wavePathHigh: UIBezierPath { 70 | let arcPath = UIBezierPath() 71 | arcPath.move(to: CGPoint(x: 0.0, y: 100.0)) 72 | arcPath.addLine(to: CGPoint(x: 0.0, y: 20.0)) 73 | arcPath.addCurve(to: CGPoint(x: 100.0, y: 20.0), controlPoint1: CGPoint(x: 30.0, y: 25.0), controlPoint2: CGPoint(x: 40.0, y: 10.0)) 74 | arcPath.addLine(to: CGPoint(x: 100.0, y: 100.0)) 75 | arcPath.addLine(to: CGPoint(x: 0.0, y: 100.0)) 76 | arcPath.close() 77 | return arcPath 78 | } 79 | 80 | var wavePathComplete: UIBezierPath { 81 | let arcPath = UIBezierPath() 82 | arcPath.move(to: CGPoint(x: 0.0, y: 100.0)) 83 | arcPath.addLine(to: CGPoint(x: 0.0, y: -5.0)) 84 | arcPath.addLine(to: CGPoint(x: 100.0, y: -5.0)) 85 | arcPath.addLine(to: CGPoint(x: 100.0, y: 100.0)) 86 | arcPath.addLine(to: CGPoint(x: 0.0, y: 100.0)) 87 | arcPath.close() 88 | return arcPath 89 | } 90 | 91 | func animate() { 92 | /// 1 93 | let waveAnimationPre: CABasicAnimation = CABasicAnimation(keyPath: "path") 94 | waveAnimationPre.fromValue = wavePathPre.cgPath 95 | waveAnimationPre.toValue = wavePathStarting.cgPath 96 | waveAnimationPre.beginTime = 0.0 97 | waveAnimationPre.duration = KAnimationDuration 98 | /// 2 99 | let waveAnimationLow: CABasicAnimation = CABasicAnimation(keyPath: "path") 100 | waveAnimationLow.fromValue = wavePathStarting.cgPath 101 | waveAnimationLow.toValue = wavePathLow.cgPath 102 | waveAnimationLow.beginTime = waveAnimationPre.beginTime + waveAnimationPre.duration 103 | waveAnimationLow.duration = KAnimationDuration 104 | /// 3 105 | let waveAnimationMid: CABasicAnimation = CABasicAnimation(keyPath: "path") 106 | waveAnimationMid.fromValue = wavePathLow.cgPath 107 | waveAnimationMid.toValue = wavePathMid.cgPath 108 | waveAnimationMid.beginTime = waveAnimationLow.beginTime + waveAnimationLow.duration 109 | waveAnimationMid.duration = KAnimationDuration 110 | /// 4 111 | let waveAnimationHigh: CABasicAnimation = CABasicAnimation(keyPath: "path") 112 | waveAnimationHigh.fromValue = wavePathMid.cgPath 113 | waveAnimationHigh.toValue = wavePathHigh.cgPath 114 | waveAnimationHigh.beginTime = waveAnimationMid.beginTime + waveAnimationMid.duration 115 | waveAnimationHigh.duration = KAnimationDuration 116 | /// 5 117 | let waveAnimationComplete: CABasicAnimation = CABasicAnimation(keyPath: "path") 118 | waveAnimationComplete.fromValue = wavePathHigh.cgPath 119 | waveAnimationComplete.toValue = wavePathComplete.cgPath 120 | waveAnimationComplete.beginTime = waveAnimationHigh.beginTime + waveAnimationHigh.duration 121 | waveAnimationComplete.duration = KAnimationDuration 122 | /// group animation 123 | let arcAnimationGroup: CAAnimationGroup = CAAnimationGroup() 124 | arcAnimationGroup.animations = [waveAnimationPre, waveAnimationLow, waveAnimationMid, waveAnimationHigh, waveAnimationComplete] 125 | arcAnimationGroup.duration = waveAnimationComplete.beginTime + waveAnimationComplete.duration 126 | arcAnimationGroup.fillMode = CAMediaTimingFillMode.forwards 127 | arcAnimationGroup.isRemovedOnCompletion = false 128 | add(arcAnimationGroup, forKey: nil) 129 | } 130 | 131 | } 132 | -------------------------------------------------------------------------------- /HWLoadingAnimation-Swift/HWLoadingAnimation/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.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 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /HWLoadingAnimation-Swift/HWLoadingAnimation/Others/Extension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Extension.swift 3 | // HWLoadingAnimation 4 | // 5 | // Created by HenryCheng on 16/6/14. 6 | // Copyright © 2016年 HenryCheng. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | extension UIColor { 13 | 14 | /** 15 | Make color with hex string 16 | 17 | - parameter hex: hex string 18 | 19 | - returns: new color 20 | */ 21 | static func colorWithHexString (hex: String) -> UIColor { 22 | 23 | var cString: String = hex.trimmingCharacters(in: NSCharacterSet.whitespacesAndNewlines).uppercased() 24 | 25 | if (cString.hasPrefix("#")) { 26 | cString = (cString as NSString).substring(from: 1) 27 | } 28 | 29 | if (cString.count != 6) { 30 | return UIColor.gray 31 | } 32 | 33 | let rString = (cString as NSString).substring(to: 2) 34 | let gString = ((cString as NSString).substring(from: 2) as NSString).substring(to: 2) 35 | let bString = ((cString as NSString).substring(from: 4) as NSString).substring(to: 2) 36 | 37 | var r:CUnsignedInt = 0, g:CUnsignedInt = 0, b:CUnsignedInt = 0; 38 | Scanner(string: rString).scanHexInt32(&r) 39 | Scanner(string: gString).scanHexInt32(&g) 40 | Scanner(string: bString).scanHexInt32(&b) 41 | 42 | 43 | return UIColor(red: CGFloat(r) / 255.0, green: CGFloat(g) / 255.0, blue: CGFloat(b) / 255.0, alpha: CGFloat(1)) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /HWLoadingAnimation-Swift/HWLoadingAnimation/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // HWLoadingAnimation 4 | // 5 | // Created by HenryCheng on 16/6/13. 6 | // Copyright © 2016年 HenryCheng. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController, AnimationViewDelegate { 12 | 13 | var animationView = AnimationView(frame: CGRect.zero) 14 | 15 | 16 | override func viewDidLoad() { 17 | super.viewDidLoad() 18 | } 19 | 20 | override func viewDidAppear(_ animated: Bool) { 21 | super.viewDidAppear(animated) 22 | addAnimationView() 23 | } 24 | 25 | /** 26 | add animationView and red circle layer 27 | */ 28 | func addAnimationView() { 29 | let size: CGFloat = 100.0 30 | animationView.frame = CGRect(x: self.view.frame.width/2 - size/2, y: self.view.frame.height/2 - size/2,width: size,height: size) 31 | animationView.parentFrame = view.frame 32 | animationView.delegate = self 33 | view.addSubview(animationView) 34 | } 35 | 36 | // MARK: - 37 | // MARK: AnimationViewDelegate 38 | func completeAnimation() { 39 | // 1 40 | animationView.removeFromSuperview() 41 | view.backgroundColor = UIColor.colorWithHexString(hex: "#40e0b0") 42 | 43 | // 2 44 | let label: UILabel = UILabel(frame: view.frame) 45 | label.textColor = UIColor.white 46 | label.font = UIFont(name: "HelveticaNeue-Thin", size: 50.0) 47 | label.textAlignment = NSTextAlignment.center 48 | label.text = "Welcome" 49 | label.transform = label.transform.scaledBy(x: 0.25, y: 0.25) 50 | view.addSubview(label) 51 | 52 | // 3 53 | UIView.animate(withDuration: 0.4, delay: 0.0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.1, options: UIView.AnimationOptions.curveEaseInOut,animations: ({ 54 | 55 | label.transform = label.transform.scaledBy(x: 4.0, y: 4.0) 56 | }), completion: { finished in 57 | self.addTouchButton() 58 | }) 59 | 60 | } 61 | 62 | func addTouchButton() { 63 | let button = UIButton() 64 | button.frame = CGRect(x: 0.0,y: 0.0,width: view.bounds.width,height: view.bounds.height) 65 | button.addTarget(self, action: #selector(btnClick), for: .touchUpInside) 66 | view.addSubview(button) 67 | } 68 | 69 | @objc func btnClick() { 70 | view.backgroundColor = UIColor.white 71 | view.subviews.forEach { ( 72 | $0.removeFromSuperview() 73 | )} 74 | animationView = AnimationView(frame: CGRect.zero) 75 | addAnimationView() 76 | } 77 | 78 | override func didReceiveMemoryWarning() { 79 | super.didReceiveMemoryWarning() 80 | // Dispose of any resources that can be recreated. 81 | } 82 | 83 | 84 | } 85 | 86 | -------------------------------------------------------------------------------- /HWLoadingAnimation-Swift/HWLoadingAnimationTests/HWLoadingAnimationTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HWLoadingAnimationTests.swift 3 | // HWLoadingAnimationTests 4 | // 5 | // Created by HenryCheng on 16/6/13. 6 | // Copyright © 2016年 HenryCheng. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import HWLoadingAnimation 11 | 12 | class HWLoadingAnimationTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | // Use XCTAssert and related functions to verify your tests produce the correct results. 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measureBlock { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /HWLoadingAnimation-Swift/HWLoadingAnimationTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /HWLoadingAnimation-Swift/HWLoadingAnimationUITests/HWLoadingAnimationUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HWLoadingAnimationUITests.swift 3 | // HWLoadingAnimationUITests 4 | // 5 | // Created by HenryCheng on 16/6/13. 6 | // Copyright © 2016年 HenryCheng. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class HWLoadingAnimationUITests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | 18 | // In UI tests it is usually best to stop immediately when a failure occurs. 19 | continueAfterFailure = false 20 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 21 | XCUIApplication().launch() 22 | 23 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 24 | } 25 | 26 | override func tearDown() { 27 | // Put teardown code here. This method is called after the invocation of each test method in the class. 28 | super.tearDown() 29 | } 30 | 31 | func testExample() { 32 | // Use recording to get started writing UI tests. 33 | // Use XCTAssert and related functions to verify your tests produce the correct results. 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /HWLoadingAnimation-Swift/HWLoadingAnimationUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HWLoadingAnimation 2 | Animation for loading (complete with Objective-C & Swift) 3 | 4 | **最新Flutter实现可见 [Flutter动画](https://github.com/loveway/flutter_loading_animation)** 5 | 6 | 用 `OC` 和 `Swift` 实现的一个炫酷的 `Loading` 动画的详细分析,详情请见 [我的简书](http://www.jianshu.com/p/658641c77f51) 7 | ,效果如下 8 | 9 | ![](https://github.com/Loveway/HWLoadingAnimation/blob/master/HWLoadingAnimation-OC/HWLoadingAnimation.gif) 10 | 11 | 12 | 13 | > 原效果出处 [How to Create a Complex Loading Animation in Swift](https://www.raywenderlich.com/1746-how-to-create-a-complex-loading-animation-in-swift) 14 | 15 | --------------------------------------------------------------------------------