├── .gitignore ├── .travis.yml ├── Example ├── MaterialActivityIndicator.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ ├── Example.xcscheme │ │ └── ExampleTV.xcscheme ├── MaterialActivityIndicator.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── MaterialActivityIndicator │ ├── AppDelegate.swift │ ├── Base.lproj │ │ ├── LaunchScreen.xib │ │ └── Main.storyboard │ ├── DemoViewController.swift │ └── Info.plist ├── MaterialActivityIndicatorTV │ ├── AppDelegate.swift │ ├── Base.lproj │ │ └── Main.storyboard │ └── Info.plist ├── Podfile └── Podfile.lock ├── LICENSE ├── MaterialActivityIndicator.podspec ├── Package.swift ├── README.md ├── Sources └── MaterialActivityIndicator │ ├── Extensions │ ├── CAPropertyAnimation+Key.swift │ ├── CGRect+Center.swift │ ├── CGSize+Min.swift │ └── UIBezierPath+Circle.swift │ ├── MaterialActivityIndicator.swift │ └── MaterialActivityIndicatorAnimator.swift └── preview.gif /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata/ 15 | *.xccheckout 16 | profile 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | 22 | # Bundler 23 | .bundle 24 | 25 | Carthage/Build 26 | Pods/ 27 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | osx_image: xcode12 2 | language: objective-c 3 | cache: cocoapods 4 | podfile: Example/Podfile 5 | 6 | before_install: 7 | - gem install cocoapods 8 | - pod install --project-directory=Example 9 | 10 | before_script: 11 | - swiftlint 12 | 13 | script: 14 | - set -o pipefail && xcodebuild -workspace Example/MaterialActivityIndicator.xcworkspace -scheme Example -sdk iphonesimulator14.0 ONLY_ACTIVE_ARCH=NO | xcpretty 15 | - pod lib lint --swift-version=5.3 16 | -------------------------------------------------------------------------------- /Example/MaterialActivityIndicator.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 3D3F31A9223AF598007A795A /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D3F31A8223AF598007A795A /* AppDelegate.swift */; }; 11 | 3D3F31AE223AF598007A795A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3D3F31AC223AF598007A795A /* Main.storyboard */; }; 12 | 3D3F31B5223AF5CF007A795A /* DemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* DemoViewController.swift */; }; 13 | 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; }; 14 | 607FACD81AFB9204008FA782 /* DemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* DemoViewController.swift */; }; 15 | 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607FACD91AFB9204008FA782 /* Main.storyboard */; }; 16 | 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; }; 17 | ACB36BAAE13FCBFF7F7EB2D2 /* Pods_MaterialActivityIndicatorTV_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3E0523A9FEED9F330F1D3A56 /* Pods_MaterialActivityIndicatorTV_Example.framework */; }; 18 | B8169754EBE76B43F46BAC8E /* Pods_MaterialActivityIndicator_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 27C381CEF92A5D2F87083898 /* Pods_MaterialActivityIndicator_Example.framework */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXFileReference section */ 22 | 00A12C36336061C79307F22C /* MaterialActivityIndicator.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = MaterialActivityIndicator.podspec; path = ../MaterialActivityIndicator.podspec; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 23 | 27C381CEF92A5D2F87083898 /* Pods_MaterialActivityIndicator_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MaterialActivityIndicator_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 24 | 2E935D60F8A3FECE56FCDCA4 /* Pods-MaterialActivityIndicator_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MaterialActivityIndicator_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-MaterialActivityIndicator_Example/Pods-MaterialActivityIndicator_Example.debug.xcconfig"; sourceTree = ""; }; 25 | 35ECD74E8F2A7A73C3A87D2E /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; 26 | 3D3F31A6223AF597007A795A /* MaterialActivityIndicatorTV_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MaterialActivityIndicatorTV_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 27 | 3D3F31A8223AF598007A795A /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 28 | 3D3F31AD223AF598007A795A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 29 | 3D3F31B1223AF599007A795A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 30 | 3E0523A9FEED9F330F1D3A56 /* Pods_MaterialActivityIndicatorTV_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MaterialActivityIndicatorTV_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 31 | 421C223690CE3B79E69BA5D3 /* Pods-MaterialActivityIndicator_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MaterialActivityIndicator_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-MaterialActivityIndicator_Example/Pods-MaterialActivityIndicator_Example.release.xcconfig"; sourceTree = ""; }; 32 | 607FACD01AFB9204008FA782 /* MaterialActivityIndicator_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MaterialActivityIndicator_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 33 | 607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 34 | 607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 35 | 607FACD71AFB9204008FA782 /* DemoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoViewController.swift; sourceTree = ""; }; 36 | 607FACDA1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 37 | 607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 38 | 9E4CFC6CB40029FE7B110EB9 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; 39 | A92DE428CC8B12F038E38C74 /* Pods-MaterialActivityIndicatorTV_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MaterialActivityIndicatorTV_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-MaterialActivityIndicatorTV_Example/Pods-MaterialActivityIndicatorTV_Example.debug.xcconfig"; sourceTree = ""; }; 40 | F15DC3BE43013A5D6C8358CF /* Pods-MaterialActivityIndicatorTV_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MaterialActivityIndicatorTV_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-MaterialActivityIndicatorTV_Example/Pods-MaterialActivityIndicatorTV_Example.release.xcconfig"; sourceTree = ""; }; 41 | /* End PBXFileReference section */ 42 | 43 | /* Begin PBXFrameworksBuildPhase section */ 44 | 3D3F31A3223AF597007A795A /* Frameworks */ = { 45 | isa = PBXFrameworksBuildPhase; 46 | buildActionMask = 2147483647; 47 | files = ( 48 | ACB36BAAE13FCBFF7F7EB2D2 /* Pods_MaterialActivityIndicatorTV_Example.framework in Frameworks */, 49 | ); 50 | runOnlyForDeploymentPostprocessing = 0; 51 | }; 52 | 607FACCD1AFB9204008FA782 /* Frameworks */ = { 53 | isa = PBXFrameworksBuildPhase; 54 | buildActionMask = 2147483647; 55 | files = ( 56 | B8169754EBE76B43F46BAC8E /* Pods_MaterialActivityIndicator_Example.framework in Frameworks */, 57 | ); 58 | runOnlyForDeploymentPostprocessing = 0; 59 | }; 60 | /* End PBXFrameworksBuildPhase section */ 61 | 62 | /* Begin PBXGroup section */ 63 | 3D3F31A7223AF598007A795A /* ExampleTV */ = { 64 | isa = PBXGroup; 65 | children = ( 66 | 3D3F31A8223AF598007A795A /* AppDelegate.swift */, 67 | 3D3F31AC223AF598007A795A /* Main.storyboard */, 68 | 3D3F31B1223AF599007A795A /* Info.plist */, 69 | ); 70 | name = ExampleTV; 71 | path = MaterialActivityIndicatorTV; 72 | sourceTree = ""; 73 | }; 74 | 607FACC71AFB9204008FA782 = { 75 | isa = PBXGroup; 76 | children = ( 77 | 607FACF51AFB993E008FA782 /* Podspec Metadata */, 78 | 607FACD21AFB9204008FA782 /* Example */, 79 | 3D3F31A7223AF598007A795A /* ExampleTV */, 80 | 607FACD11AFB9204008FA782 /* Products */, 81 | 949A0DEFB0AB224057B5DF80 /* Pods */, 82 | 6A322E92B396F81202B56B47 /* Frameworks */, 83 | ); 84 | sourceTree = ""; 85 | }; 86 | 607FACD11AFB9204008FA782 /* Products */ = { 87 | isa = PBXGroup; 88 | children = ( 89 | 607FACD01AFB9204008FA782 /* MaterialActivityIndicator_Example.app */, 90 | 3D3F31A6223AF597007A795A /* MaterialActivityIndicatorTV_Example.app */, 91 | ); 92 | name = Products; 93 | sourceTree = ""; 94 | }; 95 | 607FACD21AFB9204008FA782 /* Example */ = { 96 | isa = PBXGroup; 97 | children = ( 98 | 607FACD51AFB9204008FA782 /* AppDelegate.swift */, 99 | 607FACD71AFB9204008FA782 /* DemoViewController.swift */, 100 | 607FACD91AFB9204008FA782 /* Main.storyboard */, 101 | 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */, 102 | 607FACD31AFB9204008FA782 /* Supporting Files */, 103 | ); 104 | name = Example; 105 | path = MaterialActivityIndicator; 106 | sourceTree = ""; 107 | }; 108 | 607FACD31AFB9204008FA782 /* Supporting Files */ = { 109 | isa = PBXGroup; 110 | children = ( 111 | 607FACD41AFB9204008FA782 /* Info.plist */, 112 | ); 113 | name = "Supporting Files"; 114 | sourceTree = ""; 115 | }; 116 | 607FACF51AFB993E008FA782 /* Podspec Metadata */ = { 117 | isa = PBXGroup; 118 | children = ( 119 | 00A12C36336061C79307F22C /* MaterialActivityIndicator.podspec */, 120 | 9E4CFC6CB40029FE7B110EB9 /* README.md */, 121 | 35ECD74E8F2A7A73C3A87D2E /* LICENSE */, 122 | ); 123 | name = "Podspec Metadata"; 124 | sourceTree = ""; 125 | }; 126 | 6A322E92B396F81202B56B47 /* Frameworks */ = { 127 | isa = PBXGroup; 128 | children = ( 129 | 27C381CEF92A5D2F87083898 /* Pods_MaterialActivityIndicator_Example.framework */, 130 | 3E0523A9FEED9F330F1D3A56 /* Pods_MaterialActivityIndicatorTV_Example.framework */, 131 | ); 132 | name = Frameworks; 133 | sourceTree = ""; 134 | }; 135 | 949A0DEFB0AB224057B5DF80 /* Pods */ = { 136 | isa = PBXGroup; 137 | children = ( 138 | 2E935D60F8A3FECE56FCDCA4 /* Pods-MaterialActivityIndicator_Example.debug.xcconfig */, 139 | 421C223690CE3B79E69BA5D3 /* Pods-MaterialActivityIndicator_Example.release.xcconfig */, 140 | A92DE428CC8B12F038E38C74 /* Pods-MaterialActivityIndicatorTV_Example.debug.xcconfig */, 141 | F15DC3BE43013A5D6C8358CF /* Pods-MaterialActivityIndicatorTV_Example.release.xcconfig */, 142 | ); 143 | name = Pods; 144 | sourceTree = ""; 145 | }; 146 | /* End PBXGroup section */ 147 | 148 | /* Begin PBXNativeTarget section */ 149 | 3D3F31A5223AF597007A795A /* MaterialActivityIndicatorTV_Example */ = { 150 | isa = PBXNativeTarget; 151 | buildConfigurationList = 3D3F31B2223AF599007A795A /* Build configuration list for PBXNativeTarget "MaterialActivityIndicatorTV_Example" */; 152 | buildPhases = ( 153 | 8886D2A5BDA7FC36AC87C585 /* [CP] Check Pods Manifest.lock */, 154 | 3D3F31A2223AF597007A795A /* Sources */, 155 | 3D3F31A3223AF597007A795A /* Frameworks */, 156 | 3D3F31A4223AF597007A795A /* Resources */, 157 | 238A072FB93DC781B889FE19 /* [CP] Embed Pods Frameworks */, 158 | ); 159 | buildRules = ( 160 | ); 161 | dependencies = ( 162 | ); 163 | name = MaterialActivityIndicatorTV_Example; 164 | productName = MaterialActivityIndicatorTV_Example; 165 | productReference = 3D3F31A6223AF597007A795A /* MaterialActivityIndicatorTV_Example.app */; 166 | productType = "com.apple.product-type.application"; 167 | }; 168 | 607FACCF1AFB9204008FA782 /* MaterialActivityIndicator_Example */ = { 169 | isa = PBXNativeTarget; 170 | buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "MaterialActivityIndicator_Example" */; 171 | buildPhases = ( 172 | 443360B64CED91957521391D /* [CP] Check Pods Manifest.lock */, 173 | 607FACCC1AFB9204008FA782 /* Sources */, 174 | 607FACCD1AFB9204008FA782 /* Frameworks */, 175 | 607FACCE1AFB9204008FA782 /* Resources */, 176 | 0E59C7CCBB51E698D49CE1C5 /* [CP] Embed Pods Frameworks */, 177 | 3DEA3BE920334884007691F8 /* ShellScript */, 178 | ); 179 | buildRules = ( 180 | ); 181 | dependencies = ( 182 | ); 183 | name = MaterialActivityIndicator_Example; 184 | productName = MaterialActivityIndicator; 185 | productReference = 607FACD01AFB9204008FA782 /* MaterialActivityIndicator_Example.app */; 186 | productType = "com.apple.product-type.application"; 187 | }; 188 | /* End PBXNativeTarget section */ 189 | 190 | /* Begin PBXProject section */ 191 | 607FACC81AFB9204008FA782 /* Project object */ = { 192 | isa = PBXProject; 193 | attributes = { 194 | LastSwiftUpdateCheck = 1010; 195 | LastUpgradeCheck = 1100; 196 | ORGANIZATIONNAME = CocoaPods; 197 | TargetAttributes = { 198 | 3D3F31A5223AF597007A795A = { 199 | CreatedOnToolsVersion = 10.1; 200 | DevelopmentTeam = 2QLBXZ66VC; 201 | ProvisioningStyle = Automatic; 202 | }; 203 | 607FACCF1AFB9204008FA782 = { 204 | CreatedOnToolsVersion = 6.3.1; 205 | LastSwiftMigration = 1010; 206 | }; 207 | }; 208 | }; 209 | buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "MaterialActivityIndicator" */; 210 | compatibilityVersion = "Xcode 3.2"; 211 | developmentRegion = en; 212 | hasScannedForEncodings = 0; 213 | knownRegions = ( 214 | en, 215 | Base, 216 | ); 217 | mainGroup = 607FACC71AFB9204008FA782; 218 | productRefGroup = 607FACD11AFB9204008FA782 /* Products */; 219 | projectDirPath = ""; 220 | projectRoot = ""; 221 | targets = ( 222 | 607FACCF1AFB9204008FA782 /* MaterialActivityIndicator_Example */, 223 | 3D3F31A5223AF597007A795A /* MaterialActivityIndicatorTV_Example */, 224 | ); 225 | }; 226 | /* End PBXProject section */ 227 | 228 | /* Begin PBXResourcesBuildPhase section */ 229 | 3D3F31A4223AF597007A795A /* Resources */ = { 230 | isa = PBXResourcesBuildPhase; 231 | buildActionMask = 2147483647; 232 | files = ( 233 | 3D3F31AE223AF598007A795A /* Main.storyboard in Resources */, 234 | ); 235 | runOnlyForDeploymentPostprocessing = 0; 236 | }; 237 | 607FACCE1AFB9204008FA782 /* Resources */ = { 238 | isa = PBXResourcesBuildPhase; 239 | buildActionMask = 2147483647; 240 | files = ( 241 | 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */, 242 | 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */, 243 | ); 244 | runOnlyForDeploymentPostprocessing = 0; 245 | }; 246 | /* End PBXResourcesBuildPhase section */ 247 | 248 | /* Begin PBXShellScriptBuildPhase section */ 249 | 0E59C7CCBB51E698D49CE1C5 /* [CP] Embed Pods Frameworks */ = { 250 | isa = PBXShellScriptBuildPhase; 251 | buildActionMask = 2147483647; 252 | files = ( 253 | ); 254 | inputPaths = ( 255 | "${PODS_ROOT}/Target Support Files/Pods-MaterialActivityIndicator_Example/Pods-MaterialActivityIndicator_Example-frameworks.sh", 256 | "${BUILT_PRODUCTS_DIR}/MaterialActivityIndicator/MaterialActivityIndicator.framework", 257 | ); 258 | name = "[CP] Embed Pods Frameworks"; 259 | outputPaths = ( 260 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MaterialActivityIndicator.framework", 261 | ); 262 | runOnlyForDeploymentPostprocessing = 0; 263 | shellPath = /bin/sh; 264 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-MaterialActivityIndicator_Example/Pods-MaterialActivityIndicator_Example-frameworks.sh\"\n"; 265 | showEnvVarsInLog = 0; 266 | }; 267 | 238A072FB93DC781B889FE19 /* [CP] Embed Pods Frameworks */ = { 268 | isa = PBXShellScriptBuildPhase; 269 | buildActionMask = 2147483647; 270 | files = ( 271 | ); 272 | inputPaths = ( 273 | "${PODS_ROOT}/Target Support Files/Pods-MaterialActivityIndicatorTV_Example/Pods-MaterialActivityIndicatorTV_Example-frameworks.sh", 274 | "${BUILT_PRODUCTS_DIR}/MaterialActivityIndicator/MaterialActivityIndicator.framework", 275 | ); 276 | name = "[CP] Embed Pods Frameworks"; 277 | outputPaths = ( 278 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MaterialActivityIndicator.framework", 279 | ); 280 | runOnlyForDeploymentPostprocessing = 0; 281 | shellPath = /bin/sh; 282 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-MaterialActivityIndicatorTV_Example/Pods-MaterialActivityIndicatorTV_Example-frameworks.sh\"\n"; 283 | showEnvVarsInLog = 0; 284 | }; 285 | 3DEA3BE920334884007691F8 /* ShellScript */ = { 286 | isa = PBXShellScriptBuildPhase; 287 | buildActionMask = 2147483647; 288 | files = ( 289 | ); 290 | inputPaths = ( 291 | ); 292 | outputPaths = ( 293 | ); 294 | runOnlyForDeploymentPostprocessing = 0; 295 | shellPath = /bin/sh; 296 | shellScript = "${PODS_ROOT}/SwiftLint/swiftlint"; 297 | }; 298 | 443360B64CED91957521391D /* [CP] Check Pods Manifest.lock */ = { 299 | isa = PBXShellScriptBuildPhase; 300 | buildActionMask = 2147483647; 301 | files = ( 302 | ); 303 | inputPaths = ( 304 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 305 | "${PODS_ROOT}/Manifest.lock", 306 | ); 307 | name = "[CP] Check Pods Manifest.lock"; 308 | outputPaths = ( 309 | "$(DERIVED_FILE_DIR)/Pods-MaterialActivityIndicator_Example-checkManifestLockResult.txt", 310 | ); 311 | runOnlyForDeploymentPostprocessing = 0; 312 | shellPath = /bin/sh; 313 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 314 | showEnvVarsInLog = 0; 315 | }; 316 | 8886D2A5BDA7FC36AC87C585 /* [CP] Check Pods Manifest.lock */ = { 317 | isa = PBXShellScriptBuildPhase; 318 | buildActionMask = 2147483647; 319 | files = ( 320 | ); 321 | inputFileListPaths = ( 322 | ); 323 | inputPaths = ( 324 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 325 | "${PODS_ROOT}/Manifest.lock", 326 | ); 327 | name = "[CP] Check Pods Manifest.lock"; 328 | outputFileListPaths = ( 329 | ); 330 | outputPaths = ( 331 | "$(DERIVED_FILE_DIR)/Pods-MaterialActivityIndicatorTV_Example-checkManifestLockResult.txt", 332 | ); 333 | runOnlyForDeploymentPostprocessing = 0; 334 | shellPath = /bin/sh; 335 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 336 | showEnvVarsInLog = 0; 337 | }; 338 | /* End PBXShellScriptBuildPhase section */ 339 | 340 | /* Begin PBXSourcesBuildPhase section */ 341 | 3D3F31A2223AF597007A795A /* Sources */ = { 342 | isa = PBXSourcesBuildPhase; 343 | buildActionMask = 2147483647; 344 | files = ( 345 | 3D3F31A9223AF598007A795A /* AppDelegate.swift in Sources */, 346 | 3D3F31B5223AF5CF007A795A /* DemoViewController.swift in Sources */, 347 | ); 348 | runOnlyForDeploymentPostprocessing = 0; 349 | }; 350 | 607FACCC1AFB9204008FA782 /* Sources */ = { 351 | isa = PBXSourcesBuildPhase; 352 | buildActionMask = 2147483647; 353 | files = ( 354 | 607FACD81AFB9204008FA782 /* DemoViewController.swift in Sources */, 355 | 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */, 356 | ); 357 | runOnlyForDeploymentPostprocessing = 0; 358 | }; 359 | /* End PBXSourcesBuildPhase section */ 360 | 361 | /* Begin PBXVariantGroup section */ 362 | 3D3F31AC223AF598007A795A /* Main.storyboard */ = { 363 | isa = PBXVariantGroup; 364 | children = ( 365 | 3D3F31AD223AF598007A795A /* Base */, 366 | ); 367 | name = Main.storyboard; 368 | sourceTree = ""; 369 | }; 370 | 607FACD91AFB9204008FA782 /* Main.storyboard */ = { 371 | isa = PBXVariantGroup; 372 | children = ( 373 | 607FACDA1AFB9204008FA782 /* Base */, 374 | ); 375 | name = Main.storyboard; 376 | sourceTree = ""; 377 | }; 378 | 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */ = { 379 | isa = PBXVariantGroup; 380 | children = ( 381 | 607FACDF1AFB9204008FA782 /* Base */, 382 | ); 383 | name = LaunchScreen.xib; 384 | sourceTree = ""; 385 | }; 386 | /* End PBXVariantGroup section */ 387 | 388 | /* Begin XCBuildConfiguration section */ 389 | 3D3F31B3223AF599007A795A /* Debug */ = { 390 | isa = XCBuildConfiguration; 391 | baseConfigurationReference = A92DE428CC8B12F038E38C74 /* Pods-MaterialActivityIndicatorTV_Example.debug.xcconfig */; 392 | buildSettings = { 393 | ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; 394 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 395 | CLANG_ANALYZER_NONNULL = YES; 396 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 397 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 398 | CLANG_ENABLE_OBJC_WEAK = YES; 399 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 400 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 401 | CODE_SIGN_STYLE = Automatic; 402 | DEBUG_INFORMATION_FORMAT = dwarf; 403 | DEVELOPMENT_TEAM = 2QLBXZ66VC; 404 | GCC_C_LANGUAGE_STANDARD = gnu11; 405 | INFOPLIST_FILE = MaterialActivityIndicatorTV/Info.plist; 406 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 407 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 408 | MTL_FAST_MATH = YES; 409 | PRODUCT_BUNDLE_IDENTIFIER = "me.pavlo.MaterialActivityIndicatorTV-Example"; 410 | PRODUCT_NAME = "$(TARGET_NAME)"; 411 | SDKROOT = appletvos; 412 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 413 | SWIFT_VERSION = 5.0; 414 | TARGETED_DEVICE_FAMILY = 3; 415 | TVOS_DEPLOYMENT_TARGET = 12.1; 416 | }; 417 | name = Debug; 418 | }; 419 | 3D3F31B4223AF599007A795A /* Release */ = { 420 | isa = XCBuildConfiguration; 421 | baseConfigurationReference = F15DC3BE43013A5D6C8358CF /* Pods-MaterialActivityIndicatorTV_Example.release.xcconfig */; 422 | buildSettings = { 423 | ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; 424 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 425 | CLANG_ANALYZER_NONNULL = YES; 426 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 427 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 428 | CLANG_ENABLE_OBJC_WEAK = YES; 429 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 430 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 431 | CODE_SIGN_STYLE = Automatic; 432 | DEVELOPMENT_TEAM = 2QLBXZ66VC; 433 | GCC_C_LANGUAGE_STANDARD = gnu11; 434 | INFOPLIST_FILE = MaterialActivityIndicatorTV/Info.plist; 435 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 436 | MTL_FAST_MATH = YES; 437 | PRODUCT_BUNDLE_IDENTIFIER = "me.pavlo.MaterialActivityIndicatorTV-Example"; 438 | PRODUCT_NAME = "$(TARGET_NAME)"; 439 | SDKROOT = appletvos; 440 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 441 | SWIFT_VERSION = 5.0; 442 | TARGETED_DEVICE_FAMILY = 3; 443 | TVOS_DEPLOYMENT_TARGET = 12.1; 444 | }; 445 | name = Release; 446 | }; 447 | 607FACED1AFB9204008FA782 /* Debug */ = { 448 | isa = XCBuildConfiguration; 449 | buildSettings = { 450 | ALWAYS_SEARCH_USER_PATHS = NO; 451 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 452 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 453 | CLANG_CXX_LIBRARY = "libc++"; 454 | CLANG_ENABLE_MODULES = YES; 455 | CLANG_ENABLE_OBJC_ARC = YES; 456 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 457 | CLANG_WARN_BOOL_CONVERSION = YES; 458 | CLANG_WARN_COMMA = YES; 459 | CLANG_WARN_CONSTANT_CONVERSION = YES; 460 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 461 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 462 | CLANG_WARN_EMPTY_BODY = YES; 463 | CLANG_WARN_ENUM_CONVERSION = YES; 464 | CLANG_WARN_INFINITE_RECURSION = YES; 465 | CLANG_WARN_INT_CONVERSION = YES; 466 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 467 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 468 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 469 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 470 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 471 | CLANG_WARN_STRICT_PROTOTYPES = YES; 472 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 473 | CLANG_WARN_UNREACHABLE_CODE = YES; 474 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 475 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 476 | COPY_PHASE_STRIP = NO; 477 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 478 | ENABLE_STRICT_OBJC_MSGSEND = YES; 479 | ENABLE_TESTABILITY = YES; 480 | GCC_C_LANGUAGE_STANDARD = gnu99; 481 | GCC_DYNAMIC_NO_PIC = NO; 482 | GCC_NO_COMMON_BLOCKS = YES; 483 | GCC_OPTIMIZATION_LEVEL = 0; 484 | GCC_PREPROCESSOR_DEFINITIONS = ( 485 | "DEBUG=1", 486 | "$(inherited)", 487 | ); 488 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 489 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 490 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 491 | GCC_WARN_UNDECLARED_SELECTOR = YES; 492 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 493 | GCC_WARN_UNUSED_FUNCTION = YES; 494 | GCC_WARN_UNUSED_VARIABLE = YES; 495 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 496 | MTL_ENABLE_DEBUG_INFO = YES; 497 | ONLY_ACTIVE_ARCH = YES; 498 | SDKROOT = iphoneos; 499 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 500 | }; 501 | name = Debug; 502 | }; 503 | 607FACEE1AFB9204008FA782 /* Release */ = { 504 | isa = XCBuildConfiguration; 505 | buildSettings = { 506 | ALWAYS_SEARCH_USER_PATHS = NO; 507 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 508 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 509 | CLANG_CXX_LIBRARY = "libc++"; 510 | CLANG_ENABLE_MODULES = YES; 511 | CLANG_ENABLE_OBJC_ARC = YES; 512 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 513 | CLANG_WARN_BOOL_CONVERSION = YES; 514 | CLANG_WARN_COMMA = YES; 515 | CLANG_WARN_CONSTANT_CONVERSION = YES; 516 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 517 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 518 | CLANG_WARN_EMPTY_BODY = YES; 519 | CLANG_WARN_ENUM_CONVERSION = YES; 520 | CLANG_WARN_INFINITE_RECURSION = YES; 521 | CLANG_WARN_INT_CONVERSION = YES; 522 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 523 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 524 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 525 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 526 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 527 | CLANG_WARN_STRICT_PROTOTYPES = YES; 528 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 529 | CLANG_WARN_UNREACHABLE_CODE = YES; 530 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 531 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 532 | COPY_PHASE_STRIP = NO; 533 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 534 | ENABLE_NS_ASSERTIONS = NO; 535 | ENABLE_STRICT_OBJC_MSGSEND = YES; 536 | GCC_C_LANGUAGE_STANDARD = gnu99; 537 | GCC_NO_COMMON_BLOCKS = YES; 538 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 539 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 540 | GCC_WARN_UNDECLARED_SELECTOR = YES; 541 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 542 | GCC_WARN_UNUSED_FUNCTION = YES; 543 | GCC_WARN_UNUSED_VARIABLE = YES; 544 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 545 | MTL_ENABLE_DEBUG_INFO = NO; 546 | SDKROOT = iphoneos; 547 | SWIFT_COMPILATION_MODE = wholemodule; 548 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 549 | VALIDATE_PRODUCT = YES; 550 | }; 551 | name = Release; 552 | }; 553 | 607FACF01AFB9204008FA782 /* Debug */ = { 554 | isa = XCBuildConfiguration; 555 | baseConfigurationReference = 2E935D60F8A3FECE56FCDCA4 /* Pods-MaterialActivityIndicator_Example.debug.xcconfig */; 556 | buildSettings = { 557 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 558 | INFOPLIST_FILE = MaterialActivityIndicator/Info.plist; 559 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 560 | MODULE_NAME = ExampleApp; 561 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; 562 | PRODUCT_NAME = "$(TARGET_NAME)"; 563 | SWIFT_VERSION = 5.0; 564 | }; 565 | name = Debug; 566 | }; 567 | 607FACF11AFB9204008FA782 /* Release */ = { 568 | isa = XCBuildConfiguration; 569 | baseConfigurationReference = 421C223690CE3B79E69BA5D3 /* Pods-MaterialActivityIndicator_Example.release.xcconfig */; 570 | buildSettings = { 571 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 572 | INFOPLIST_FILE = MaterialActivityIndicator/Info.plist; 573 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 574 | MODULE_NAME = ExampleApp; 575 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; 576 | PRODUCT_NAME = "$(TARGET_NAME)"; 577 | SWIFT_VERSION = 5.0; 578 | }; 579 | name = Release; 580 | }; 581 | /* End XCBuildConfiguration section */ 582 | 583 | /* Begin XCConfigurationList section */ 584 | 3D3F31B2223AF599007A795A /* Build configuration list for PBXNativeTarget "MaterialActivityIndicatorTV_Example" */ = { 585 | isa = XCConfigurationList; 586 | buildConfigurations = ( 587 | 3D3F31B3223AF599007A795A /* Debug */, 588 | 3D3F31B4223AF599007A795A /* Release */, 589 | ); 590 | defaultConfigurationIsVisible = 0; 591 | defaultConfigurationName = Release; 592 | }; 593 | 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "MaterialActivityIndicator" */ = { 594 | isa = XCConfigurationList; 595 | buildConfigurations = ( 596 | 607FACED1AFB9204008FA782 /* Debug */, 597 | 607FACEE1AFB9204008FA782 /* Release */, 598 | ); 599 | defaultConfigurationIsVisible = 0; 600 | defaultConfigurationName = Release; 601 | }; 602 | 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "MaterialActivityIndicator_Example" */ = { 603 | isa = XCConfigurationList; 604 | buildConfigurations = ( 605 | 607FACF01AFB9204008FA782 /* Debug */, 606 | 607FACF11AFB9204008FA782 /* Release */, 607 | ); 608 | defaultConfigurationIsVisible = 0; 609 | defaultConfigurationName = Release; 610 | }; 611 | /* End XCConfigurationList section */ 612 | }; 613 | rootObject = 607FACC81AFB9204008FA782 /* Project object */; 614 | } 615 | -------------------------------------------------------------------------------- /Example/MaterialActivityIndicator.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/MaterialActivityIndicator.xcodeproj/xcshareddata/xcschemes/Example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 51 | 52 | 53 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 76 | 78 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /Example/MaterialActivityIndicator.xcodeproj/xcshareddata/xcschemes/ExampleTV.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 70 | 72 | 73 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /Example/MaterialActivityIndicator.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/MaterialActivityIndicator.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/MaterialActivityIndicator/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // MaterialActivityIndicator 4 | // 5 | // Created by Jans Pavlovs on 02/13/2018. 6 | // Copyright (c) 2018 Jans Pavlovs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @main 12 | class AppDelegate: UIResponder { 13 | var window: UIWindow? 14 | } 15 | 16 | // MARK: UIApplicationDelegate 17 | 18 | extension AppDelegate: UIApplicationDelegate { 19 | func application(_ application: UIApplication, 20 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 21 | return true 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/MaterialActivityIndicator/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 25 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /Example/MaterialActivityIndicator/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 | 27 | -------------------------------------------------------------------------------- /Example/MaterialActivityIndicator/DemoViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DemoViewController.swift 3 | // MaterialActivityIndicator 4 | // 5 | // Created by Jans Pavlovs on 02/13/2018. 6 | // Copyright (c) 2018 Jans Pavlovs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import MaterialActivityIndicator 11 | 12 | // MARK: Initialization 13 | 14 | final class DemoViewController: UIViewController { 15 | private let indicator = MaterialActivityIndicatorView() 16 | 17 | override func viewDidLoad() { 18 | super.viewDidLoad() 19 | setupActivityIndicatorView() 20 | } 21 | 22 | override func viewDidAppear(_ animated: Bool) { 23 | super.viewDidAppear(animated) 24 | indicator.startAnimating() 25 | } 26 | 27 | override func viewDidDisappear(_ animated: Bool) { 28 | super.viewDidDisappear(animated) 29 | indicator.stopAnimating() 30 | } 31 | } 32 | 33 | // MARK: Private Methods 34 | 35 | private extension DemoViewController { 36 | func setupActivityIndicatorView() { 37 | view.addSubview(indicator) 38 | setupActivityIndicatorViewConstraints() 39 | } 40 | 41 | func setupActivityIndicatorViewConstraints() { 42 | indicator.translatesAutoresizingMaskIntoConstraints = false 43 | indicator.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true 44 | indicator.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Example/MaterialActivityIndicator/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 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /Example/MaterialActivityIndicatorTV/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // MaterialActivityIndicatorTV_Example 4 | // 5 | // Created by Jans Pavlovs on 14/03/2019. 6 | // Copyright © 2019 CocoaPods. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @main 12 | class AppDelegate: UIResponder { 13 | var window: UIWindow? 14 | } 15 | 16 | // MARK: UIApplicationDelegate 17 | 18 | extension AppDelegate: UIApplicationDelegate { 19 | func application(_ application: UIApplication, 20 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 21 | return true 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/MaterialActivityIndicatorTV/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 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Example/MaterialActivityIndicatorTV/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 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 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIMainStoryboardFile 24 | Main 25 | UIRequiredDeviceCapabilities 26 | 27 | arm64 28 | 29 | UIUserInterfaceStyle 30 | Automatic 31 | 32 | 33 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, '9.3' 2 | use_frameworks! 3 | 4 | def common 5 | pod 'MaterialActivityIndicator', :path => '../' 6 | pod 'SwiftLint' 7 | end 8 | 9 | target 'MaterialActivityIndicator_Example' do 10 | common 11 | end 12 | 13 | target 'MaterialActivityIndicatorTV_Example' do 14 | common 15 | end 16 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - MaterialActivityIndicator (0.0.6) 3 | - SwiftLint (0.42.0) 4 | 5 | DEPENDENCIES: 6 | - MaterialActivityIndicator (from `../`) 7 | - SwiftLint 8 | 9 | SPEC REPOS: 10 | trunk: 11 | - SwiftLint 12 | 13 | EXTERNAL SOURCES: 14 | MaterialActivityIndicator: 15 | :path: "../" 16 | 17 | SPEC CHECKSUMS: 18 | MaterialActivityIndicator: a35967446e1512afc6bbbf5f5e2cb997d8b4d2cb 19 | SwiftLint: 4fa9579c63416865179bc416f0a92d55f009600d 20 | 21 | PODFILE CHECKSUM: 1c4817de43630a39be6b932338317b7440ef3580 22 | 23 | COCOAPODS: 1.10.0 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018 nspavlo 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /MaterialActivityIndicator.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'MaterialActivityIndicator' 3 | s.version = '0.0.6' 4 | s.summary = 'Material activity indicator' 5 | s.description = <<-DESC 6 | Material activity indicator (Circular progress indicator) 7 | DESC 8 | s.swift_version = '5.3' 9 | 10 | s.homepage = 'https://github.com/nspavlo/MaterialActivityIndicator' 11 | s.license = { :type => 'MIT', :file => 'LICENSE' } 12 | s.author = { 'nspavlo' => 'jans.pavlovs@gmail.com' } 13 | s.source = { :git => 'https://github.com/nspavlo/MaterialActivityIndicator.git', :tag => s.version.to_s } 14 | 15 | s.ios.deployment_target = '9.0' 16 | s.tvos.deployment_target = '9.0' 17 | 18 | s.source_files = 'Sources/MaterialActivityIndicator/**/*' 19 | s.frameworks = 'UIKit' 20 | end 21 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.0 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "MaterialActivityIndicator", 8 | products: [ 9 | .library( 10 | name: "MaterialActivityIndicator", 11 | targets: ["MaterialActivityIndicator"]), 12 | ], 13 | targets: [ 14 | .target( 15 | name: "MaterialActivityIndicator", 16 | dependencies: []), 17 | ] 18 | ) 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MaterialActivityIndicator 2 | 3 | [![CI Status](http://img.shields.io/travis/nspavlo/MaterialActivityIndicator.svg?style=flat)](https://travis-ci.org/nspavlo/MaterialActivityIndicator) 4 | [![Version](https://img.shields.io/cocoapods/v/MaterialActivityIndicator.svg?style=flat)](http://cocoapods.org/pods/MaterialActivityIndicator) 5 | [![License](https://img.shields.io/cocoapods/l/MaterialActivityIndicator.svg?style=flat)](http://cocoapods.org/pods/MaterialActivityIndicator) 6 | [![Platform](https://img.shields.io/cocoapods/p/MaterialActivityIndicator.svg?style=flat)](http://cocoapods.org/pods/MaterialActivityIndicator) 7 | 8 | `MaterialActivityIndicatorView` is a drop in replacement for `UIActivityIndicatorView` 9 | 10 | ## Example 11 | 12 | ![Material activity indicator in Swift](https://raw.githubusercontent.com/nspavlo/MaterialActivityIndicator/master/preview.gif) 13 | To run the example project, clone the repo, and run `pod install` from the Example directory first. 14 | 15 | ## Requirements 16 | 17 | This pod requires a deployment target of iOS 9.3 or greater 18 | 19 | ## Installation 20 | 21 | #### Swift Package Manager 22 | 23 | - File > Swift Packages > Add Package Dependency 24 | - Add `https://github.com/nspavlo/MaterialActivityIndicator` 25 | 26 | #### CocoaPods 27 | 28 | MaterialActivityIndicator is available through [CocoaPods](http://cocoapods.org). To install 29 | it, simply add the following line to your Podfile: 30 | 31 | ```ruby 32 | pod 'MaterialActivityIndicator' 33 | ``` 34 | 35 | ## Usage 36 | 37 | ```Swift 38 | let indicator = MaterialActivityIndicatorView() 39 | indicator.startAnimating() 40 | ``` 41 | 42 | ## Author 43 | 44 | [@JansPavlovs 👨‍💻](https://twitter.com/JansPavlovs) 45 | 46 | ## License 47 | 48 | MaterialActivityIndicator is available under the MIT license. See the LICENSE file for more info. 49 | -------------------------------------------------------------------------------- /Sources/MaterialActivityIndicator/Extensions/CAPropertyAnimation+Key.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CAPropertyAnimation+Key.swift 3 | // MaterialActivityIndicator 4 | // 5 | // Created by Jans Pavlovs on 15.02.18. 6 | // Copyright (c) 2018 Jans Pavlovs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension CAPropertyAnimation { 12 | enum Key: String { 13 | var path: String { 14 | return rawValue 15 | } 16 | 17 | case strokeStart = "strokeStart" 18 | case strokeEnd = "strokeEnd" 19 | case strokeColor = "strokeColor" 20 | case rotationZ = "transform.rotation.z" 21 | case scale = "transform.scale" 22 | } 23 | 24 | convenience init(key: Key) { 25 | self.init(keyPath: key.path) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Sources/MaterialActivityIndicator/Extensions/CGRect+Center.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CGRect+Center.swift 3 | // MaterialActivityIndicator 4 | // 5 | // Created by Jans Pavlovs on 13.02.18. 6 | // Copyright (c) 2018 Jans Pavlovs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension CGRect { 12 | var center: CGPoint { 13 | return CGPoint(x: midX, y: midY) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Sources/MaterialActivityIndicator/Extensions/CGSize+Min.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CGSize+Min.swift 3 | // MaterialActivityIndicator 4 | // 5 | // Created by Jans Pavlovs on 13.02.18. 6 | // Copyright (c) 2018 Jans Pavlovs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension CGSize { 12 | var min: CGFloat { 13 | return CGFloat.minimum(width, height) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Sources/MaterialActivityIndicator/Extensions/UIBezierPath+Circle.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIBezierPath+Circle.swift 3 | // MaterialActivityIndicator 4 | // 5 | // Created by Jans Pavlovs on 13.02.18. 6 | // Copyright (c) 2018 Jans Pavlovs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension UIBezierPath { 12 | convenience init(center: CGPoint, radius: CGFloat) { 13 | self.init(arcCenter: center, radius: radius, startAngle: 0, endAngle: CGFloat(.pi * 2.0), clockwise: true) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Sources/MaterialActivityIndicator/MaterialActivityIndicator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MaterialActivityIndicator.swift 3 | // MaterialActivityIndicator 4 | // 5 | // Created by Jans Pavlovs on 02/13/2018. 6 | // Copyright (c) 2018 Jans Pavlovs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @IBDesignable 12 | public class MaterialActivityIndicatorView: UIView { 13 | @IBInspectable 14 | public var color: UIColor = .red { 15 | didSet { 16 | indicator.strokeColor = color.cgColor 17 | } 18 | } 19 | 20 | @IBInspectable 21 | public var lineWidth: CGFloat = 2.0 { 22 | didSet { 23 | indicator.lineWidth = lineWidth 24 | setNeedsLayout() 25 | } 26 | } 27 | 28 | private let indicator = CAShapeLayer() 29 | private let animator = MaterialActivityIndicatorAnimator() 30 | 31 | private var isAnimating = false 32 | 33 | convenience init() { 34 | self.init(frame: .zero) 35 | self.setup() 36 | } 37 | 38 | override public init(frame: CGRect) { 39 | super.init(frame: frame) 40 | self.setup() 41 | } 42 | 43 | public required init?(coder aDecoder: NSCoder) { 44 | super.init(coder: aDecoder) 45 | self.setup() 46 | } 47 | 48 | private func setup() { 49 | indicator.strokeColor = color.cgColor 50 | indicator.fillColor = nil 51 | indicator.lineWidth = lineWidth 52 | indicator.strokeStart = 0.0 53 | indicator.strokeEnd = 0.0 54 | layer.addSublayer(indicator) 55 | } 56 | } 57 | 58 | extension MaterialActivityIndicatorView { 59 | override public var intrinsicContentSize: CGSize { 60 | return CGSize(width: 24, height: 24) 61 | } 62 | 63 | override public func layoutSubviews() { 64 | super.layoutSubviews() 65 | 66 | indicator.frame = bounds 67 | 68 | let diameter = bounds.size.min - indicator.lineWidth 69 | let path = UIBezierPath(center: bounds.center, radius: diameter / 2) 70 | indicator.path = path.cgPath 71 | } 72 | } 73 | 74 | extension MaterialActivityIndicatorView { 75 | public func startAnimating() { 76 | guard !isAnimating else { return } 77 | 78 | animator.addAnimation(to: indicator) 79 | isAnimating = true 80 | } 81 | 82 | public func stopAnimating() { 83 | guard isAnimating else { return } 84 | 85 | animator.removeAnimation(from: indicator) 86 | isAnimating = false 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /Sources/MaterialActivityIndicator/MaterialActivityIndicatorAnimator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MaterialActivityIndicatorAnimator.swift 3 | // MaterialActivityIndicator 4 | // 5 | // Created by Jans Pavlovs on 15.02.18. 6 | // Copyright (c) 2018 Jans Pavlovs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | final class MaterialActivityIndicatorAnimator { 12 | enum Animation: String { 13 | var key: String { 14 | return rawValue 15 | } 16 | 17 | case spring = "material.indicator.spring" 18 | case rotation = "material.indicator.rotation" 19 | } 20 | 21 | public func addAnimation(to layer: CALayer) { 22 | layer.add(rotationAnimation(), forKey: Animation.rotation.key) 23 | layer.add(springAnimation(), forKey: Animation.spring.key) 24 | } 25 | 26 | public func removeAnimation(from layer: CALayer) { 27 | layer.removeAnimation(forKey: Animation.rotation.key) 28 | layer.removeAnimation(forKey: Animation.spring.key) 29 | } 30 | } 31 | 32 | extension MaterialActivityIndicatorAnimator { 33 | private func rotationAnimation() -> CABasicAnimation { 34 | let animation = CABasicAnimation(key: .rotationZ) 35 | animation.duration = 4 36 | animation.fromValue = 0 37 | animation.toValue = (2.0 * .pi) 38 | animation.repeatCount = .infinity 39 | 40 | return animation 41 | } 42 | 43 | private func springAnimation() -> CAAnimationGroup { 44 | let animation = CAAnimationGroup() 45 | animation.duration = 1.5 46 | animation.animations = [ 47 | strokeStartAnimation(), 48 | strokeEndAnimation(), 49 | strokeCatchAnimation(), 50 | strokeFreezeAnimation() 51 | ] 52 | animation.repeatCount = .infinity 53 | 54 | return animation 55 | } 56 | 57 | private func strokeStartAnimation() -> CABasicAnimation { 58 | let animation = CABasicAnimation(key: .strokeStart) 59 | animation.duration = 1 60 | animation.fromValue = 0 61 | animation.toValue = 0.15 62 | animation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut) 63 | 64 | return animation 65 | } 66 | 67 | private func strokeEndAnimation() -> CABasicAnimation { 68 | let animation = CABasicAnimation(key: .strokeEnd) 69 | animation.duration = 1 70 | animation.fromValue = 0 71 | animation.toValue = 1 72 | animation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut) 73 | 74 | return animation 75 | } 76 | 77 | private func strokeCatchAnimation() -> CABasicAnimation { 78 | let animation = CABasicAnimation(key: .strokeStart) 79 | animation.beginTime = 1 80 | animation.duration = 0.5 81 | animation.fromValue = 0.15 82 | animation.toValue = 1 83 | animation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut) 84 | 85 | return animation 86 | } 87 | 88 | private func strokeFreezeAnimation() -> CABasicAnimation { 89 | let animation = CABasicAnimation(key: .strokeEnd) 90 | animation.beginTime = 1 91 | animation.duration = 0.5 92 | animation.fromValue = 1 93 | animation.toValue = 1 94 | animation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut) 95 | 96 | return animation 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nspavlo/MaterialActivityIndicator/097d31631b16cf9cc80b74b43026ccfda5db52d3/preview.gif --------------------------------------------------------------------------------