├── .gitignore ├── LICENSE ├── README.md └── clearCache ├── clearCache.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata └── clearCache ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets └── AppIcon.appiconset │ └── Contents.json ├── Base.lproj ├── LaunchScreen.storyboard └── Main.storyboard ├── Info.plist ├── LBClearCacheTool.h ├── LBClearCacheTool.m ├── SVProgressHUD ├── LICENSE.txt ├── README.md └── SVProgressHUD │ ├── SVIndefiniteAnimatedView.h │ ├── SVIndefiniteAnimatedView.m │ ├── SVProgressAnimatedView.h │ ├── SVProgressAnimatedView.m │ ├── SVProgressHUD.bundle │ ├── angle-mask.png │ ├── angle-mask@2x.png │ ├── angle-mask@3x.png │ ├── error.png │ ├── error@2x.png │ ├── error@3x.png │ ├── info.png │ ├── info@2x.png │ ├── info@3x.png │ ├── success.png │ ├── success@2x.png │ └── success@3x.png │ ├── SVProgressHUD.h │ ├── SVProgressHUD.m │ ├── SVRadialGradientLayer.h │ └── SVRadialGradientLayer.m ├── ViewController.h ├── ViewController.m └── main.m /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xcuserstate 23 | 24 | ## Obj-C/Swift specific 25 | *.hmap 26 | *.ipa 27 | *.dSYM.zip 28 | *.dSYM 29 | 30 | # CocoaPods 31 | # 32 | # We recommend against adding the Pods directory to your .gitignore. However 33 | # you should judge for yourself, the pros and cons are mentioned at: 34 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 35 | # 36 | # Pods/ 37 | 38 | # Carthage 39 | # 40 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 41 | # Carthage/Checkouts 42 | 43 | Carthage/Build 44 | 45 | # fastlane 46 | # 47 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 48 | # screenshots whenever they are needed. 49 | # For more information about the recommended setup visit: 50 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 51 | 52 | fastlane/report.xml 53 | fastlane/screenshots 54 | 55 | #Code Injection 56 | # 57 | # After new code Injection tools there's a generated folder /iOSInjectionProject 58 | # https://github.com/johnno1962/injectionforxcode 59 | 60 | iOSInjectionProject/ 61 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ClearFileCache 2 | 这是一个工具类,提供了获取指定文件夹缓存大小以及清除指定文件夹缓存的类方法 3 | -------------------------------------------------------------------------------- /clearCache/clearCache.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | E497B06E1CFBE6A700068A04 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = E497B06D1CFBE6A700068A04 /* main.m */; }; 11 | E497B0711CFBE6A700068A04 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = E497B0701CFBE6A700068A04 /* AppDelegate.m */; }; 12 | E497B0741CFBE6A700068A04 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E497B0731CFBE6A700068A04 /* ViewController.m */; }; 13 | E497B0771CFBE6A700068A04 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E497B0751CFBE6A700068A04 /* Main.storyboard */; }; 14 | E497B0791CFBE6A700068A04 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E497B0781CFBE6A700068A04 /* Assets.xcassets */; }; 15 | E497B07C1CFBE6A700068A04 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E497B07A1CFBE6A700068A04 /* LaunchScreen.storyboard */; }; 16 | E497B0861CFBE7BA00068A04 /* LBClearCacheTool.m in Sources */ = {isa = PBXBuildFile; fileRef = E497B0851CFBE7BA00068A04 /* LBClearCacheTool.m */; }; 17 | E497B0941CFBE8F300068A04 /* LICENSE.txt in Resources */ = {isa = PBXBuildFile; fileRef = E497B0881CFBE8F300068A04 /* LICENSE.txt */; }; 18 | E497B0951CFBE8F300068A04 /* README.md in Sources */ = {isa = PBXBuildFile; fileRef = E497B0891CFBE8F300068A04 /* README.md */; }; 19 | E497B0961CFBE8F300068A04 /* SVIndefiniteAnimatedView.m in Sources */ = {isa = PBXBuildFile; fileRef = E497B08C1CFBE8F300068A04 /* SVIndefiniteAnimatedView.m */; }; 20 | E497B0971CFBE8F300068A04 /* SVProgressAnimatedView.m in Sources */ = {isa = PBXBuildFile; fileRef = E497B08E1CFBE8F300068A04 /* SVProgressAnimatedView.m */; }; 21 | E497B0981CFBE8F300068A04 /* SVProgressHUD.bundle in Resources */ = {isa = PBXBuildFile; fileRef = E497B08F1CFBE8F300068A04 /* SVProgressHUD.bundle */; }; 22 | E497B0991CFBE8F300068A04 /* SVProgressHUD.m in Sources */ = {isa = PBXBuildFile; fileRef = E497B0911CFBE8F300068A04 /* SVProgressHUD.m */; }; 23 | E497B09A1CFBE8F300068A04 /* SVRadialGradientLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = E497B0931CFBE8F300068A04 /* SVRadialGradientLayer.m */; }; 24 | /* End PBXBuildFile section */ 25 | 26 | /* Begin PBXFileReference section */ 27 | E497B0691CFBE6A700068A04 /* clearCache.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = clearCache.app; sourceTree = BUILT_PRODUCTS_DIR; }; 28 | E497B06D1CFBE6A700068A04 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 29 | E497B06F1CFBE6A700068A04 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 30 | E497B0701CFBE6A700068A04 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 31 | E497B0721CFBE6A700068A04 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 32 | E497B0731CFBE6A700068A04 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 33 | E497B0761CFBE6A700068A04 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 34 | E497B0781CFBE6A700068A04 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 35 | E497B07B1CFBE6A700068A04 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 36 | E497B07D1CFBE6A700068A04 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 37 | E497B0841CFBE7BA00068A04 /* LBClearCacheTool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LBClearCacheTool.h; sourceTree = ""; }; 38 | E497B0851CFBE7BA00068A04 /* LBClearCacheTool.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LBClearCacheTool.m; sourceTree = ""; }; 39 | E497B0881CFBE8F300068A04 /* LICENSE.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE.txt; sourceTree = ""; }; 40 | E497B0891CFBE8F300068A04 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 41 | E497B08B1CFBE8F300068A04 /* SVIndefiniteAnimatedView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVIndefiniteAnimatedView.h; sourceTree = ""; }; 42 | E497B08C1CFBE8F300068A04 /* SVIndefiniteAnimatedView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SVIndefiniteAnimatedView.m; sourceTree = ""; }; 43 | E497B08D1CFBE8F300068A04 /* SVProgressAnimatedView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVProgressAnimatedView.h; sourceTree = ""; }; 44 | E497B08E1CFBE8F300068A04 /* SVProgressAnimatedView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SVProgressAnimatedView.m; sourceTree = ""; }; 45 | E497B08F1CFBE8F300068A04 /* SVProgressHUD.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = SVProgressHUD.bundle; sourceTree = ""; }; 46 | E497B0901CFBE8F300068A04 /* SVProgressHUD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVProgressHUD.h; sourceTree = ""; }; 47 | E497B0911CFBE8F300068A04 /* SVProgressHUD.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SVProgressHUD.m; sourceTree = ""; }; 48 | E497B0921CFBE8F300068A04 /* SVRadialGradientLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVRadialGradientLayer.h; sourceTree = ""; }; 49 | E497B0931CFBE8F300068A04 /* SVRadialGradientLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SVRadialGradientLayer.m; sourceTree = ""; }; 50 | /* End PBXFileReference section */ 51 | 52 | /* Begin PBXFrameworksBuildPhase section */ 53 | E497B0661CFBE6A700068A04 /* Frameworks */ = { 54 | isa = PBXFrameworksBuildPhase; 55 | buildActionMask = 2147483647; 56 | files = ( 57 | ); 58 | runOnlyForDeploymentPostprocessing = 0; 59 | }; 60 | /* End PBXFrameworksBuildPhase section */ 61 | 62 | /* Begin PBXGroup section */ 63 | E497B0601CFBE6A700068A04 = { 64 | isa = PBXGroup; 65 | children = ( 66 | E497B06B1CFBE6A700068A04 /* clearCache */, 67 | E497B06A1CFBE6A700068A04 /* Products */, 68 | ); 69 | sourceTree = ""; 70 | }; 71 | E497B06A1CFBE6A700068A04 /* Products */ = { 72 | isa = PBXGroup; 73 | children = ( 74 | E497B0691CFBE6A700068A04 /* clearCache.app */, 75 | ); 76 | name = Products; 77 | sourceTree = ""; 78 | }; 79 | E497B06B1CFBE6A700068A04 /* clearCache */ = { 80 | isa = PBXGroup; 81 | children = ( 82 | E497B0831CFBE79B00068A04 /* ClearCache */, 83 | E497B06F1CFBE6A700068A04 /* AppDelegate.h */, 84 | E497B0701CFBE6A700068A04 /* AppDelegate.m */, 85 | E497B0721CFBE6A700068A04 /* ViewController.h */, 86 | E497B0731CFBE6A700068A04 /* ViewController.m */, 87 | E497B0751CFBE6A700068A04 /* Main.storyboard */, 88 | E497B0781CFBE6A700068A04 /* Assets.xcassets */, 89 | E497B07A1CFBE6A700068A04 /* LaunchScreen.storyboard */, 90 | E497B07D1CFBE6A700068A04 /* Info.plist */, 91 | E497B0871CFBE8F300068A04 /* SVProgressHUD */, 92 | E497B06C1CFBE6A700068A04 /* Supporting Files */, 93 | ); 94 | path = clearCache; 95 | sourceTree = ""; 96 | }; 97 | E497B06C1CFBE6A700068A04 /* Supporting Files */ = { 98 | isa = PBXGroup; 99 | children = ( 100 | E497B06D1CFBE6A700068A04 /* main.m */, 101 | ); 102 | name = "Supporting Files"; 103 | sourceTree = ""; 104 | }; 105 | E497B0831CFBE79B00068A04 /* ClearCache */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | E497B0841CFBE7BA00068A04 /* LBClearCacheTool.h */, 109 | E497B0851CFBE7BA00068A04 /* LBClearCacheTool.m */, 110 | ); 111 | name = ClearCache; 112 | sourceTree = ""; 113 | }; 114 | E497B0871CFBE8F300068A04 /* SVProgressHUD */ = { 115 | isa = PBXGroup; 116 | children = ( 117 | E497B0881CFBE8F300068A04 /* LICENSE.txt */, 118 | E497B0891CFBE8F300068A04 /* README.md */, 119 | E497B08A1CFBE8F300068A04 /* SVProgressHUD */, 120 | ); 121 | path = SVProgressHUD; 122 | sourceTree = ""; 123 | }; 124 | E497B08A1CFBE8F300068A04 /* SVProgressHUD */ = { 125 | isa = PBXGroup; 126 | children = ( 127 | E497B08B1CFBE8F300068A04 /* SVIndefiniteAnimatedView.h */, 128 | E497B08C1CFBE8F300068A04 /* SVIndefiniteAnimatedView.m */, 129 | E497B08D1CFBE8F300068A04 /* SVProgressAnimatedView.h */, 130 | E497B08E1CFBE8F300068A04 /* SVProgressAnimatedView.m */, 131 | E497B08F1CFBE8F300068A04 /* SVProgressHUD.bundle */, 132 | E497B0901CFBE8F300068A04 /* SVProgressHUD.h */, 133 | E497B0911CFBE8F300068A04 /* SVProgressHUD.m */, 134 | E497B0921CFBE8F300068A04 /* SVRadialGradientLayer.h */, 135 | E497B0931CFBE8F300068A04 /* SVRadialGradientLayer.m */, 136 | ); 137 | path = SVProgressHUD; 138 | sourceTree = ""; 139 | }; 140 | /* End PBXGroup section */ 141 | 142 | /* Begin PBXNativeTarget section */ 143 | E497B0681CFBE6A700068A04 /* clearCache */ = { 144 | isa = PBXNativeTarget; 145 | buildConfigurationList = E497B0801CFBE6A700068A04 /* Build configuration list for PBXNativeTarget "clearCache" */; 146 | buildPhases = ( 147 | E497B0651CFBE6A700068A04 /* Sources */, 148 | E497B0661CFBE6A700068A04 /* Frameworks */, 149 | E497B0671CFBE6A700068A04 /* Resources */, 150 | ); 151 | buildRules = ( 152 | ); 153 | dependencies = ( 154 | ); 155 | name = clearCache; 156 | productName = clearCache; 157 | productReference = E497B0691CFBE6A700068A04 /* clearCache.app */; 158 | productType = "com.apple.product-type.application"; 159 | }; 160 | /* End PBXNativeTarget section */ 161 | 162 | /* Begin PBXProject section */ 163 | E497B0611CFBE6A700068A04 /* Project object */ = { 164 | isa = PBXProject; 165 | attributes = { 166 | LastUpgradeCheck = 0720; 167 | ORGANIZATIONNAME = "li bo"; 168 | TargetAttributes = { 169 | E497B0681CFBE6A700068A04 = { 170 | CreatedOnToolsVersion = 7.2.1; 171 | }; 172 | }; 173 | }; 174 | buildConfigurationList = E497B0641CFBE6A700068A04 /* Build configuration list for PBXProject "clearCache" */; 175 | compatibilityVersion = "Xcode 3.2"; 176 | developmentRegion = English; 177 | hasScannedForEncodings = 0; 178 | knownRegions = ( 179 | en, 180 | Base, 181 | ); 182 | mainGroup = E497B0601CFBE6A700068A04; 183 | productRefGroup = E497B06A1CFBE6A700068A04 /* Products */; 184 | projectDirPath = ""; 185 | projectRoot = ""; 186 | targets = ( 187 | E497B0681CFBE6A700068A04 /* clearCache */, 188 | ); 189 | }; 190 | /* End PBXProject section */ 191 | 192 | /* Begin PBXResourcesBuildPhase section */ 193 | E497B0671CFBE6A700068A04 /* Resources */ = { 194 | isa = PBXResourcesBuildPhase; 195 | buildActionMask = 2147483647; 196 | files = ( 197 | E497B0981CFBE8F300068A04 /* SVProgressHUD.bundle in Resources */, 198 | E497B0941CFBE8F300068A04 /* LICENSE.txt in Resources */, 199 | E497B07C1CFBE6A700068A04 /* LaunchScreen.storyboard in Resources */, 200 | E497B0791CFBE6A700068A04 /* Assets.xcassets in Resources */, 201 | E497B0771CFBE6A700068A04 /* Main.storyboard in Resources */, 202 | ); 203 | runOnlyForDeploymentPostprocessing = 0; 204 | }; 205 | /* End PBXResourcesBuildPhase section */ 206 | 207 | /* Begin PBXSourcesBuildPhase section */ 208 | E497B0651CFBE6A700068A04 /* Sources */ = { 209 | isa = PBXSourcesBuildPhase; 210 | buildActionMask = 2147483647; 211 | files = ( 212 | E497B0861CFBE7BA00068A04 /* LBClearCacheTool.m in Sources */, 213 | E497B09A1CFBE8F300068A04 /* SVRadialGradientLayer.m in Sources */, 214 | E497B0991CFBE8F300068A04 /* SVProgressHUD.m in Sources */, 215 | E497B0741CFBE6A700068A04 /* ViewController.m in Sources */, 216 | E497B0951CFBE8F300068A04 /* README.md in Sources */, 217 | E497B0971CFBE8F300068A04 /* SVProgressAnimatedView.m in Sources */, 218 | E497B0711CFBE6A700068A04 /* AppDelegate.m in Sources */, 219 | E497B06E1CFBE6A700068A04 /* main.m in Sources */, 220 | E497B0961CFBE8F300068A04 /* SVIndefiniteAnimatedView.m in Sources */, 221 | ); 222 | runOnlyForDeploymentPostprocessing = 0; 223 | }; 224 | /* End PBXSourcesBuildPhase section */ 225 | 226 | /* Begin PBXVariantGroup section */ 227 | E497B0751CFBE6A700068A04 /* Main.storyboard */ = { 228 | isa = PBXVariantGroup; 229 | children = ( 230 | E497B0761CFBE6A700068A04 /* Base */, 231 | ); 232 | name = Main.storyboard; 233 | sourceTree = ""; 234 | }; 235 | E497B07A1CFBE6A700068A04 /* LaunchScreen.storyboard */ = { 236 | isa = PBXVariantGroup; 237 | children = ( 238 | E497B07B1CFBE6A700068A04 /* Base */, 239 | ); 240 | name = LaunchScreen.storyboard; 241 | sourceTree = ""; 242 | }; 243 | /* End PBXVariantGroup section */ 244 | 245 | /* Begin XCBuildConfiguration section */ 246 | E497B07E1CFBE6A700068A04 /* Debug */ = { 247 | isa = XCBuildConfiguration; 248 | buildSettings = { 249 | ALWAYS_SEARCH_USER_PATHS = NO; 250 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 251 | CLANG_CXX_LIBRARY = "libc++"; 252 | CLANG_ENABLE_MODULES = YES; 253 | CLANG_ENABLE_OBJC_ARC = YES; 254 | CLANG_WARN_BOOL_CONVERSION = YES; 255 | CLANG_WARN_CONSTANT_CONVERSION = YES; 256 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 257 | CLANG_WARN_EMPTY_BODY = YES; 258 | CLANG_WARN_ENUM_CONVERSION = YES; 259 | CLANG_WARN_INT_CONVERSION = YES; 260 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 261 | CLANG_WARN_UNREACHABLE_CODE = YES; 262 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 263 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 264 | COPY_PHASE_STRIP = NO; 265 | DEBUG_INFORMATION_FORMAT = dwarf; 266 | ENABLE_STRICT_OBJC_MSGSEND = YES; 267 | ENABLE_TESTABILITY = YES; 268 | GCC_C_LANGUAGE_STANDARD = gnu99; 269 | GCC_DYNAMIC_NO_PIC = NO; 270 | GCC_NO_COMMON_BLOCKS = YES; 271 | GCC_OPTIMIZATION_LEVEL = 0; 272 | GCC_PREPROCESSOR_DEFINITIONS = ( 273 | "DEBUG=1", 274 | "$(inherited)", 275 | ); 276 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 277 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 278 | GCC_WARN_UNDECLARED_SELECTOR = YES; 279 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 280 | GCC_WARN_UNUSED_FUNCTION = YES; 281 | GCC_WARN_UNUSED_VARIABLE = YES; 282 | IPHONEOS_DEPLOYMENT_TARGET = 9.2; 283 | MTL_ENABLE_DEBUG_INFO = YES; 284 | ONLY_ACTIVE_ARCH = YES; 285 | SDKROOT = iphoneos; 286 | }; 287 | name = Debug; 288 | }; 289 | E497B07F1CFBE6A700068A04 /* Release */ = { 290 | isa = XCBuildConfiguration; 291 | buildSettings = { 292 | ALWAYS_SEARCH_USER_PATHS = NO; 293 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 294 | CLANG_CXX_LIBRARY = "libc++"; 295 | CLANG_ENABLE_MODULES = YES; 296 | CLANG_ENABLE_OBJC_ARC = YES; 297 | CLANG_WARN_BOOL_CONVERSION = YES; 298 | CLANG_WARN_CONSTANT_CONVERSION = YES; 299 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 300 | CLANG_WARN_EMPTY_BODY = YES; 301 | CLANG_WARN_ENUM_CONVERSION = YES; 302 | CLANG_WARN_INT_CONVERSION = YES; 303 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 304 | CLANG_WARN_UNREACHABLE_CODE = YES; 305 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 306 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 307 | COPY_PHASE_STRIP = NO; 308 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 309 | ENABLE_NS_ASSERTIONS = NO; 310 | ENABLE_STRICT_OBJC_MSGSEND = YES; 311 | GCC_C_LANGUAGE_STANDARD = gnu99; 312 | GCC_NO_COMMON_BLOCKS = YES; 313 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 314 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 315 | GCC_WARN_UNDECLARED_SELECTOR = YES; 316 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 317 | GCC_WARN_UNUSED_FUNCTION = YES; 318 | GCC_WARN_UNUSED_VARIABLE = YES; 319 | IPHONEOS_DEPLOYMENT_TARGET = 9.2; 320 | MTL_ENABLE_DEBUG_INFO = NO; 321 | SDKROOT = iphoneos; 322 | VALIDATE_PRODUCT = YES; 323 | }; 324 | name = Release; 325 | }; 326 | E497B0811CFBE6A700068A04 /* Debug */ = { 327 | isa = XCBuildConfiguration; 328 | buildSettings = { 329 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 330 | CODE_SIGN_IDENTITY = "iPhone Developer"; 331 | INFOPLIST_FILE = clearCache/Info.plist; 332 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 333 | PRODUCT_BUNDLE_IDENTIFIER = it.com.clearCache; 334 | PRODUCT_NAME = "$(TARGET_NAME)"; 335 | }; 336 | name = Debug; 337 | }; 338 | E497B0821CFBE6A700068A04 /* Release */ = { 339 | isa = XCBuildConfiguration; 340 | buildSettings = { 341 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 342 | CODE_SIGN_IDENTITY = "iPhone Developer"; 343 | INFOPLIST_FILE = clearCache/Info.plist; 344 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 345 | PRODUCT_BUNDLE_IDENTIFIER = it.com.clearCache; 346 | PRODUCT_NAME = "$(TARGET_NAME)"; 347 | }; 348 | name = Release; 349 | }; 350 | /* End XCBuildConfiguration section */ 351 | 352 | /* Begin XCConfigurationList section */ 353 | E497B0641CFBE6A700068A04 /* Build configuration list for PBXProject "clearCache" */ = { 354 | isa = XCConfigurationList; 355 | buildConfigurations = ( 356 | E497B07E1CFBE6A700068A04 /* Debug */, 357 | E497B07F1CFBE6A700068A04 /* Release */, 358 | ); 359 | defaultConfigurationIsVisible = 0; 360 | defaultConfigurationName = Release; 361 | }; 362 | E497B0801CFBE6A700068A04 /* Build configuration list for PBXNativeTarget "clearCache" */ = { 363 | isa = XCConfigurationList; 364 | buildConfigurations = ( 365 | E497B0811CFBE6A700068A04 /* Debug */, 366 | E497B0821CFBE6A700068A04 /* Release */, 367 | ); 368 | defaultConfigurationIsVisible = 0; 369 | }; 370 | /* End XCConfigurationList section */ 371 | }; 372 | rootObject = E497B0611CFBE6A700068A04 /* Project object */; 373 | } 374 | -------------------------------------------------------------------------------- /clearCache/clearCache.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /clearCache/clearCache/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // clearCache 4 | // 5 | // Created by li bo on 16/5/30. 6 | // Copyright © 2016年 li bo. 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 | -------------------------------------------------------------------------------- /clearCache/clearCache/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // clearCache 4 | // 5 | // Created by li bo on 16/5/30. 6 | // Copyright © 2016年 li bo. 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 | -------------------------------------------------------------------------------- /clearCache/clearCache/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 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /clearCache/clearCache/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 | -------------------------------------------------------------------------------- /clearCache/clearCache/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 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /clearCache/clearCache/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 | 40 | 41 | -------------------------------------------------------------------------------- /clearCache/clearCache/LBClearCacheTool.h: -------------------------------------------------------------------------------- 1 | // 2 | // LBClearCacheTool.h 3 | // clearTest 4 | // 5 | // Created by li bo on 16/5/29. 6 | // Copyright © 2016年 li bo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface LBClearCacheTool : NSObject 12 | 13 | /** 14 | * @author li bo, 16/05/29 15 | * 16 | * 获取path路径文件夹的大小 17 | * 18 | * @param path 要获取大小的文件夹全路径 19 | * 20 | * @return 返回path路径文件夹的大小 21 | */ 22 | + (NSString *)getCacheSizeWithFilePath:(NSString *)path; 23 | 24 | /** 25 | * @author li bo, 16/05/29 26 | * 27 | * 清除path路径文件夹的缓存 28 | * 29 | * @param path 要清除缓存的文件夹全路径 30 | * 31 | * @return 是否清除成功 32 | */ 33 | + (BOOL)clearCacheWithFilePath:(NSString *)path; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /clearCache/clearCache/LBClearCacheTool.m: -------------------------------------------------------------------------------- 1 | // 2 | // LBClearCacheTool.m 3 | // clearTest 4 | // 5 | // Created by li bo on 16/5/29. 6 | // Copyright © 2016年 li bo. All rights reserved. 7 | // 8 | 9 | #import "LBClearCacheTool.h" 10 | 11 | #define fileManager [NSFileManager defaultManager] 12 | 13 | @implementation LBClearCacheTool 14 | 15 | 16 | //获取path路径下文件夹大小 17 | + (NSString *)getCacheSizeWithFilePath:(NSString *)path 18 | { 19 | 20 | //调试 21 | #ifdef DEBUG 22 | //如果文件夹不存在或者不是一个文件夹那么就抛出一个异常 23 | //抛出异常会导致程序闪退,所以只在调试阶段抛出,发布阶段不要再抛了,不然极度影响用户体验 24 | BOOL isDirectory = NO; 25 | BOOL isExist = [fileManager fileExistsAtPath:path isDirectory:&isDirectory]; 26 | if (!isExist || !isDirectory) 27 | { 28 | NSException *exception = [NSException exceptionWithName:@"fileError" reason:@"please check your filePath!" userInfo:nil]; 29 | [exception raise]; 30 | 31 | } 32 | NSLog(@"debug"); 33 | //发布 34 | #else 35 | NSLog(@"post"); 36 | #endif 37 | 38 | //获取“path”文件夹下面的所有文件 39 | NSArray *subpathArray= [fileManager subpathsAtPath:path]; 40 | 41 | NSString *filePath = nil; 42 | NSInteger totleSize=0; 43 | 44 | for (NSString *subpath in subpathArray) 45 | { 46 | //拼接每一个文件的全路径 47 | filePath =[path stringByAppendingPathComponent:subpath]; 48 | 49 | 50 | 51 | //isDirectory,是否是文件夹,默认不是 52 | BOOL isDirectory = NO; 53 | 54 | //isExist,判断文件是否存在 55 | BOOL isExist = [fileManager fileExistsAtPath:filePath isDirectory:&isDirectory]; 56 | 57 | //判断文件是否存在,不存在的话过滤 58 | //如果存在的话,那么是否是文件夹,是的话也过滤 59 | //如果文件既存在又不是文件夹,那么判断它是不是隐藏文件,是的话也过滤 60 | //过滤以上三个情况后,就是一个文件夹里面真实的文件的总大小 61 | //以上判断目的是忽略不需要计算的文件 62 | if (!isExist || isDirectory || [filePath containsString:@".DS"]) continue; 63 | //NSLog(@"%@",filePath); 64 | //指定路径,获取这个路径的属性 65 | //attributesOfItemAtPath:需要传文件夹路径 66 | //但是attributesOfItemAtPath 只可以获得文件属性,不可以获得文件夹属性,这个也就是需要for-in遍历文件夹里面每一个文件的原因 67 | NSDictionary *dict= [fileManager attributesOfItemAtPath:filePath error:nil]; 68 | 69 | NSInteger size=[dict[@"NSFileSize"] integerValue]; 70 | totleSize+=size; 71 | } 72 | 73 | //将文件夹大小转换为 M/KB/B 74 | NSString *totleStr = nil; 75 | 76 | if (totleSize > 1000 * 1000) 77 | { 78 | totleStr = [NSString stringWithFormat:@"%.1fM",totleSize / 1000.0f /1000.0f]; 79 | }else if (totleSize > 1000) 80 | { 81 | totleStr = [NSString stringWithFormat:@"%.1fKB",totleSize / 1000.0f ]; 82 | 83 | }else 84 | { 85 | totleStr = [NSString stringWithFormat:@"%.1fB",totleSize / 1.0f]; 86 | } 87 | 88 | return totleStr; 89 | 90 | 91 | } 92 | 93 | 94 | //清除path文件夹下缓存大小 95 | + (BOOL)clearCacheWithFilePath:(NSString *)path 96 | { 97 | 98 | //拿到path路径的下一级目录的子文件夹 99 | NSArray *subpathArray = [fileManager contentsOfDirectoryAtPath:path error:nil]; 100 | 101 | NSString *message = nil; 102 | NSError *error = nil; 103 | NSString *filePath = nil; 104 | 105 | for (NSString *subpath in subpathArray) 106 | { 107 | filePath =[path stringByAppendingPathComponent:subpath]; 108 | //删除子文件夹 109 | [fileManager removeItemAtPath:filePath error:&error]; 110 | if (error) { 111 | message = [NSString stringWithFormat:@"%@这个路径的文件夹删除失败了,请检查后重新再试",filePath]; 112 | return NO; 113 | 114 | }else { 115 | message = @"成功了"; 116 | } 117 | 118 | } 119 | NSLog(@"%@",message); 120 | 121 | return YES; 122 | 123 | } 124 | @end 125 | -------------------------------------------------------------------------------- /clearCache/clearCache/SVProgressHUD/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011-2016 Sam Vermette, Tobias Tiemerding and contributors. 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | A different license may apply to other resources included in this package, 25 | including Freepik Icons. Please consult their 26 | respective headers for the terms of their individual licenses. 27 | -------------------------------------------------------------------------------- /clearCache/clearCache/SVProgressHUD/README.md: -------------------------------------------------------------------------------- 1 | # SVProgressHUD 2 | 3 | ![Pod Version](https://img.shields.io/cocoapods/v/SVProgressHUD.svg?style=flat) 4 | ![Pod License](https://img.shields.io/cocoapods/l/SVProgressHUD.svg?style=flat) 5 | ![Pod Platform](https://img.shields.io/cocoapods/p/SVProgressHUD.svg?style=flat) 6 | [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) 7 | 8 | `SVProgressHUD` is a clean and easy-to-use HUD meant to display the progress of an ongoing task on iOS and tvOS. 9 | 10 | ![SVProgressHUD](http://f.cl.ly/items/2G1F1Z0M0k0h2U3V1p39/SVProgressHUD.gif) 11 | 12 | ## Demo 13 | 14 | Try `SVProgressHUD` on [Appetize.io](https://appetize.io/app/p8r2cvy8kq74x7q7tjqf5gyatr). 15 | 16 | ## Installation 17 | 18 | ### From CocoaPods 19 | 20 | [CocoaPods](http://cocoapods.org) is a dependency manager for Objective-C, which automates and simplifies the process of using 3rd-party libraries like `SVProgressHUD` in your projects. First, add the following line to your [Podfile](http://guides.cocoapods.org/using/using-cocoapods.html): 21 | 22 | ```ruby 23 | pod 'SVProgressHUD' 24 | ``` 25 | 26 | If you want to use the latest features of `SVProgressHUD` use normal external source dependencies. 27 | 28 | ```ruby 29 | pod 'SVProgressHUD', :git => 'https://github.com/SVProgressHUD/SVProgressHUD.git' 30 | ``` 31 | 32 | This pulls from the `master` branch directly. We are usually careful about what we push there and this is the version we use ourselves in all of our projects. 33 | 34 | Second, install `SVProgressHUD` into your project: 35 | 36 | ```ruby 37 | pod install 38 | ``` 39 | 40 | ### Carthage 41 | 42 | [Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. 43 | 44 | You can install Carthage with [Homebrew](http://brew.sh/) using the following command: 45 | 46 | ```bash 47 | $ brew update 48 | $ brew install carthage 49 | ``` 50 | 51 | To integrate `SVProgressHUD` into your Xcode project using Carthage, specify it in your `Cartfile`: 52 | 53 | ```ogdl 54 | github "SVProgressHUD/SVProgressHUD" 55 | ``` 56 | 57 | Run `carthage update` to build the framework and drag the built `SVProgressHUD.framework` (in Carthage/Build/iOS folder) into your Xcode project (Linked Frameworks and Libraries in `Targets`). 58 | 59 | 60 | ### Manually 61 | 62 | * Drag the `SVProgressHUD/SVProgressHUD` folder into your project. 63 | * Take care that `SVProgressHUD.bundle` is added to `Targets->Build Phases->Copy Bundle Resources`. 64 | * Add the **QuartzCore** framework to your project. 65 | 66 | ## Usage 67 | 68 | (see sample Xcode project in `/Demo`) 69 | 70 | `SVProgressHUD` is created as a singleton (i.e. it doesn't need to be explicitly allocated and instantiated; you directly call `[SVProgressHUD method]`). 71 | 72 | **Use `SVProgressHUD` wisely! Only use it if you absolutely need to perform a task before taking the user forward. Bad use case examples: pull to refresh, infinite scrolling, sending message.** 73 | 74 | Using `SVProgressHUD` in your app will usually look as simple as this (using Grand Central Dispatch): 75 | 76 | ```objective-c 77 | [SVProgressHUD show]; 78 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 79 | // time-consuming task 80 | dispatch_async(dispatch_get_main_queue(), ^{ 81 | [SVProgressHUD dismiss]; 82 | }); 83 | }); 84 | ``` 85 | 86 | ### Showing the HUD 87 | 88 | You can show the status of indeterminate tasks using one of the following: 89 | 90 | ```objective-c 91 | + (void)show; 92 | + (void)showWithStatus:(NSString*)string; 93 | ``` 94 | 95 | If you'd like the HUD to reflect the progress of a task, use one of these: 96 | 97 | ```objective-c 98 | + (void)showProgress:(CGFloat)progress; 99 | + (void)showProgress:(CGFloat)progress status:(NSString*)status; 100 | ``` 101 | 102 | ### Dismissing the HUD 103 | 104 | The HUD can be dismissed using: 105 | 106 | ```objective-c 107 | + (void)dismiss; 108 | + (void)dismissWithDelay:(NSTimeInterval)delay; 109 | ``` 110 | 111 | If you'd like to stack HUDs, you can balance out every show call using: 112 | 113 | ```objective-c 114 | + (void)popActivity; 115 | ``` 116 | 117 | The HUD will get dismissed once the `popActivity` calls will match the number of show calls. 118 | 119 | Or show a confirmation glyph before before getting dismissed a little bit later. The display time depends on `minimumDismissTimeInterval` and the length of the given string. 120 | 121 | ```objective-c 122 | + (void)showInfoWithStatus:(NSString*)string; 123 | + (void)showSuccessWithStatus:(NSString*)string; 124 | + (void)showErrorWithStatus:(NSString*)string; 125 | + (void)showImage:(UIImage*)image status:(NSString*)string; 126 | ``` 127 | 128 | ## Customization 129 | 130 | `SVProgressHUD` can be customized via the following methods: 131 | 132 | ```objective-c 133 | + (void)setDefaultStyle:(SVProgressHUDStyle)style; // default is SVProgressHUDStyleLight 134 | + (void)setDefaultMaskType:(SVProgressHUDMaskType)maskType; // default is SVProgressHUDMaskTypeNone 135 | + (void)setDefaultAnimationType:(SVProgressHUDAnimationType)type; // default is SVProgressHUDAnimationTypeFlat 136 | + (void)setMinimumSize:(CGSize)minimumSize; // default is CGSizeZero, can be used to avoid resizing for a larger message 137 | + (void)setRingThickness:(CGFloat)width; // default is 2 pt 138 | + (void)setRingRadius:(CGFloat)radius; // default is 18 pt 139 | + (void)setRingNoTextRadius:(CGFloat)radius; // default is 24 pt 140 | + (void)setCornerRadius:(CGFloat)cornerRadius; // default is 14 pt 141 | + (void)setFont:(UIFont*)font; // default is [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline] 142 | + (void)setForegroundColor:(UIColor*)color; // default is [UIColor blackColor], only used for SVProgressHUDStyleCustom 143 | + (void)setBackgroundColor:(UIColor*)color; // default is [UIColor whiteColor], only used for SVProgressHUDStyleCustom 144 | + (void)setBackgroundLayerColor:(UIColor*)color; // default is [UIColor colorWithWhite:0 alpha:0.4], only used for SVProgressHUDMaskTypeCustom 145 | + (void)setInfoImage:(UIImage*)image; // default is the bundled info image provided by Freepik 146 | + (void)setSuccessImage:(UIImage*)image; // default is bundled success image from Freepik 147 | + (void)setErrorImage:(UIImage*)image; // default is bundled error image from Freepik 148 | + (void)setViewForExtension:(UIView*)view; // default is nil, only used if #define SV_APP_EXTENSIONS is set 149 | + (void)setMinimumDismissTimeInterval:(NSTimeInterval)interval; // default is 5.0 seconds 150 | + (void)setFadeInAnimationDuration:(NSTimeInterval)duration; // default is 0.15 seconds 151 | + (void)setFadeOutAnimationDuration:(NSTimeInterval)duration; // default is 0.15 seconds 152 | ``` 153 | 154 | Additionally `SVProgressHUD` supports the `UIAppearance` protocol for most of the above methods. 155 | 156 | ### Hint 157 | 158 | As standard `SVProgressHUD` offers two preconfigured styles: 159 | 160 | * `SVProgressHUDStyleLight`: White background with black spinner and text 161 | * `SVProgressHUDStyleDark`: Black background with white spinner and text 162 | 163 | If you want to use custom colors with `setForegroundColor` and `setBackgroundColor:` don't forget to set `SVProgressHUDStyleCustom` via `setDefaultStyle:`. 164 | 165 | ## Notifications 166 | 167 | `SVProgressHUD` posts four notifications via `NSNotificationCenter` in response to being shown/dismissed: 168 | * `SVProgressHUDWillAppearNotification` when the show animation starts 169 | * `SVProgressHUDDidAppearNotification` when the show animation completes 170 | * `SVProgressHUDWillDisappearNotification` when the dismiss animation starts 171 | * `SVProgressHUDDidDisappearNotification` when the dismiss animation completes 172 | 173 | Each notification passes a `userInfo` dictionary holding the HUD's status string (if any), retrievable via `SVProgressHUDStatusUserInfoKey`. 174 | 175 | `SVProgressHUD` also posts `SVProgressHUDDidReceiveTouchEventNotification` when users touch on the overall screen or `SVProgressHUDDidTouchDownInsideNotification` when a user touches on the HUD directly. For this notifications `userInfo` is not passed but the object parameter contains the `UIEvent` that related to the touch. 176 | 177 | ## App Extensions 178 | 179 | When using `SVProgressHUD` in an App Extension, `#define SV_APP_EXTENSIONS` to avoid using unavailable APIs. Additionally call `setViewForExtension:` from your extensions view controller with `self.view`. 180 | 181 | ## Contributing to this project 182 | 183 | If you have feature requests or bug reports, feel free to help out by sending pull requests or by [creating new issues](https://github.com/SVProgressHUD/SVProgressHUD/issues/new). Please take a moment to 184 | review the guidelines written by [Nicolas Gallagher](https://github.com/necolas): 185 | 186 | * [Bug reports](https://github.com/necolas/issue-guidelines/blob/master/CONTRIBUTING.md#bugs) 187 | * [Feature requests](https://github.com/necolas/issue-guidelines/blob/master/CONTRIBUTING.md#features) 188 | * [Pull requests](https://github.com/necolas/issue-guidelines/blob/master/CONTRIBUTING.md#pull-requests) 189 | 190 | ## License 191 | 192 | `SVProgressHUD` is distributed under the terms and conditions of the [MIT license](https://github.com/SVProgressHUD/SVProgressHUD/blob/master/LICENSE.txt). The success, error and info icons are made by [Freepik](http://www.freepik.com) from [Flaticon](http://www.flaticon.com) and are licensed under [Creative Commons BY 3.0](http://creativecommons.org/licenses/by/3.0/). 193 | 194 | ## Credits 195 | 196 | `SVProgressHUD` is brought to you by [Sam Vermette](http://samvermette.com), [Tobias Tiemerding](http://tiemerding.com) and [contributors to the project](https://github.com/SVProgressHUD/SVProgressHUD/contributors). If you're using `SVProgressHUD` in your project, attribution would be very appreciated. 197 | -------------------------------------------------------------------------------- /clearCache/clearCache/SVProgressHUD/SVProgressHUD/SVIndefiniteAnimatedView.h: -------------------------------------------------------------------------------- 1 | // 2 | // SVIndefiniteAnimatedView.h 3 | // SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD 4 | // 5 | // Copyright (c) 2014-2016 Guillaume Campagna. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | @interface SVIndefiniteAnimatedView : UIView 11 | 12 | @property (nonatomic, assign) CGFloat strokeThickness; 13 | @property (nonatomic, assign) CGFloat radius; 14 | @property (nonatomic, strong) UIColor *strokeColor; 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /clearCache/clearCache/SVProgressHUD/SVProgressHUD/SVIndefiniteAnimatedView.m: -------------------------------------------------------------------------------- 1 | // 2 | // SVIndefiniteAnimatedView.m 3 | // SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD 4 | // 5 | // Copyright (c) 2014-2016 Guillaume Campagna. All rights reserved. 6 | // 7 | 8 | #import "SVIndefiniteAnimatedView.h" 9 | #import "SVProgressHUD.h" 10 | 11 | @interface SVIndefiniteAnimatedView () 12 | 13 | @property (nonatomic, strong) CAShapeLayer *indefiniteAnimatedLayer; 14 | 15 | @end 16 | 17 | @implementation SVIndefiniteAnimatedView 18 | 19 | - (void)willMoveToSuperview:(UIView*)newSuperview { 20 | if (newSuperview) { 21 | [self layoutAnimatedLayer]; 22 | } else { 23 | [_indefiniteAnimatedLayer removeFromSuperlayer]; 24 | _indefiniteAnimatedLayer = nil; 25 | } 26 | } 27 | 28 | - (void)layoutAnimatedLayer { 29 | CALayer *layer = self.indefiniteAnimatedLayer; 30 | [self.layer addSublayer:layer]; 31 | 32 | CGFloat widthDiff = CGRectGetWidth(self.bounds) - CGRectGetWidth(layer.bounds); 33 | CGFloat heightDiff = CGRectGetHeight(self.bounds) - CGRectGetHeight(layer.bounds); 34 | layer.position = CGPointMake(CGRectGetWidth(self.bounds) - CGRectGetWidth(layer.bounds) / 2 - widthDiff / 2, CGRectGetHeight(self.bounds) - CGRectGetHeight(layer.bounds) / 2 - heightDiff / 2); 35 | } 36 | 37 | - (CAShapeLayer*)indefiniteAnimatedLayer { 38 | if(!_indefiniteAnimatedLayer) { 39 | CGPoint arcCenter = CGPointMake(self.radius+self.strokeThickness/2+5, self.radius+self.strokeThickness/2+5); 40 | UIBezierPath* smoothedPath = [UIBezierPath bezierPathWithArcCenter:arcCenter radius:self.radius startAngle:(CGFloat) (M_PI*3/2) endAngle:(CGFloat) (M_PI/2+M_PI*5) clockwise:YES]; 41 | 42 | _indefiniteAnimatedLayer = [CAShapeLayer layer]; 43 | _indefiniteAnimatedLayer.contentsScale = [[UIScreen mainScreen] scale]; 44 | _indefiniteAnimatedLayer.frame = CGRectMake(0.0f, 0.0f, arcCenter.x*2, arcCenter.y*2); 45 | _indefiniteAnimatedLayer.fillColor = [UIColor clearColor].CGColor; 46 | _indefiniteAnimatedLayer.strokeColor = self.strokeColor.CGColor; 47 | _indefiniteAnimatedLayer.lineWidth = self.strokeThickness; 48 | _indefiniteAnimatedLayer.lineCap = kCALineCapRound; 49 | _indefiniteAnimatedLayer.lineJoin = kCALineJoinBevel; 50 | _indefiniteAnimatedLayer.path = smoothedPath.CGPath; 51 | 52 | CALayer *maskLayer = [CALayer layer]; 53 | 54 | NSBundle *bundle = [NSBundle bundleForClass:[SVProgressHUD class]]; 55 | NSURL *url = [bundle URLForResource:@"SVProgressHUD" withExtension:@"bundle"]; 56 | NSBundle *imageBundle = [NSBundle bundleWithURL:url]; 57 | 58 | NSString *path = [imageBundle pathForResource:@"angle-mask" ofType:@"png"]; 59 | 60 | maskLayer.contents = (__bridge id)[[UIImage imageWithContentsOfFile:path] CGImage]; 61 | maskLayer.frame = _indefiniteAnimatedLayer.bounds; 62 | _indefiniteAnimatedLayer.mask = maskLayer; 63 | 64 | NSTimeInterval animationDuration = 1; 65 | CAMediaTimingFunction *linearCurve = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; 66 | 67 | CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"]; 68 | animation.fromValue = (id) 0; 69 | animation.toValue = @(M_PI*2); 70 | animation.duration = animationDuration; 71 | animation.timingFunction = linearCurve; 72 | animation.removedOnCompletion = NO; 73 | animation.repeatCount = INFINITY; 74 | animation.fillMode = kCAFillModeForwards; 75 | animation.autoreverses = NO; 76 | [_indefiniteAnimatedLayer.mask addAnimation:animation forKey:@"rotate"]; 77 | 78 | CAAnimationGroup *animationGroup = [CAAnimationGroup animation]; 79 | animationGroup.duration = animationDuration; 80 | animationGroup.repeatCount = INFINITY; 81 | animationGroup.removedOnCompletion = NO; 82 | animationGroup.timingFunction = linearCurve; 83 | 84 | CABasicAnimation *strokeStartAnimation = [CABasicAnimation animationWithKeyPath:@"strokeStart"]; 85 | strokeStartAnimation.fromValue = @0.015; 86 | strokeStartAnimation.toValue = @0.515; 87 | 88 | CABasicAnimation *strokeEndAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; 89 | strokeEndAnimation.fromValue = @0.485; 90 | strokeEndAnimation.toValue = @0.985; 91 | 92 | animationGroup.animations = @[strokeStartAnimation, strokeEndAnimation]; 93 | [_indefiniteAnimatedLayer addAnimation:animationGroup forKey:@"progress"]; 94 | 95 | } 96 | return _indefiniteAnimatedLayer; 97 | } 98 | 99 | - (void)setFrame:(CGRect)frame { 100 | if(!CGRectEqualToRect(frame, super.frame)) { 101 | [super setFrame:frame]; 102 | 103 | if(self.superview) { 104 | [self layoutAnimatedLayer]; 105 | } 106 | } 107 | 108 | } 109 | 110 | - (void)setRadius:(CGFloat)radius { 111 | if(radius != _radius) { 112 | _radius = radius; 113 | 114 | [_indefiniteAnimatedLayer removeFromSuperlayer]; 115 | _indefiniteAnimatedLayer = nil; 116 | 117 | if(self.superview) { 118 | [self layoutAnimatedLayer]; 119 | } 120 | } 121 | } 122 | 123 | - (void)setStrokeColor:(UIColor*)strokeColor { 124 | _strokeColor = strokeColor; 125 | _indefiniteAnimatedLayer.strokeColor = strokeColor.CGColor; 126 | } 127 | 128 | - (void)setStrokeThickness:(CGFloat)strokeThickness { 129 | _strokeThickness = strokeThickness; 130 | _indefiniteAnimatedLayer.lineWidth = _strokeThickness; 131 | } 132 | 133 | - (CGSize)sizeThatFits:(CGSize)size { 134 | return CGSizeMake((self.radius+self.strokeThickness/2+5)*2, (self.radius+self.strokeThickness/2+5)*2); 135 | } 136 | 137 | @end 138 | -------------------------------------------------------------------------------- /clearCache/clearCache/SVProgressHUD/SVProgressHUD/SVProgressAnimatedView.h: -------------------------------------------------------------------------------- 1 | // 2 | // SVProgressAnimatedView.h 3 | // SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD 4 | // 5 | // Copyright (c) 2016 Tobias Tiemerding. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | @interface SVProgressAnimatedView : UIView 11 | 12 | @property (nonatomic, assign) CGFloat radius; 13 | @property (nonatomic, assign) CGFloat strokeThickness; 14 | @property (nonatomic, strong) UIColor *strokeColor; 15 | @property (nonatomic, assign) CGFloat strokeEnd; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /clearCache/clearCache/SVProgressHUD/SVProgressHUD/SVProgressAnimatedView.m: -------------------------------------------------------------------------------- 1 | // 2 | // SVProgressAnimatedView.m 3 | // SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD 4 | // 5 | // Copyright (c) 2016 Tobias Tiemerding. All rights reserved. 6 | // 7 | 8 | #import "SVProgressAnimatedView.h" 9 | 10 | @interface SVProgressAnimatedView () 11 | 12 | @property (nonatomic, strong) CAShapeLayer *ringAnimatedLayer; 13 | 14 | @end 15 | 16 | @implementation SVProgressAnimatedView 17 | 18 | - (void)willMoveToSuperview:(UIView*)newSuperview { 19 | if (newSuperview) { 20 | [self layoutAnimatedLayer]; 21 | } else { 22 | [_ringAnimatedLayer removeFromSuperlayer]; 23 | _ringAnimatedLayer = nil; 24 | } 25 | } 26 | 27 | - (void)layoutAnimatedLayer { 28 | CALayer *layer = self.ringAnimatedLayer; 29 | [self.layer addSublayer:layer]; 30 | 31 | CGFloat widthDiff = CGRectGetWidth(self.bounds) - CGRectGetWidth(layer.bounds); 32 | CGFloat heightDiff = CGRectGetHeight(self.bounds) - CGRectGetHeight(layer.bounds); 33 | layer.position = CGPointMake(CGRectGetWidth(self.bounds) - CGRectGetWidth(layer.bounds) / 2 - widthDiff / 2, CGRectGetHeight(self.bounds) - CGRectGetHeight(layer.bounds) / 2 - heightDiff / 2); 34 | } 35 | 36 | - (CAShapeLayer*)ringAnimatedLayer { 37 | if(!_ringAnimatedLayer) { 38 | CGPoint arcCenter = CGPointMake(self.radius+self.strokeThickness/2+5, self.radius+self.strokeThickness/2+5); 39 | UIBezierPath* smoothedPath = [UIBezierPath bezierPathWithArcCenter:arcCenter radius:self.radius startAngle:(CGFloat)-M_PI_2 endAngle:(CGFloat) (M_PI + M_PI_2) clockwise:YES]; 40 | 41 | _ringAnimatedLayer = [CAShapeLayer layer]; 42 | _ringAnimatedLayer.contentsScale = [[UIScreen mainScreen] scale]; 43 | _ringAnimatedLayer.frame = CGRectMake(0.0f, 0.0f, arcCenter.x*2, arcCenter.y*2); 44 | _ringAnimatedLayer.fillColor = [UIColor clearColor].CGColor; 45 | _ringAnimatedLayer.strokeColor = self.strokeColor.CGColor; 46 | _ringAnimatedLayer.lineWidth = self.strokeThickness; 47 | _ringAnimatedLayer.lineCap = kCALineCapRound; 48 | _ringAnimatedLayer.lineJoin = kCALineJoinBevel; 49 | _ringAnimatedLayer.path = smoothedPath.CGPath; 50 | } 51 | return _ringAnimatedLayer; 52 | } 53 | 54 | - (void)setFrame:(CGRect)frame { 55 | if(!CGRectEqualToRect(frame, super.frame)) { 56 | [super setFrame:frame]; 57 | 58 | if(self.superview) { 59 | [self layoutAnimatedLayer]; 60 | } 61 | } 62 | 63 | } 64 | 65 | - (void)setRadius:(CGFloat)radius { 66 | if(radius != _radius) { 67 | _radius = radius; 68 | 69 | [_ringAnimatedLayer removeFromSuperlayer]; 70 | _ringAnimatedLayer = nil; 71 | 72 | if(self.superview) { 73 | [self layoutAnimatedLayer]; 74 | } 75 | } 76 | } 77 | 78 | - (void)setStrokeColor:(UIColor*)strokeColor { 79 | _strokeColor = strokeColor; 80 | _ringAnimatedLayer.strokeColor = strokeColor.CGColor; 81 | } 82 | 83 | - (void)setStrokeThickness:(CGFloat)strokeThickness { 84 | _strokeThickness = strokeThickness; 85 | _ringAnimatedLayer.lineWidth = _strokeThickness; 86 | } 87 | 88 | - (void)setStrokeEnd:(CGFloat)strokeEnd { 89 | _strokeEnd = strokeEnd; 90 | _ringAnimatedLayer.strokeEnd = _strokeEnd; 91 | } 92 | 93 | 94 | - (CGSize)sizeThatFits:(CGSize)size { 95 | return CGSizeMake((self.radius+self.strokeThickness/2+5)*2, (self.radius+self.strokeThickness/2+5)*2); 96 | } 97 | 98 | @end 99 | -------------------------------------------------------------------------------- /clearCache/clearCache/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/angle-mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LBCoderLee/ClearFileCache/2605d484060fedca2e1036d053e91efeb8410a9f/clearCache/clearCache/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/angle-mask.png -------------------------------------------------------------------------------- /clearCache/clearCache/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/angle-mask@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LBCoderLee/ClearFileCache/2605d484060fedca2e1036d053e91efeb8410a9f/clearCache/clearCache/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/angle-mask@2x.png -------------------------------------------------------------------------------- /clearCache/clearCache/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/angle-mask@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LBCoderLee/ClearFileCache/2605d484060fedca2e1036d053e91efeb8410a9f/clearCache/clearCache/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/angle-mask@3x.png -------------------------------------------------------------------------------- /clearCache/clearCache/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LBCoderLee/ClearFileCache/2605d484060fedca2e1036d053e91efeb8410a9f/clearCache/clearCache/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/error.png -------------------------------------------------------------------------------- /clearCache/clearCache/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/error@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LBCoderLee/ClearFileCache/2605d484060fedca2e1036d053e91efeb8410a9f/clearCache/clearCache/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/error@2x.png -------------------------------------------------------------------------------- /clearCache/clearCache/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/error@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LBCoderLee/ClearFileCache/2605d484060fedca2e1036d053e91efeb8410a9f/clearCache/clearCache/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/error@3x.png -------------------------------------------------------------------------------- /clearCache/clearCache/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LBCoderLee/ClearFileCache/2605d484060fedca2e1036d053e91efeb8410a9f/clearCache/clearCache/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/info.png -------------------------------------------------------------------------------- /clearCache/clearCache/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/info@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LBCoderLee/ClearFileCache/2605d484060fedca2e1036d053e91efeb8410a9f/clearCache/clearCache/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/info@2x.png -------------------------------------------------------------------------------- /clearCache/clearCache/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/info@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LBCoderLee/ClearFileCache/2605d484060fedca2e1036d053e91efeb8410a9f/clearCache/clearCache/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/info@3x.png -------------------------------------------------------------------------------- /clearCache/clearCache/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LBCoderLee/ClearFileCache/2605d484060fedca2e1036d053e91efeb8410a9f/clearCache/clearCache/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/success.png -------------------------------------------------------------------------------- /clearCache/clearCache/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/success@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LBCoderLee/ClearFileCache/2605d484060fedca2e1036d053e91efeb8410a9f/clearCache/clearCache/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/success@2x.png -------------------------------------------------------------------------------- /clearCache/clearCache/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/success@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LBCoderLee/ClearFileCache/2605d484060fedca2e1036d053e91efeb8410a9f/clearCache/clearCache/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/success@3x.png -------------------------------------------------------------------------------- /clearCache/clearCache/SVProgressHUD/SVProgressHUD/SVProgressHUD.h: -------------------------------------------------------------------------------- 1 | // 2 | // SVProgressHUD.h 3 | // SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD 4 | // 5 | // Copyright (c) 2011-2016 Sam Vermette and contributors. All rights reserved. 6 | // 7 | 8 | #import 9 | #import 10 | 11 | #if __IPHONE_OS_VERSION_MAX_ALLOWED < 70000 12 | 13 | #define UI_APPEARANCE_SELECTOR 14 | 15 | #endif 16 | 17 | extern NSString * const SVProgressHUDDidReceiveTouchEventNotification; 18 | extern NSString * const SVProgressHUDDidTouchDownInsideNotification; 19 | extern NSString * const SVProgressHUDWillDisappearNotification; 20 | extern NSString * const SVProgressHUDDidDisappearNotification; 21 | extern NSString * const SVProgressHUDWillAppearNotification; 22 | extern NSString * const SVProgressHUDDidAppearNotification; 23 | 24 | extern NSString * const SVProgressHUDStatusUserInfoKey; 25 | 26 | typedef NS_ENUM(NSInteger, SVProgressHUDStyle) { 27 | SVProgressHUDStyleLight, // default style, white HUD with black text, HUD background will be blurred on iOS 8 and above 28 | SVProgressHUDStyleDark, // black HUD and white text, HUD background will be blurred on iOS 8 and above 29 | SVProgressHUDStyleCustom // uses the fore- and background color properties 30 | }; 31 | 32 | typedef NS_ENUM(NSUInteger, SVProgressHUDMaskType) { 33 | SVProgressHUDMaskTypeNone = 1, // default mask type, allow user interactions while HUD is displayed 34 | SVProgressHUDMaskTypeClear, // don't allow user interactions 35 | SVProgressHUDMaskTypeBlack, // don't allow user interactions and dim the UI in the back of the HUD, as on iOS 7 and above 36 | SVProgressHUDMaskTypeGradient, // don't allow user interactions and dim the UI with a a-la UIAlertView background gradient, as on iOS 6 37 | SVProgressHUDMaskTypeCustom // don't allow user interactions and dim the UI in the back of the HUD with a custom color 38 | }; 39 | 40 | typedef NS_ENUM(NSUInteger, SVProgressHUDAnimationType) { 41 | SVProgressHUDAnimationTypeFlat, // default animation type, custom flat animation (indefinite animated ring) 42 | SVProgressHUDAnimationTypeNative // iOS native UIActivityIndicatorView 43 | }; 44 | 45 | @interface SVProgressHUD : UIView 46 | 47 | #pragma mark - Customization 48 | 49 | @property (assign, nonatomic) SVProgressHUDStyle defaultStyle UI_APPEARANCE_SELECTOR; // default is SVProgressHUDStyleLight 50 | @property (assign, nonatomic) SVProgressHUDMaskType defaultMaskType UI_APPEARANCE_SELECTOR; // default is SVProgressHUDMaskTypeNone 51 | @property (assign, nonatomic) SVProgressHUDAnimationType defaultAnimationType UI_APPEARANCE_SELECTOR; // default is SVProgressHUDAnimationTypeFlat 52 | @property (assign, nonatomic) CGSize minimumSize UI_APPEARANCE_SELECTOR; // default is CGSizeZero, can be used to avoid resizing for a larger message 53 | @property (assign, nonatomic) CGFloat ringThickness UI_APPEARANCE_SELECTOR; // default is 2 pt 54 | @property (assign, nonatomic) CGFloat ringRadius UI_APPEARANCE_SELECTOR; // default is 18 pt 55 | @property (assign, nonatomic) CGFloat ringNoTextRadius UI_APPEARANCE_SELECTOR; // default is 24 pt 56 | @property (assign, nonatomic) CGFloat cornerRadius UI_APPEARANCE_SELECTOR; // default is 14 pt 57 | @property (strong, nonatomic) UIFont *font UI_APPEARANCE_SELECTOR; // default is [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline] 58 | @property (strong, nonatomic) UIColor *backgroundColor UI_APPEARANCE_SELECTOR; // default is [UIColor whiteColor] 59 | @property (strong, nonatomic) UIColor *foregroundColor UI_APPEARANCE_SELECTOR; // default is [UIColor blackColor] 60 | @property (strong, nonatomic) UIColor *backgroundLayerColor UI_APPEARANCE_SELECTOR; // default is [UIColor colorWithWhite:0 alpha:0.4] 61 | @property (strong, nonatomic) UIImage *infoImage UI_APPEARANCE_SELECTOR; // default is the bundled info image provided by Freepik 62 | @property (strong, nonatomic) UIImage *successImage UI_APPEARANCE_SELECTOR; // default is the bundled success image provided by Freepik 63 | @property (strong, nonatomic) UIImage *errorImage UI_APPEARANCE_SELECTOR; // default is the bundled error image provided by Freepik 64 | @property (strong, nonatomic) UIView *viewForExtension UI_APPEARANCE_SELECTOR; // default is nil, only used if #define SV_APP_EXTENSIONS is set 65 | @property (assign, nonatomic) NSTimeInterval minimumDismissTimeInterval; // default is 5.0 seconds 66 | 67 | @property (assign, nonatomic) UIOffset offsetFromCenter UI_APPEARANCE_SELECTOR; // default is 0, 0 68 | 69 | @property (assign, nonatomic) NSTimeInterval fadeInAnimationDuration; // default is 0.15 70 | @property (assign, nonatomic) NSTimeInterval fadeOutAnimationDuration; // default is 0.15 71 | 72 | 73 | + (void)setDefaultStyle:(SVProgressHUDStyle)style; // default is SVProgressHUDStyleLight 74 | + (void)setDefaultMaskType:(SVProgressHUDMaskType)maskType; // default is SVProgressHUDMaskTypeNone 75 | + (void)setDefaultAnimationType:(SVProgressHUDAnimationType)type; // default is SVProgressHUDAnimationTypeFlat 76 | + (void)setMinimumSize:(CGSize)minimumSize; // default is CGSizeZero, can be used to avoid resizing for a larger message 77 | + (void)setRingThickness:(CGFloat)ringThickness; // default is 2 pt 78 | + (void)setRingRadius:(CGFloat)radius; // default is 18 pt 79 | + (void)setRingNoTextRadius:(CGFloat)radius; // default is 24 pt 80 | + (void)setCornerRadius:(CGFloat)cornerRadius; // default is 14 pt 81 | + (void)setFont:(UIFont*)font; // default is [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline] 82 | + (void)setForegroundColor:(UIColor*)color; // default is [UIColor blackColor], only used for SVProgressHUDStyleCustom 83 | + (void)setBackgroundColor:(UIColor*)color; // default is [UIColor whiteColor], only used for SVProgressHUDStyleCustom 84 | + (void)setBackgroundLayerColor:(UIColor*)color; // default is [UIColor colorWithWhite:0 alpha:0.5], only used for SVProgressHUDMaskTypeBlack 85 | + (void)setInfoImage:(UIImage*)image; // default is the bundled info image provided by Freepik 86 | + (void)setSuccessImage:(UIImage*)image; // default is the bundled success image provided by Freepik 87 | + (void)setErrorImage:(UIImage*)image; // default is the bundled error image provided by Freepik 88 | + (void)setViewForExtension:(UIView*)view; // default is nil, only used if #define SV_APP_EXTENSIONS is set 89 | + (void)setMinimumDismissTimeInterval:(NSTimeInterval)interval; // default is 5.0 seconds 90 | + (void)setFadeInAnimationDuration:(NSTimeInterval)duration; // default is 0.15 seconds 91 | + (void)setFadeOutAnimationDuration:(NSTimeInterval)duration; // default is 0.15 seconds 92 | 93 | #pragma mark - Show Methods 94 | 95 | + (void)show; 96 | + (void)showWithMaskType:(SVProgressHUDMaskType)maskType __attribute__((deprecated("Use show and setDefaultMaskType: instead."))); 97 | + (void)showWithStatus:(NSString*)status; 98 | + (void)showWithStatus:(NSString*)status maskType:(SVProgressHUDMaskType)maskType __attribute__((deprecated("Use showWithStatus: and setDefaultMaskType: instead."))); 99 | 100 | + (void)showProgress:(float)progress; 101 | + (void)showProgress:(float)progress maskType:(SVProgressHUDMaskType)maskType __attribute__((deprecated("Use showProgress: and setDefaultMaskType: instead."))); 102 | + (void)showProgress:(float)progress status:(NSString*)status; 103 | + (void)showProgress:(float)progress status:(NSString*)status maskType:(SVProgressHUDMaskType)maskType __attribute__((deprecated("Use showProgress:status: and setDefaultMaskType: instead."))); 104 | 105 | + (void)setStatus:(NSString*)status; // change the HUD loading status while it's showing 106 | 107 | // stops the activity indicator, shows a glyph + status, and dismisses the HUD a little bit later 108 | + (void)showInfoWithStatus:(NSString*)status; 109 | + (void)showInfoWithStatus:(NSString*)status maskType:(SVProgressHUDMaskType)maskType __attribute__((deprecated("Use showInfoWithStatus: and setDefaultMaskType: instead."))); 110 | + (void)showSuccessWithStatus:(NSString*)status; 111 | + (void)showSuccessWithStatus:(NSString*)status maskType:(SVProgressHUDMaskType)maskType __attribute__((deprecated("Use showSuccessWithStatus: and setDefaultMaskType: instead."))); 112 | + (void)showErrorWithStatus:(NSString*)status; 113 | + (void)showErrorWithStatus:(NSString*)status maskType:(SVProgressHUDMaskType)maskType __attribute__((deprecated("Use showErrorWithStatus: and setDefaultMaskType: instead."))); 114 | 115 | // shows a image + status, use 28x28 white PNGs 116 | + (void)showImage:(UIImage*)image status:(NSString*)status; 117 | + (void)showImage:(UIImage*)image status:(NSString*)status maskType:(SVProgressHUDMaskType)maskType __attribute__((deprecated("Use showImage:status: and setDefaultMaskType: instead."))); 118 | 119 | + (void)setOffsetFromCenter:(UIOffset)offset; 120 | + (void)resetOffsetFromCenter; 121 | 122 | + (void)popActivity; // decrease activity count, if activity count == 0 the HUD is dismissed 123 | + (void)dismiss; 124 | + (void)dismissWithDelay:(NSTimeInterval)delay; 125 | 126 | + (BOOL)isVisible; 127 | 128 | + (NSTimeInterval)displayDurationForString:(NSString*)string; 129 | 130 | @end 131 | 132 | -------------------------------------------------------------------------------- /clearCache/clearCache/SVProgressHUD/SVProgressHUD/SVProgressHUD.m: -------------------------------------------------------------------------------- 1 | // 2 | // SVProgressHUD.h 3 | // SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD 4 | // 5 | // Copyright (c) 2011-2016 Sam Vermette and contributors. All rights reserved. 6 | // 7 | 8 | #if !__has_feature(objc_arc) 9 | #error SVProgressHUD is ARC only. Either turn on ARC for the project or use -fobjc-arc flag 10 | #endif 11 | 12 | #import "SVProgressHUD.h" 13 | #import "SVIndefiniteAnimatedView.h" 14 | #import "SVProgressAnimatedView.h" 15 | #import "SVRadialGradientLayer.h" 16 | 17 | NSString * const SVProgressHUDDidReceiveTouchEventNotification = @"SVProgressHUDDidReceiveTouchEventNotification"; 18 | NSString * const SVProgressHUDDidTouchDownInsideNotification = @"SVProgressHUDDidTouchDownInsideNotification"; 19 | NSString * const SVProgressHUDWillDisappearNotification = @"SVProgressHUDWillDisappearNotification"; 20 | NSString * const SVProgressHUDDidDisappearNotification = @"SVProgressHUDDidDisappearNotification"; 21 | NSString * const SVProgressHUDWillAppearNotification = @"SVProgressHUDWillAppearNotification"; 22 | NSString * const SVProgressHUDDidAppearNotification = @"SVProgressHUDDidAppearNotification"; 23 | 24 | NSString * const SVProgressHUDStatusUserInfoKey = @"SVProgressHUDStatusUserInfoKey"; 25 | 26 | static const CGFloat SVProgressHUDParallaxDepthPoints = 10; 27 | static const CGFloat SVProgressHUDUndefinedProgress = -1; 28 | static const CGFloat SVProgressHUDDefaultAnimationDuration = 0.15; 29 | 30 | @interface SVProgressHUD () 31 | 32 | @property (nonatomic, strong, readonly) NSTimer *fadeOutTimer; 33 | @property (nonatomic, readonly, getter = isClear) BOOL clear; 34 | 35 | @property (nonatomic, strong) UIControl *overlayView; 36 | @property (nonatomic, strong) UIView *hudView; 37 | 38 | @property (nonatomic, strong) UILabel *statusLabel; 39 | @property (nonatomic, strong) UIImageView *imageView; 40 | @property (nonatomic, strong) UIView *indefiniteAnimatedView; 41 | @property (nonatomic, strong) SVProgressAnimatedView *ringView; 42 | @property (nonatomic, strong) SVProgressAnimatedView *backgroundRingView; 43 | @property (nonatomic, strong) CALayer *backgroundLayer; 44 | 45 | @property (nonatomic, readwrite) CGFloat progress; 46 | @property (nonatomic, readwrite) NSUInteger activityCount; 47 | 48 | @property (nonatomic, readonly) CGFloat visibleKeyboardHeight; 49 | 50 | - (void)updateHUDFrame; 51 | - (void)updateMask; 52 | - (void)updateBlurBounds; 53 | #if TARGET_OS_IOS 54 | - (void)updateMotionEffectForOrientation:(UIInterfaceOrientation)orientation; 55 | #endif 56 | - (void)updateMotionEffectForXMotionEffectType:(UIInterpolatingMotionEffectType)xMotionEffectType yMotionEffectType:(UIInterpolatingMotionEffectType)yMotionEffectType; 57 | - (void)updateViewHierachy; 58 | 59 | - (void)setStatus:(NSString*)status; 60 | - (void)setFadeOutTimer:(NSTimer*)timer; 61 | 62 | - (void)registerNotifications; 63 | - (NSDictionary*)notificationUserInfo; 64 | 65 | - (void)positionHUD:(NSNotification*)notification; 66 | - (void)moveToPoint:(CGPoint)newCenter rotateAngle:(CGFloat)angle; 67 | 68 | - (void)overlayViewDidReceiveTouchEvent:(id)sender forEvent:(UIEvent*)event; 69 | 70 | - (void)showProgress:(float)progress status:(NSString*)status; 71 | - (void)showImage:(UIImage*)image status:(NSString*)status duration:(NSTimeInterval)duration; 72 | - (void)showStatus:(NSString*)status; 73 | 74 | - (void)dismiss; 75 | - (void)dismissWithDelay:(NSTimeInterval)delay; 76 | 77 | - (UIView*)indefiniteAnimatedView; 78 | - (SVProgressAnimatedView*)ringView; 79 | - (SVProgressAnimatedView*)backgroundRingView; 80 | 81 | - (void)cancelRingLayerAnimation; 82 | - (void)cancelIndefiniteAnimatedViewAnimation; 83 | 84 | - (UIColor*)foregroundColorForStyle; 85 | - (UIColor*)backgroundColorForStyle; 86 | - (UIImage*)image:(UIImage*)image withTintColor:(UIColor*)color; 87 | 88 | @end 89 | 90 | 91 | @implementation SVProgressHUD { 92 | BOOL _isInitializing; 93 | } 94 | 95 | + (SVProgressHUD*)sharedView { 96 | static dispatch_once_t once; 97 | 98 | static SVProgressHUD *sharedView; 99 | #if !defined(SV_APP_EXTENSIONS) 100 | dispatch_once(&once, ^{ sharedView = [[self alloc] initWithFrame:[[[UIApplication sharedApplication] delegate] window].bounds]; }); 101 | #else 102 | dispatch_once(&once, ^{ sharedView = [[self alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; }); 103 | #endif 104 | return sharedView; 105 | } 106 | 107 | 108 | #pragma mark - Setters 109 | 110 | + (void)setStatus:(NSString*)status { 111 | [[self sharedView] setStatus:status]; 112 | } 113 | 114 | + (void)setDefaultStyle:(SVProgressHUDStyle)style { 115 | [self sharedView].defaultStyle = style; 116 | } 117 | 118 | + (void)setDefaultMaskType:(SVProgressHUDMaskType)maskType { 119 | [self sharedView].defaultMaskType = maskType; 120 | } 121 | 122 | + (void)setDefaultAnimationType:(SVProgressHUDAnimationType)type { 123 | [self sharedView].defaultAnimationType = type; 124 | } 125 | 126 | + (void)setMinimumSize:(CGSize)minimumSize { 127 | [self sharedView].minimumSize = minimumSize; 128 | } 129 | 130 | + (void)setRingThickness:(CGFloat)ringThickness { 131 | [self sharedView].ringThickness = ringThickness; 132 | } 133 | 134 | + (void)setRingRadius:(CGFloat)radius { 135 | [self sharedView].ringRadius = radius; 136 | } 137 | 138 | + (void)setRingNoTextRadius:(CGFloat)radius { 139 | [self sharedView].ringNoTextRadius = radius; 140 | } 141 | 142 | + (void)setCornerRadius:(CGFloat)cornerRadius { 143 | [self sharedView].cornerRadius = cornerRadius; 144 | } 145 | 146 | + (void)setFont:(UIFont*)font { 147 | [self sharedView].font = font; 148 | } 149 | 150 | + (void)setForegroundColor:(UIColor*)color { 151 | [self sharedView].foregroundColor = color; 152 | } 153 | 154 | + (void)setBackgroundColor:(UIColor*)color { 155 | [self sharedView].backgroundColor = color; 156 | } 157 | 158 | + (void)setBackgroundLayerColor:(UIColor*)color { 159 | [self sharedView].backgroundLayerColor = color; 160 | } 161 | 162 | + (void)setInfoImage:(UIImage*)image { 163 | [self sharedView].infoImage = image; 164 | } 165 | 166 | + (void)setSuccessImage:(UIImage*)image { 167 | [self sharedView].successImage = image; 168 | } 169 | 170 | + (void)setErrorImage:(UIImage*)image { 171 | [self sharedView].errorImage = image; 172 | } 173 | 174 | + (void)setViewForExtension:(UIView*)view { 175 | [self sharedView].viewForExtension = view; 176 | } 177 | 178 | + (void)setMinimumDismissTimeInterval:(NSTimeInterval)interval { 179 | [self sharedView].minimumDismissTimeInterval = interval; 180 | } 181 | 182 | + (void)setFadeInAnimationDuration:(NSTimeInterval)duration { 183 | [self sharedView].fadeInAnimationDuration = duration; 184 | } 185 | 186 | + (void)setFadeOutAnimationDuration:(NSTimeInterval)duration { 187 | [self sharedView].fadeOutAnimationDuration = duration; 188 | } 189 | 190 | 191 | #pragma mark - Show Methods 192 | 193 | + (void)show { 194 | [self showWithStatus:nil]; 195 | } 196 | 197 | + (void)showWithMaskType:(SVProgressHUDMaskType)maskType { 198 | SVProgressHUDMaskType existingMaskType = [self sharedView].defaultMaskType; 199 | [self setDefaultMaskType:maskType]; 200 | [self show]; 201 | [self setDefaultMaskType:existingMaskType]; 202 | } 203 | 204 | + (void)showWithStatus:(NSString*)status { 205 | [self sharedView]; 206 | [self showProgress:SVProgressHUDUndefinedProgress status:status]; 207 | } 208 | 209 | + (void)showWithStatus:(NSString*)status maskType:(SVProgressHUDMaskType)maskType { 210 | SVProgressHUDMaskType existingMaskType = [self sharedView].defaultMaskType; 211 | [self setDefaultMaskType:maskType]; 212 | [self showWithStatus:status]; 213 | [self setDefaultMaskType:existingMaskType]; 214 | } 215 | 216 | + (void)showProgress:(float)progress { 217 | [self showProgress:progress status:nil]; 218 | } 219 | 220 | + (void)showProgress:(float)progress maskType:(SVProgressHUDMaskType)maskType { 221 | SVProgressHUDMaskType existingMaskType = [self sharedView].defaultMaskType; 222 | [self setDefaultMaskType:maskType]; 223 | [self showProgress:progress]; 224 | [self setDefaultMaskType:existingMaskType]; 225 | } 226 | 227 | + (void)showProgress:(float)progress status:(NSString*)status { 228 | [[self sharedView] showProgress:progress status:status]; 229 | } 230 | 231 | + (void)showProgress:(float)progress status:(NSString*)status maskType:(SVProgressHUDMaskType)maskType { 232 | SVProgressHUDMaskType existingMaskType = [self sharedView].defaultMaskType; 233 | [self setDefaultMaskType:maskType]; 234 | [self showProgress:progress status:status]; 235 | [self setDefaultMaskType:existingMaskType]; 236 | } 237 | 238 | 239 | #pragma mark - Show, then automatically dismiss methods 240 | 241 | + (void)showInfoWithStatus:(NSString*)status { 242 | [self showImage:[self sharedView].infoImage status:status]; 243 | } 244 | 245 | + (void)showInfoWithStatus:(NSString*)status maskType:(SVProgressHUDMaskType)maskType { 246 | SVProgressHUDMaskType existingMaskType = [self sharedView].defaultMaskType; 247 | [self setDefaultMaskType:maskType]; 248 | [self showInfoWithStatus:status]; 249 | [self setDefaultMaskType:existingMaskType]; 250 | } 251 | 252 | + (void)showSuccessWithStatus:(NSString*)status { 253 | [self showImage:[self sharedView].successImage status:status]; 254 | } 255 | 256 | + (void)showSuccessWithStatus:(NSString*)status maskType:(SVProgressHUDMaskType)maskType { 257 | SVProgressHUDMaskType existingMaskType = [self sharedView].defaultMaskType; 258 | [self setDefaultMaskType:maskType]; 259 | [self showSuccessWithStatus:status]; 260 | [self setDefaultMaskType:existingMaskType]; 261 | } 262 | 263 | + (void)showErrorWithStatus:(NSString*)status { 264 | [self showImage:[self sharedView].errorImage status:status]; 265 | } 266 | 267 | + (void)showErrorWithStatus:(NSString*)status maskType:(SVProgressHUDMaskType)maskType { 268 | SVProgressHUDMaskType existingMaskType = [self sharedView].defaultMaskType; 269 | [self setDefaultMaskType:maskType]; 270 | [self showErrorWithStatus:status]; 271 | [self setDefaultMaskType:existingMaskType]; 272 | } 273 | 274 | + (void)showImage:(UIImage*)image status:(NSString*)status { 275 | NSTimeInterval displayInterval = [self displayDurationForString:status]; 276 | [[self sharedView] showImage:image status:status duration:displayInterval]; 277 | } 278 | 279 | + (void)showImage:(UIImage*)image status:(NSString*)status maskType:(SVProgressHUDMaskType)maskType { 280 | SVProgressHUDMaskType existingMaskType = [self sharedView].defaultMaskType; 281 | [self setDefaultMaskType:maskType]; 282 | [self showImage:image status:status]; 283 | [self setDefaultMaskType:existingMaskType]; 284 | } 285 | 286 | 287 | #pragma mark - Dismiss Methods 288 | 289 | + (void)popActivity { 290 | if([self sharedView].activityCount > 0) { 291 | [self sharedView].activityCount--; 292 | } 293 | if([self sharedView].activityCount == 0) { 294 | [[self sharedView] dismiss]; 295 | } 296 | } 297 | 298 | + (void)dismiss { 299 | [self dismissWithDelay:0.0]; 300 | } 301 | 302 | + (void)dismissWithDelay:(NSTimeInterval)delay { 303 | [[self sharedView] dismissWithDelay:delay]; 304 | } 305 | 306 | 307 | #pragma mark - Offset 308 | 309 | + (void)setOffsetFromCenter:(UIOffset)offset { 310 | [self sharedView].offsetFromCenter = offset; 311 | } 312 | 313 | + (void)resetOffsetFromCenter { 314 | [self setOffsetFromCenter:UIOffsetZero]; 315 | } 316 | 317 | 318 | #pragma mark - Instance Methods 319 | 320 | - (instancetype)initWithFrame:(CGRect)frame { 321 | if((self = [super initWithFrame:frame])) { 322 | _isInitializing = YES; 323 | 324 | self.userInteractionEnabled = NO; 325 | _backgroundColor = [UIColor clearColor]; 326 | _foregroundColor = [UIColor blackColor]; 327 | _backgroundLayerColor = [UIColor colorWithWhite:0 alpha:0.4]; 328 | 329 | self.alpha = 0.0f; 330 | self.activityCount = 0; 331 | 332 | // Set default values 333 | _defaultMaskType = SVProgressHUDMaskTypeNone; 334 | _defaultStyle = SVProgressHUDStyleLight; 335 | _defaultAnimationType = SVProgressHUDAnimationTypeFlat; 336 | 337 | if ([UIFont respondsToSelector:@selector(preferredFontForTextStyle:)]) { 338 | _font = [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline]; 339 | } else { 340 | _font = [UIFont systemFontOfSize:14.0f]; 341 | } 342 | 343 | NSBundle *bundle = [NSBundle bundleForClass:[SVProgressHUD class]]; 344 | NSURL *url = [bundle URLForResource:@"SVProgressHUD" withExtension:@"bundle"]; 345 | NSBundle *imageBundle = [NSBundle bundleWithURL:url]; 346 | 347 | UIImage* infoImage = [UIImage imageWithContentsOfFile:[imageBundle pathForResource:@"info" ofType:@"png"]]; 348 | UIImage* successImage = [UIImage imageWithContentsOfFile:[imageBundle pathForResource:@"success" ofType:@"png"]]; 349 | UIImage* errorImage = [UIImage imageWithContentsOfFile:[imageBundle pathForResource:@"error" ofType:@"png"]]; 350 | 351 | if ([[UIImage class] instancesRespondToSelector:@selector(imageWithRenderingMode:)]) { 352 | _infoImage = [infoImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; 353 | _successImage = [successImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; 354 | _errorImage = [errorImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; 355 | } else { 356 | _infoImage = infoImage; 357 | _successImage = successImage; 358 | _errorImage = errorImage; 359 | } 360 | 361 | _ringThickness = 2.0f; 362 | _ringRadius = 18.0f; 363 | _ringNoTextRadius = 24.0f; 364 | 365 | _cornerRadius = 14.0f; 366 | 367 | _minimumDismissTimeInterval = 5.0; 368 | 369 | _fadeInAnimationDuration = SVProgressHUDDefaultAnimationDuration; 370 | _fadeOutAnimationDuration = SVProgressHUDDefaultAnimationDuration; 371 | 372 | // Accessibility support 373 | self.accessibilityIdentifier = @"SVProgressHUD"; 374 | self.accessibilityLabel = @"SVProgressHUD"; 375 | self.isAccessibilityElement = YES; 376 | 377 | _isInitializing = NO; 378 | } 379 | return self; 380 | } 381 | 382 | - (void)updateHUDFrame { 383 | // For the beginning use default values, these 384 | // might get update if string is too large etc. 385 | CGFloat hudWidth = 100.0f; 386 | CGFloat hudHeight = 100.0f; 387 | CGFloat stringHeightBuffer = 20.0f; 388 | CGFloat stringAndContentHeightBuffer = 80.0f; 389 | CGRect labelRect = CGRectZero; 390 | 391 | // Check if an image or progress ring is displayed 392 | BOOL imageUsed = (self.imageView.image) && !(self.imageView.hidden); 393 | BOOL progressUsed = self.imageView.hidden; 394 | 395 | // Calculate size of string and update HUD size 396 | NSString *string = self.statusLabel.text; 397 | if(string) { 398 | CGSize constraintSize = CGSizeMake(200.0f, 300.0f); 399 | CGRect stringRect; 400 | if([string respondsToSelector:@selector(boundingRectWithSize:options:attributes:context:)]) { 401 | stringRect = [string boundingRectWithSize:constraintSize 402 | options:(NSStringDrawingOptions)(NSStringDrawingUsesFontLeading|NSStringDrawingTruncatesLastVisibleLine|NSStringDrawingUsesLineFragmentOrigin) 403 | attributes:@{NSFontAttributeName: self.statusLabel.font} 404 | context:NULL]; 405 | } else { 406 | CGSize stringSize; 407 | if([string respondsToSelector:@selector(sizeWithAttributes:)]) { 408 | stringSize = [string sizeWithAttributes:@{NSFontAttributeName:[UIFont fontWithName:self.statusLabel.font.fontName size:self.statusLabel.font.pointSize]}]; 409 | } else { 410 | #if TARGET_OS_IOS 411 | #pragma clang diagnostic push 412 | #pragma clang diagnostic ignored "-Wdeprecated" 413 | stringSize = [string sizeWithFont:self.statusLabel.font constrainedToSize:CGSizeMake(200.0f, 300.0f)]; 414 | #pragma clang diagnostic pop 415 | #endif 416 | } 417 | stringRect = CGRectMake(0.0f, 0.0f, stringSize.width, stringSize.height); 418 | } 419 | 420 | CGFloat stringWidth = stringRect.size.width; 421 | CGFloat stringHeight = ceilf(CGRectGetHeight(stringRect)); 422 | 423 | if(imageUsed || progressUsed) { 424 | hudHeight = stringAndContentHeightBuffer + stringHeight; 425 | } else { 426 | hudHeight = stringHeightBuffer + stringHeight; 427 | } 428 | if(stringWidth > hudWidth) { 429 | hudWidth = ceilf(stringWidth/2)*2; 430 | } 431 | CGFloat labelRectY = (imageUsed || progressUsed) ? 68.0f : 9.0f; 432 | if(hudHeight > 100.0f) { 433 | labelRect = CGRectMake(12.0f, labelRectY, hudWidth, stringHeight); 434 | hudWidth += 24.0f; 435 | } else { 436 | hudWidth += 24.0f; 437 | labelRect = CGRectMake(0.0f, labelRectY, hudWidth, stringHeight); 438 | } 439 | } 440 | 441 | // Update values on subviews 442 | self.hudView.bounds = CGRectMake(0.0f, 0.0f, MAX(self.minimumSize.width, hudWidth), MAX(self.minimumSize.height, hudHeight)); 443 | labelRect.size.width += MAX(0, self.minimumSize.width - hudWidth); 444 | [self updateBlurBounds]; 445 | 446 | if(string) { 447 | self.imageView.center = CGPointMake(CGRectGetWidth(self.hudView.bounds)/2, 36.0f); 448 | } else { 449 | self.imageView.center = CGPointMake(CGRectGetWidth(self.hudView.bounds)/2, CGRectGetHeight(self.hudView.bounds)/2); 450 | } 451 | 452 | self.statusLabel.hidden = NO; 453 | self.statusLabel.frame = labelRect; 454 | 455 | // Animate value update 456 | [CATransaction begin]; 457 | [CATransaction setDisableActions:YES]; 458 | 459 | if(string) { 460 | if(self.defaultAnimationType == SVProgressHUDAnimationTypeFlat) { 461 | SVIndefiniteAnimatedView *indefiniteAnimationView = (SVIndefiniteAnimatedView*)self.indefiniteAnimatedView; 462 | indefiniteAnimationView.radius = self.ringRadius; 463 | [indefiniteAnimationView sizeToFit]; 464 | } 465 | 466 | CGPoint center = CGPointMake((CGRectGetWidth(self.hudView.bounds)/2), 36.0f); 467 | self.indefiniteAnimatedView.center = center; 468 | 469 | if(self.progress != SVProgressHUDUndefinedProgress) { 470 | self.backgroundRingView.center = self.ringView.center = CGPointMake((CGRectGetWidth(self.hudView.bounds)/2), 36.0f); 471 | } 472 | } else { 473 | if(self.defaultAnimationType == SVProgressHUDAnimationTypeFlat) { 474 | SVIndefiniteAnimatedView *indefiniteAnimationView = (SVIndefiniteAnimatedView*)self.indefiniteAnimatedView; 475 | indefiniteAnimationView.radius = self.ringNoTextRadius; 476 | [indefiniteAnimationView sizeToFit]; 477 | } 478 | 479 | CGPoint center = CGPointMake((CGRectGetWidth(self.hudView.bounds)/2), CGRectGetHeight(self.hudView.bounds)/2); 480 | self.indefiniteAnimatedView.center = center; 481 | 482 | if(self.progress != SVProgressHUDUndefinedProgress) { 483 | self.backgroundRingView.center = self.ringView.center = CGPointMake((CGRectGetWidth(self.hudView.bounds)/2), CGRectGetHeight(self.hudView.bounds)/2); 484 | } 485 | } 486 | 487 | [CATransaction commit]; 488 | } 489 | 490 | - (void)updateMask { 491 | if(self.backgroundLayer) { 492 | [self.backgroundLayer removeFromSuperlayer]; 493 | self.backgroundLayer = nil; 494 | } 495 | switch (self.defaultMaskType) { 496 | case SVProgressHUDMaskTypeCustom: 497 | case SVProgressHUDMaskTypeBlack:{ 498 | 499 | self.backgroundLayer = [CALayer layer]; 500 | self.backgroundLayer.frame = self.bounds; 501 | self.backgroundLayer.backgroundColor = self.defaultMaskType == SVProgressHUDMaskTypeCustom ? self.backgroundLayerColor.CGColor : [UIColor colorWithWhite:0 alpha:0.4].CGColor; 502 | [self.backgroundLayer setNeedsDisplay]; 503 | 504 | [self.layer insertSublayer:self.backgroundLayer atIndex:0]; 505 | break; 506 | } 507 | 508 | case SVProgressHUDMaskTypeGradient:{ 509 | SVRadialGradientLayer *layer = [SVRadialGradientLayer layer]; 510 | self.backgroundLayer = layer; 511 | self.backgroundLayer.frame = self.bounds; 512 | CGPoint gradientCenter = self.center; 513 | gradientCenter.y = (self.bounds.size.height - self.visibleKeyboardHeight)/2; 514 | layer.gradientCenter = gradientCenter; 515 | [self.backgroundLayer setNeedsDisplay]; 516 | 517 | [self.layer insertSublayer:self.backgroundLayer atIndex:0]; 518 | break; 519 | } 520 | default: 521 | break; 522 | } 523 | } 524 | 525 | - (void)updateBlurBounds { 526 | #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 527 | if(NSClassFromString(@"UIBlurEffect") && self.defaultStyle != SVProgressHUDStyleCustom) { 528 | // Remove background color, else the effect would not work 529 | self.hudView.backgroundColor = [UIColor clearColor]; 530 | 531 | // Remove any old instances of UIVisualEffectViews 532 | for (UIView *subview in self.hudView.subviews) { 533 | if([subview isKindOfClass:[UIVisualEffectView class]]) { 534 | [subview removeFromSuperview]; 535 | } 536 | } 537 | 538 | if(self.backgroundColor != [UIColor clearColor]) { 539 | // Create blur effect 540 | UIBlurEffectStyle blurEffectStyle = self.defaultStyle == SVProgressHUDStyleDark ? UIBlurEffectStyleDark : UIBlurEffectStyleLight; 541 | UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:blurEffectStyle]; 542 | UIVisualEffectView *blurEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect]; 543 | blurEffectView.autoresizingMask = self.hudView.autoresizingMask; 544 | blurEffectView.frame = self.hudView.bounds; 545 | 546 | // Add vibrancy to the blur effect to make it more vivid 547 | UIVibrancyEffect *vibrancyEffect = [UIVibrancyEffect effectForBlurEffect:blurEffect]; 548 | UIVisualEffectView *vibrancyEffectView = [[UIVisualEffectView alloc] initWithEffect:vibrancyEffect]; 549 | vibrancyEffectView.autoresizingMask = blurEffectView.autoresizingMask; 550 | vibrancyEffectView.bounds = blurEffectView.bounds; 551 | [blurEffectView.contentView addSubview:vibrancyEffectView]; 552 | 553 | [self.hudView insertSubview:blurEffectView atIndex:0]; 554 | } 555 | } 556 | #endif 557 | } 558 | 559 | #if TARGET_OS_IOS 560 | - (void)updateMotionEffectForOrientation:(UIInterfaceOrientation)orientation { 561 | UIInterpolatingMotionEffectType xMotionEffectType = UIInterfaceOrientationIsPortrait(orientation) ? UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis : UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis; 562 | UIInterpolatingMotionEffectType yMotionEffectType = UIInterfaceOrientationIsPortrait(orientation) ? UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis : UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis; 563 | [self updateMotionEffectForXMotionEffectType:xMotionEffectType yMotionEffectType:yMotionEffectType]; 564 | } 565 | #endif 566 | 567 | - (void)updateMotionEffectForXMotionEffectType:(UIInterpolatingMotionEffectType)xMotionEffectType yMotionEffectType:(UIInterpolatingMotionEffectType)yMotionEffectType { 568 | if([self.hudView respondsToSelector:@selector(addMotionEffect:)]) { 569 | UIInterpolatingMotionEffect *effectX = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.x" type:xMotionEffectType]; 570 | effectX.minimumRelativeValue = @(-SVProgressHUDParallaxDepthPoints); 571 | effectX.maximumRelativeValue = @(SVProgressHUDParallaxDepthPoints); 572 | 573 | UIInterpolatingMotionEffect *effectY = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.y" type:yMotionEffectType]; 574 | effectY.minimumRelativeValue = @(-SVProgressHUDParallaxDepthPoints); 575 | effectY.maximumRelativeValue = @(SVProgressHUDParallaxDepthPoints); 576 | 577 | UIMotionEffectGroup *effectGroup = [[UIMotionEffectGroup alloc] init]; 578 | effectGroup.motionEffects = @[effectX, effectY]; 579 | 580 | // Clear old motion effect, then add new motion effects 581 | self.hudView.motionEffects = @[]; 582 | [self.hudView addMotionEffect:effectGroup]; 583 | } 584 | } 585 | 586 | - (void)updateViewHierachy { 587 | // Add the overlay (e.g. black, gradient) to the application window if necessary 588 | if(!self.overlayView.superview) { 589 | #if !defined(SV_APP_EXTENSIONS) 590 | // Default case: iterate over UIApplication windows 591 | NSEnumerator *frontToBackWindows = [UIApplication.sharedApplication.windows reverseObjectEnumerator]; 592 | for (UIWindow *window in frontToBackWindows) { 593 | BOOL windowOnMainScreen = window.screen == UIScreen.mainScreen; 594 | BOOL windowIsVisible = !window.hidden && window.alpha > 0; 595 | BOOL windowLevelNormal = window.windowLevel == UIWindowLevelNormal; 596 | 597 | if(windowOnMainScreen && windowIsVisible && windowLevelNormal) { 598 | [window addSubview:self.overlayView]; 599 | break; 600 | } 601 | } 602 | #else 603 | // If SVProgressHUD ist used inside an app extension add it to the given view 604 | if(self.viewForExtension) { 605 | [self.viewForExtension addSubview:self.overlayView]; 606 | } 607 | #endif 608 | } else { 609 | // The HUD is already on screen, but maybot not in front. Therefore 610 | // ensure that overlay will be on top of rootViewController (which may 611 | // be changed during runtime). 612 | [self.overlayView.superview bringSubviewToFront:self.overlayView]; 613 | } 614 | 615 | 616 | // Add self to the overlay view 617 | if(!self.superview){ 618 | [self.overlayView addSubview:self]; 619 | } 620 | if(!self.hudView.superview) { 621 | [self addSubview:self.hudView]; 622 | } 623 | } 624 | 625 | - (void)setStatus:(NSString*)status { 626 | self.statusLabel.text = status; 627 | [self updateHUDFrame]; 628 | } 629 | 630 | - (void)setFadeOutTimer:(NSTimer*)timer { 631 | if(_fadeOutTimer) { 632 | [_fadeOutTimer invalidate], _fadeOutTimer = nil; 633 | } 634 | if(timer) { 635 | _fadeOutTimer = timer; 636 | } 637 | } 638 | 639 | 640 | #pragma mark - Notifications and their handling 641 | 642 | - (void)registerNotifications { 643 | #if TARGET_OS_IOS 644 | [[NSNotificationCenter defaultCenter] addObserver:self 645 | selector:@selector(positionHUD:) 646 | name:UIApplicationDidChangeStatusBarOrientationNotification 647 | object:nil]; 648 | 649 | [[NSNotificationCenter defaultCenter] addObserver:self 650 | selector:@selector(positionHUD:) 651 | name:UIKeyboardWillHideNotification 652 | object:nil]; 653 | 654 | [[NSNotificationCenter defaultCenter] addObserver:self 655 | selector:@selector(positionHUD:) 656 | name:UIKeyboardDidHideNotification 657 | object:nil]; 658 | 659 | [[NSNotificationCenter defaultCenter] addObserver:self 660 | selector:@selector(positionHUD:) 661 | name:UIKeyboardWillShowNotification 662 | object:nil]; 663 | 664 | [[NSNotificationCenter defaultCenter] addObserver:self 665 | selector:@selector(positionHUD:) 666 | name:UIKeyboardDidShowNotification 667 | object:nil]; 668 | #endif 669 | [[NSNotificationCenter defaultCenter] addObserver:self 670 | selector:@selector(positionHUD:) 671 | name:UIApplicationDidBecomeActiveNotification 672 | object:nil]; 673 | } 674 | 675 | - (NSDictionary*)notificationUserInfo{ 676 | return (self.statusLabel.text ? @{SVProgressHUDStatusUserInfoKey : self.statusLabel.text} : nil); 677 | } 678 | 679 | - (void)positionHUD:(NSNotification*)notification { 680 | CGFloat keyboardHeight = 0.0f; 681 | double animationDuration = 0.0; 682 | 683 | #if !defined(SV_APP_EXTENSIONS) && TARGET_OS_IOS 684 | self.frame = [[[UIApplication sharedApplication] delegate] window].bounds; 685 | UIInterfaceOrientation orientation = UIApplication.sharedApplication.statusBarOrientation; 686 | #elif !defined(SV_APP_EXTENSIONS) 687 | self.frame = [UIApplication sharedApplication].keyWindow.bounds; 688 | #else 689 | if (self.viewForExtension) { 690 | self.frame = self.viewForExtension.frame; 691 | } else { 692 | self.frame = UIScreen.mainScreen.bounds; 693 | } 694 | UIInterfaceOrientation orientation = CGRectGetWidth(self.frame) > CGRectGetHeight(self.frame) ? UIInterfaceOrientationLandscapeLeft : UIInterfaceOrientationPortrait; 695 | #endif 696 | 697 | // no transforms applied to window in iOS 8, but only if compiled with iOS 8 sdk as base sdk, otherwise system supports old rotation logic. 698 | BOOL ignoreOrientation = NO; 699 | #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 700 | if([[NSProcessInfo processInfo] respondsToSelector:@selector(operatingSystemVersion)]) { 701 | ignoreOrientation = YES; 702 | } 703 | #endif 704 | 705 | #if TARGET_OS_IOS 706 | // Get keyboardHeight in regards to current state 707 | if(notification) { 708 | NSDictionary* keyboardInfo = [notification userInfo]; 709 | CGRect keyboardFrame = [keyboardInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue]; 710 | animationDuration = [keyboardInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]; 711 | 712 | if(notification.name == UIKeyboardWillShowNotification || notification.name == UIKeyboardDidShowNotification) { 713 | keyboardHeight = CGRectGetWidth(keyboardFrame); 714 | 715 | if(ignoreOrientation || UIInterfaceOrientationIsPortrait(orientation)) { 716 | keyboardHeight = CGRectGetHeight(keyboardFrame); 717 | } 718 | } 719 | } else { 720 | keyboardHeight = self.visibleKeyboardHeight; 721 | } 722 | #endif 723 | 724 | // Get the currently active frame of the display (depends on orientation) 725 | CGRect orientationFrame = self.bounds; 726 | 727 | #if !defined(SV_APP_EXTENSIONS) && TARGET_OS_IOS 728 | CGRect statusBarFrame = UIApplication.sharedApplication.statusBarFrame; 729 | #else 730 | CGRect statusBarFrame = CGRectZero; 731 | #endif 732 | 733 | #if TARGET_OS_IOS 734 | if(!ignoreOrientation && UIInterfaceOrientationIsLandscape(orientation)) { 735 | float temp = CGRectGetWidth(orientationFrame); 736 | orientationFrame.size.width = CGRectGetHeight(orientationFrame); 737 | orientationFrame.size.height = temp; 738 | 739 | temp = CGRectGetWidth(statusBarFrame); 740 | statusBarFrame.size.width = CGRectGetHeight(statusBarFrame); 741 | statusBarFrame.size.height = temp; 742 | } 743 | 744 | // Update the motion effects in regards to orientation 745 | [self updateMotionEffectForOrientation:orientation]; 746 | #else 747 | [self updateMotionEffectForXMotionEffectType:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis yMotionEffectType:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis]; 748 | #endif 749 | 750 | // Calculate available height for display 751 | CGFloat activeHeight = CGRectGetHeight(orientationFrame); 752 | if(keyboardHeight > 0) { 753 | activeHeight += CGRectGetHeight(statusBarFrame)*2; 754 | } 755 | activeHeight -= keyboardHeight; 756 | 757 | CGFloat posX = CGRectGetWidth(orientationFrame)/2.0f; 758 | CGFloat posY = floorf(activeHeight*0.45f); 759 | 760 | CGFloat rotateAngle = 0.0; 761 | CGPoint newCenter = CGPointMake(posX, posY); 762 | 763 | // Update posX and posY in regards to orientation 764 | #if TARGET_OS_IOS 765 | if(!ignoreOrientation) { 766 | switch (orientation) { 767 | case UIInterfaceOrientationPortraitUpsideDown: 768 | rotateAngle = (CGFloat) M_PI; 769 | newCenter = CGPointMake(posX, CGRectGetHeight(orientationFrame)-posY); 770 | break; 771 | case UIInterfaceOrientationLandscapeLeft: 772 | rotateAngle = (CGFloat) (-M_PI/2.0f); 773 | newCenter = CGPointMake(posY, posX); 774 | break; 775 | case UIInterfaceOrientationLandscapeRight: 776 | rotateAngle = (CGFloat) (M_PI/2.0f); 777 | newCenter = CGPointMake(CGRectGetHeight(orientationFrame)-posY, posX); 778 | break; 779 | default: // Same as UIInterfaceOrientationPortrait 780 | rotateAngle = 0.0f; 781 | newCenter = CGPointMake(posX, posY); 782 | break; 783 | } 784 | } 785 | #endif 786 | 787 | if(notification) { 788 | // Animate update if notification was present 789 | __weak SVProgressHUD *weakSelf = self; 790 | [UIView animateWithDuration:animationDuration 791 | delay:0 792 | options:UIViewAnimationOptionAllowUserInteraction 793 | animations:^{ 794 | __strong SVProgressHUD *strongSelf = weakSelf; 795 | if(strongSelf) { 796 | [strongSelf moveToPoint:newCenter rotateAngle:rotateAngle]; 797 | [strongSelf.hudView setNeedsDisplay]; 798 | } 799 | } completion:NULL]; 800 | } else { 801 | [self moveToPoint:newCenter rotateAngle:rotateAngle]; 802 | [self.hudView setNeedsDisplay]; 803 | } 804 | 805 | [self updateMask]; 806 | } 807 | 808 | - (void)moveToPoint:(CGPoint)newCenter rotateAngle:(CGFloat)angle { 809 | self.hudView.transform = CGAffineTransformMakeRotation(angle); 810 | self.hudView.center = CGPointMake(newCenter.x + self.offsetFromCenter.horizontal, newCenter.y + self.offsetFromCenter.vertical); 811 | } 812 | 813 | 814 | #pragma mark - Event handling 815 | 816 | - (void)overlayViewDidReceiveTouchEvent:(id)sender forEvent:(UIEvent*)event { 817 | [[NSNotificationCenter defaultCenter] postNotificationName:SVProgressHUDDidReceiveTouchEventNotification 818 | object:self 819 | userInfo:[self notificationUserInfo]]; 820 | 821 | UITouch *touch = event.allTouches.anyObject; 822 | CGPoint touchLocation = [touch locationInView:self]; 823 | 824 | if(CGRectContainsPoint(self.hudView.frame, touchLocation)) { 825 | [[NSNotificationCenter defaultCenter] postNotificationName:SVProgressHUDDidTouchDownInsideNotification 826 | object:self 827 | userInfo:[self notificationUserInfo]]; 828 | } 829 | } 830 | 831 | 832 | #pragma mark - Master show/dismiss methods 833 | 834 | - (void)showProgress:(float)progress status:(NSString*)status { 835 | __weak SVProgressHUD *weakSelf = self; 836 | [[NSOperationQueue mainQueue] addOperationWithBlock:^{ 837 | __strong SVProgressHUD *strongSelf = weakSelf; 838 | if(strongSelf){ 839 | // Update / Check view hierachy to ensure the HUD is visible 840 | [strongSelf updateViewHierachy]; 841 | 842 | // Reset imageView and fadeout timer if an image is currently displayed 843 | strongSelf.imageView.hidden = YES; 844 | strongSelf.imageView.image = nil; 845 | 846 | if(strongSelf.fadeOutTimer) { 847 | strongSelf.activityCount = 0; 848 | } 849 | strongSelf.fadeOutTimer = nil; 850 | 851 | // Update text and set progress to the given value 852 | strongSelf.statusLabel.text = status; 853 | strongSelf.progress = progress; 854 | 855 | // Choose the "right" indicator depending on the progress 856 | if(progress >= 0) { 857 | // Cancel the indefiniteAnimatedView, then show the ringLayer 858 | [strongSelf cancelIndefiniteAnimatedViewAnimation]; 859 | 860 | // Add ring to HUD and set progress 861 | [strongSelf.hudView addSubview:strongSelf.ringView]; 862 | [strongSelf.hudView addSubview:strongSelf.backgroundRingView]; 863 | strongSelf.ringView.strokeEnd = progress; 864 | 865 | // Updat the activity count 866 | if(progress == 0) { 867 | strongSelf.activityCount++; 868 | } 869 | } else { 870 | // Cancel the ringLayer animation, then show the indefiniteAnimatedView 871 | [strongSelf cancelRingLayerAnimation]; 872 | 873 | // Add indefiniteAnimatedView to HUD 874 | [strongSelf.hudView addSubview:strongSelf.indefiniteAnimatedView]; 875 | if([strongSelf.indefiniteAnimatedView respondsToSelector:@selector(startAnimating)]) { 876 | [(id)strongSelf.indefiniteAnimatedView startAnimating]; 877 | } 878 | 879 | // Update the activity count 880 | strongSelf.activityCount++; 881 | } 882 | 883 | // Show 884 | [strongSelf showStatus:status]; 885 | } 886 | }]; 887 | } 888 | 889 | - (void)showImage:(UIImage*)image status:(NSString*)status duration:(NSTimeInterval)duration { 890 | __weak SVProgressHUD *weakSelf = self; 891 | [[NSOperationQueue mainQueue] addOperationWithBlock:^{ 892 | __strong SVProgressHUD *strongSelf = weakSelf; 893 | if(strongSelf){ 894 | // Update / Check view hierachy to ensure the HUD is visible 895 | [strongSelf updateViewHierachy]; 896 | 897 | // Reset progress and cancel any running animation 898 | strongSelf.progress = SVProgressHUDUndefinedProgress; 899 | [strongSelf cancelRingLayerAnimation]; 900 | [strongSelf cancelIndefiniteAnimatedViewAnimation]; 901 | 902 | // Update imageView 903 | UIColor *tintColor = strongSelf.foregroundColorForStyle; 904 | UIImage *tintedImage = image; 905 | if([strongSelf.imageView respondsToSelector:@selector(setTintColor:)]) { 906 | if (tintedImage.renderingMode != UIImageRenderingModeAlwaysTemplate) { 907 | tintedImage = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; 908 | } 909 | strongSelf.imageView.tintColor = tintColor; 910 | } else { 911 | tintedImage = [strongSelf image:image withTintColor:tintColor]; 912 | } 913 | strongSelf.imageView.image = tintedImage; 914 | strongSelf.imageView.hidden = NO; 915 | 916 | // Update text 917 | strongSelf.statusLabel.text = status; 918 | 919 | // Show 920 | [strongSelf showStatus:status]; 921 | 922 | // An image will dismissed automatically. Therefore we start a timer 923 | // which then will call dismiss after the predefined duration 924 | strongSelf.fadeOutTimer = [NSTimer timerWithTimeInterval:duration target:strongSelf selector:@selector(dismiss) userInfo:nil repeats:NO]; 925 | [[NSRunLoop mainRunLoop] addTimer:strongSelf.fadeOutTimer forMode:NSRunLoopCommonModes]; 926 | } 927 | }]; 928 | } 929 | 930 | - (void)showStatus:(NSString*)status { 931 | // Update the HUDs frame to the new content and position HUD 932 | [self updateHUDFrame]; 933 | [self positionHUD:nil]; 934 | 935 | // Update accesibilty as well as user interaction 936 | if(self.defaultMaskType != SVProgressHUDMaskTypeNone) { 937 | self.overlayView.userInteractionEnabled = YES; 938 | self.accessibilityLabel = status; 939 | self.isAccessibilityElement = YES; 940 | } else { 941 | self.overlayView.userInteractionEnabled = NO; 942 | self.hudView.accessibilityLabel = status; 943 | self.hudView.isAccessibilityElement = YES; 944 | } 945 | 946 | // Show overlay 947 | self.overlayView.backgroundColor = [UIColor clearColor]; 948 | 949 | // Show if not already visible (depending on alpha) 950 | if(self.alpha != 1.0f || self.hudView.alpha != 1.0f) { 951 | // Post notification to inform user 952 | [[NSNotificationCenter defaultCenter] postNotificationName:SVProgressHUDWillAppearNotification 953 | object:self 954 | userInfo:[self notificationUserInfo]]; 955 | 956 | // Zoom HUD a little to make a nice appear / pop up animation 957 | self.hudView.transform = CGAffineTransformScale(self.hudView.transform, 1.3, 1.3); 958 | 959 | // Set initial values to handle iOS 7 (and above) UIToolbar which not answers well to hierarchy opacity change 960 | self.alpha = 0.0f; 961 | self.hudView.alpha = 0.0f; 962 | 963 | // Define blocks 964 | __weak SVProgressHUD *weakSelf = self; 965 | 966 | __block void (^animationsBlock)(void) = ^{ 967 | __strong SVProgressHUD *strongSelf = weakSelf; 968 | if(strongSelf) { 969 | // Shrink HUD to finish pop up animation 970 | strongSelf.hudView.transform = CGAffineTransformScale(strongSelf.hudView.transform, 1/1.3f, 1/1.3f); 971 | strongSelf.alpha = 1.0f; 972 | strongSelf.hudView.alpha = 1.0f; 973 | } 974 | }; 975 | 976 | __block void (^completionBlock)(void) = ^{ 977 | __strong SVProgressHUD *strongSelf = weakSelf; 978 | if(strongSelf) { 979 | /// Register observer <=> we now have to handle orientation changes etc. 980 | [strongSelf registerNotifications]; 981 | 982 | // Post notification to inform user 983 | [[NSNotificationCenter defaultCenter] postNotificationName:SVProgressHUDDidAppearNotification 984 | object:strongSelf 985 | userInfo:[strongSelf notificationUserInfo]]; 986 | } 987 | 988 | // Update accesibilty 989 | UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, nil); 990 | UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, status); 991 | }; 992 | 993 | if (self.fadeInAnimationDuration > 0) { 994 | // Animate appearance 995 | [UIView animateWithDuration:self.fadeInAnimationDuration 996 | delay:0 997 | options:(UIViewAnimationOptions) (UIViewAnimationOptionAllowUserInteraction | UIViewAnimationCurveEaseOut | UIViewAnimationOptionBeginFromCurrentState) 998 | animations:^{ 999 | animationsBlock(); 1000 | } completion:^(BOOL finished) { 1001 | completionBlock(); 1002 | }]; 1003 | } else { 1004 | animationsBlock(); 1005 | completionBlock(); 1006 | } 1007 | 1008 | // Inform iOS to redraw the view hierachy 1009 | [self setNeedsDisplay]; 1010 | } 1011 | } 1012 | 1013 | - (void)dismiss { 1014 | [self dismissWithDelay:0]; 1015 | } 1016 | 1017 | - (void)dismissWithDelay:(NSTimeInterval)delay { 1018 | __weak SVProgressHUD *weakSelf = self; 1019 | [[NSOperationQueue mainQueue] addOperationWithBlock:^{ 1020 | __strong SVProgressHUD *strongSelf = weakSelf; 1021 | if(strongSelf){ 1022 | // Dismiss if visible (depending on alpha) 1023 | if(strongSelf.alpha != 0.0f || strongSelf.hudView.alpha != 0.0f){ 1024 | // Post notification to inform user 1025 | [[NSNotificationCenter defaultCenter] postNotificationName:SVProgressHUDWillDisappearNotification 1026 | object:nil 1027 | userInfo:[strongSelf notificationUserInfo]]; 1028 | 1029 | // Reset activitiy count 1030 | strongSelf.activityCount = 0; 1031 | 1032 | // Define blocks 1033 | __block void (^animationsBlock)(void) = ^{ 1034 | strongSelf.hudView.transform = CGAffineTransformScale(strongSelf.hudView.transform, 0.8f, 0.8f); 1035 | strongSelf.alpha = 0.0f; 1036 | strongSelf.hudView.alpha = 0.0f; 1037 | }; 1038 | 1039 | __block void (^completionBlock)(void) = ^{ 1040 | // Clean up view hierachy (overlays) 1041 | [strongSelf.overlayView removeFromSuperview]; 1042 | [strongSelf.hudView removeFromSuperview]; 1043 | [strongSelf removeFromSuperview]; 1044 | 1045 | // Reset progress and cancel any running animation 1046 | strongSelf.progress = SVProgressHUDUndefinedProgress; 1047 | [strongSelf cancelRingLayerAnimation]; 1048 | [strongSelf cancelIndefiniteAnimatedViewAnimation]; 1049 | 1050 | // Remove observer <=> we do not have to handle orientation changes etc. 1051 | [[NSNotificationCenter defaultCenter] removeObserver:strongSelf]; 1052 | 1053 | // Post notification to inform user 1054 | [[NSNotificationCenter defaultCenter] postNotificationName:SVProgressHUDDidDisappearNotification 1055 | object:strongSelf 1056 | userInfo:[strongSelf notificationUserInfo]]; 1057 | 1058 | // Tell the rootViewController to update the StatusBar appearance 1059 | #if !defined(SV_APP_EXTENSIONS) && TARGET_OS_IOS 1060 | UIViewController *rootController = [[UIApplication sharedApplication] keyWindow].rootViewController; 1061 | if([rootController respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)]) { 1062 | [rootController setNeedsStatusBarAppearanceUpdate]; 1063 | } 1064 | #endif 1065 | // Update accesibilty 1066 | UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, nil); 1067 | }; 1068 | 1069 | if (strongSelf.fadeOutAnimationDuration > 0) { 1070 | // Animate appearance 1071 | [UIView animateWithDuration:strongSelf.fadeOutAnimationDuration 1072 | delay:delay 1073 | options:(UIViewAnimationOptions) (UIViewAnimationOptionAllowUserInteraction | UIViewAnimationCurveEaseIn | UIViewAnimationOptionBeginFromCurrentState) 1074 | animations:^{ 1075 | animationsBlock(); 1076 | } completion:^(BOOL finished) { 1077 | completionBlock(); 1078 | }]; 1079 | } else { 1080 | animationsBlock(); 1081 | completionBlock(); 1082 | } 1083 | 1084 | // Inform iOS to redraw the view hierachy 1085 | [strongSelf setNeedsDisplay]; 1086 | } 1087 | } 1088 | }]; 1089 | } 1090 | 1091 | 1092 | #pragma mark - Ring progress animation 1093 | 1094 | - (UIView*)indefiniteAnimatedView { 1095 | // Get the correct spinner for defaultAnimationType 1096 | if(self.defaultAnimationType == SVProgressHUDAnimationTypeFlat){ 1097 | // Check if spinner exists and is an object of different class 1098 | if(_indefiniteAnimatedView && ![_indefiniteAnimatedView isKindOfClass:[SVIndefiniteAnimatedView class]]){ 1099 | [_indefiniteAnimatedView removeFromSuperview]; 1100 | _indefiniteAnimatedView = nil; 1101 | } 1102 | 1103 | if(!_indefiniteAnimatedView){ 1104 | _indefiniteAnimatedView = [[SVIndefiniteAnimatedView alloc] initWithFrame:CGRectZero]; 1105 | } 1106 | 1107 | // Update styling 1108 | SVIndefiniteAnimatedView *indefiniteAnimatedView = (SVIndefiniteAnimatedView*)_indefiniteAnimatedView; 1109 | indefiniteAnimatedView.strokeColor = self.foregroundColorForStyle; 1110 | indefiniteAnimatedView.strokeThickness = self.ringThickness; 1111 | indefiniteAnimatedView.radius = self.statusLabel.text ? self.ringRadius : self.ringNoTextRadius; 1112 | } else { 1113 | // Check if spinner exists and is an object of different class 1114 | if(_indefiniteAnimatedView && ![_indefiniteAnimatedView isKindOfClass:[UIActivityIndicatorView class]]){ 1115 | [_indefiniteAnimatedView removeFromSuperview]; 1116 | _indefiniteAnimatedView = nil; 1117 | } 1118 | 1119 | if(!_indefiniteAnimatedView){ 1120 | _indefiniteAnimatedView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; 1121 | } 1122 | 1123 | // Update styling 1124 | UIActivityIndicatorView *activityIndicatorView = (UIActivityIndicatorView*)_indefiniteAnimatedView; 1125 | activityIndicatorView.color = self.foregroundColorForStyle; 1126 | } 1127 | [_indefiniteAnimatedView sizeToFit]; 1128 | 1129 | return _indefiniteAnimatedView; 1130 | } 1131 | 1132 | - (SVProgressAnimatedView*)ringView { 1133 | if(!_ringView) { 1134 | _ringView = [[SVProgressAnimatedView alloc] initWithFrame:CGRectZero]; 1135 | } 1136 | 1137 | // Update styling 1138 | _ringView.strokeColor = self.foregroundColorForStyle; 1139 | _ringView.strokeThickness = self.ringThickness; 1140 | _ringView.radius = self.statusLabel.text ? self.ringRadius : self.ringNoTextRadius; 1141 | 1142 | return _ringView; 1143 | } 1144 | 1145 | - (SVProgressAnimatedView*)backgroundRingView { 1146 | if(!_backgroundRingView) { 1147 | _backgroundRingView = [[SVProgressAnimatedView alloc] initWithFrame:CGRectZero]; 1148 | _backgroundRingView.strokeEnd = 1.0f; 1149 | } 1150 | 1151 | // Update styling 1152 | _backgroundRingView.strokeColor = [self.foregroundColorForStyle colorWithAlphaComponent:0.1f]; 1153 | _backgroundRingView.strokeThickness = self.ringThickness; 1154 | _backgroundRingView.radius = self.statusLabel.text ? self.ringRadius : self.ringNoTextRadius; 1155 | 1156 | return _backgroundRingView; 1157 | } 1158 | 1159 | - (void)cancelRingLayerAnimation { 1160 | // Animate value update, stop animation 1161 | [CATransaction begin]; 1162 | [CATransaction setDisableActions:YES]; 1163 | 1164 | [self.hudView.layer removeAllAnimations]; 1165 | self.ringView.strokeEnd = 0.0f; 1166 | 1167 | [CATransaction commit]; 1168 | 1169 | // Remove from view 1170 | [self.ringView removeFromSuperview]; 1171 | [self.backgroundRingView removeFromSuperview]; 1172 | } 1173 | 1174 | - (void)cancelIndefiniteAnimatedViewAnimation { 1175 | // Stop animation 1176 | if([self.indefiniteAnimatedView respondsToSelector:@selector(stopAnimating)]) { 1177 | [(id)self.indefiniteAnimatedView stopAnimating]; 1178 | } 1179 | // Remove from view 1180 | [self.indefiniteAnimatedView removeFromSuperview]; 1181 | } 1182 | 1183 | 1184 | #pragma mark - Utilities 1185 | 1186 | + (BOOL)isVisible { 1187 | return ([self sharedView].alpha > 0); 1188 | } 1189 | 1190 | 1191 | #pragma mark - Getters 1192 | 1193 | + (NSTimeInterval)displayDurationForString:(NSString*)string { 1194 | return MAX((float)string.length * 0.06 + 0.5, [self sharedView].minimumDismissTimeInterval); 1195 | } 1196 | 1197 | - (UIColor*)foregroundColorForStyle { 1198 | if(self.defaultStyle == SVProgressHUDStyleLight) { 1199 | return [UIColor blackColor]; 1200 | } else if(self.defaultStyle == SVProgressHUDStyleDark) { 1201 | return [UIColor whiteColor]; 1202 | } else { 1203 | return self.foregroundColor; 1204 | } 1205 | } 1206 | 1207 | - (UIColor*)backgroundColorForStyle { 1208 | if(self.defaultStyle == SVProgressHUDStyleLight) { 1209 | return [UIColor whiteColor]; 1210 | } else if(self.defaultStyle == SVProgressHUDStyleDark) { 1211 | return [UIColor blackColor]; 1212 | } else { 1213 | return self.backgroundColor; 1214 | } 1215 | } 1216 | 1217 | - (UIImage*)image:(UIImage*)image withTintColor:(UIColor*)color { 1218 | CGRect rect = CGRectMake(0.0f, 0.0f, image.size.width, image.size.height); 1219 | UIGraphicsBeginImageContextWithOptions(rect.size, NO, image.scale); 1220 | CGContextRef c = UIGraphicsGetCurrentContext(); 1221 | [image drawInRect:rect]; 1222 | CGContextSetFillColorWithColor(c, [color CGColor]); 1223 | CGContextSetBlendMode(c, kCGBlendModeSourceAtop); 1224 | CGContextFillRect(c, rect); 1225 | UIImage *tintedImage = UIGraphicsGetImageFromCurrentImageContext(); 1226 | UIGraphicsEndImageContext(); 1227 | 1228 | return tintedImage; 1229 | } 1230 | 1231 | - (BOOL)isClear { // used for iOS 7 and above 1232 | return (self.defaultMaskType == SVProgressHUDMaskTypeClear || self.defaultMaskType == SVProgressHUDMaskTypeNone); 1233 | } 1234 | 1235 | - (UIControl*)overlayView { 1236 | if(!_overlayView) { 1237 | #if !defined(SV_APP_EXTENSIONS) 1238 | CGRect windowBounds = [[[UIApplication sharedApplication] delegate] window].bounds; 1239 | _overlayView = [[UIControl alloc] initWithFrame:windowBounds]; 1240 | #else 1241 | _overlayView = [[UIControl alloc] initWithFrame:[UIScreen mainScreen].bounds]; 1242 | #endif 1243 | _overlayView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 1244 | _overlayView.backgroundColor = [UIColor clearColor]; 1245 | [_overlayView addTarget:self action:@selector(overlayViewDidReceiveTouchEvent:forEvent:) forControlEvents:UIControlEventTouchDown]; 1246 | } 1247 | return _overlayView; 1248 | } 1249 | 1250 | - (UIView*)hudView { 1251 | if(!_hudView) { 1252 | _hudView = [[UIView alloc] initWithFrame:CGRectZero]; 1253 | _hudView.layer.masksToBounds = YES; 1254 | _hudView.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin; 1255 | } 1256 | 1257 | // Update styling 1258 | _hudView.layer.cornerRadius = self.cornerRadius; 1259 | _hudView.backgroundColor = self.backgroundColorForStyle; 1260 | 1261 | return _hudView; 1262 | } 1263 | 1264 | - (UILabel*)statusLabel { 1265 | if(!_statusLabel) { 1266 | _statusLabel = [[UILabel alloc] initWithFrame:CGRectZero]; 1267 | _statusLabel.backgroundColor = [UIColor clearColor]; 1268 | _statusLabel.adjustsFontSizeToFitWidth = YES; 1269 | _statusLabel.textAlignment = NSTextAlignmentCenter; 1270 | _statusLabel.baselineAdjustment = UIBaselineAdjustmentAlignCenters; 1271 | _statusLabel.numberOfLines = 0; 1272 | } 1273 | if(!_statusLabel.superview) { 1274 | [self.hudView addSubview:_statusLabel]; 1275 | } 1276 | 1277 | // Update styling 1278 | _statusLabel.textColor = self.foregroundColorForStyle; 1279 | _statusLabel.font = self.font; 1280 | 1281 | return _statusLabel; 1282 | } 1283 | 1284 | - (UIImageView*)imageView { 1285 | if(!_imageView) { 1286 | _imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 28.0f, 28.0f)]; 1287 | } 1288 | if(!_imageView.superview) { 1289 | [self.hudView addSubview:_imageView]; 1290 | } 1291 | return _imageView; 1292 | } 1293 | 1294 | - (CGFloat)visibleKeyboardHeight { 1295 | #if !defined(SV_APP_EXTENSIONS) 1296 | UIWindow *keyboardWindow = nil; 1297 | for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) { 1298 | if(![[testWindow class] isEqual:[UIWindow class]]) { 1299 | keyboardWindow = testWindow; 1300 | break; 1301 | } 1302 | } 1303 | 1304 | for (__strong UIView *possibleKeyboard in [keyboardWindow subviews]) { 1305 | if([possibleKeyboard isKindOfClass:NSClassFromString(@"UIPeripheralHostView")] || [possibleKeyboard isKindOfClass:NSClassFromString(@"UIKeyboard")]) { 1306 | return CGRectGetHeight(possibleKeyboard.bounds); 1307 | } else if([possibleKeyboard isKindOfClass:NSClassFromString(@"UIInputSetContainerView")]) { 1308 | for (__strong UIView *possibleKeyboardSubview in [possibleKeyboard subviews]) { 1309 | if([possibleKeyboardSubview isKindOfClass:NSClassFromString(@"UIInputSetHostView")]) { 1310 | return CGRectGetHeight(possibleKeyboardSubview.bounds); 1311 | } 1312 | } 1313 | } 1314 | } 1315 | #endif 1316 | return 0; 1317 | } 1318 | 1319 | 1320 | #pragma mark - UIAppearance Setters 1321 | 1322 | - (void)setDefaultStyle:(SVProgressHUDStyle)style { 1323 | if (!_isInitializing) _defaultStyle = style; 1324 | } 1325 | 1326 | - (void)setDefaultMaskType:(SVProgressHUDMaskType)maskType { 1327 | if (!_isInitializing) _defaultMaskType = maskType; 1328 | } 1329 | 1330 | - (void)setDefaultAnimationType:(SVProgressHUDAnimationType)animationType { 1331 | if (!_isInitializing) _defaultAnimationType = animationType; 1332 | } 1333 | 1334 | - (void)setMinimumSize:(CGSize)minimumSize { 1335 | if (!_isInitializing) _minimumSize = minimumSize; 1336 | } 1337 | 1338 | - (void)setRingThickness:(CGFloat)ringThickness { 1339 | if (!_isInitializing) _ringThickness = ringThickness; 1340 | } 1341 | 1342 | - (void)setRingRadius:(CGFloat)ringRadius { 1343 | if (!_isInitializing) _ringRadius = ringRadius; 1344 | } 1345 | 1346 | - (void)setRingNoTextRadius:(CGFloat)ringNoTextRadius { 1347 | if (!_isInitializing) _ringNoTextRadius = ringNoTextRadius; 1348 | } 1349 | 1350 | - (void)setCornerRadius:(CGFloat)cornerRadius { 1351 | if (!_isInitializing) _cornerRadius = cornerRadius; 1352 | } 1353 | 1354 | - (void)setFont:(UIFont*)font { 1355 | if (!_isInitializing) _font = font; 1356 | } 1357 | 1358 | - (void)setForegroundColor:(UIColor*)color { 1359 | if (!_isInitializing) _foregroundColor = color; 1360 | } 1361 | 1362 | - (void)setBackgroundColor:(UIColor*)color { 1363 | if (!_isInitializing) _backgroundColor = color; 1364 | } 1365 | 1366 | - (void)setBackgroundLayerColor:(UIColor*)color { 1367 | if (!_isInitializing) _backgroundLayerColor = color; 1368 | } 1369 | 1370 | - (void)setInfoImage:(UIImage*)image { 1371 | if (!_isInitializing) _infoImage = image; 1372 | } 1373 | 1374 | - (void)setSuccessImage:(UIImage*)image { 1375 | if (!_isInitializing) _successImage = image; 1376 | } 1377 | 1378 | - (void)setErrorImage:(UIImage*)image { 1379 | if (!_isInitializing) _errorImage = image; 1380 | } 1381 | 1382 | - (void)setViewForExtension:(UIView*)view { 1383 | if (!_isInitializing) _viewForExtension = view; 1384 | } 1385 | 1386 | - (void)setOffsetFromCenter:(UIOffset)offset { 1387 | if (!_isInitializing) _offsetFromCenter = offset; 1388 | } 1389 | 1390 | - (void)setMinimumDismissTimeInterval:(NSTimeInterval)minimumDismissTimeInterval { 1391 | if (!_isInitializing) _minimumDismissTimeInterval = minimumDismissTimeInterval; 1392 | } 1393 | 1394 | - (void)setFadeInAnimationDuration:(NSTimeInterval)duration { 1395 | if (!_isInitializing) _fadeInAnimationDuration = duration; 1396 | } 1397 | 1398 | - (void)setFadeOutAnimationDuration:(NSTimeInterval)duration { 1399 | if (!_isInitializing) _fadeOutAnimationDuration = duration; 1400 | } 1401 | 1402 | @end 1403 | 1404 | -------------------------------------------------------------------------------- /clearCache/clearCache/SVProgressHUD/SVProgressHUD/SVRadialGradientLayer.h: -------------------------------------------------------------------------------- 1 | // 2 | // SVRadialGradientLayer.h 3 | // SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD 4 | // 5 | // Copyright (c) 2014-2016 Tobias Tiemerding. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | @interface SVRadialGradientLayer : CALayer 11 | 12 | @property (nonatomic) CGPoint gradientCenter; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /clearCache/clearCache/SVProgressHUD/SVProgressHUD/SVRadialGradientLayer.m: -------------------------------------------------------------------------------- 1 | // 2 | // SVRadialGradientLayer.m 3 | // SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD 4 | // 5 | // Copyright (c) 2014-2016 Tobias Tiemerding. All rights reserved. 6 | // 7 | 8 | #import "SVRadialGradientLayer.h" 9 | 10 | @implementation SVRadialGradientLayer 11 | 12 | - (void)drawInContext:(CGContextRef)context { 13 | size_t locationsCount = 2; 14 | CGFloat locations[2] = {0.0f, 1.0f}; 15 | CGFloat colors[8] = {0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.75f}; 16 | CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 17 | CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, colors, locations, locationsCount); 18 | CGColorSpaceRelease(colorSpace); 19 | 20 | float radius = MIN(self.bounds.size.width , self.bounds.size.height); 21 | CGContextDrawRadialGradient (context, gradient, self.gradientCenter, 0, self.gradientCenter, radius, kCGGradientDrawsAfterEndLocation); 22 | CGGradientRelease(gradient); 23 | } 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /clearCache/clearCache/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // clearCache 4 | // 5 | // Created by li bo on 16/5/30. 6 | // Copyright © 2016年 li bo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UITableViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /clearCache/clearCache/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // clearCache 4 | // 5 | // Created by li bo on 16/5/30. 6 | // Copyright © 2016年 li bo. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "LBClearCacheTool.h" 11 | 12 | #import "SVProgressHUD.h" 13 | 14 | #define filePath [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] 15 | @interface ViewController () 16 | 17 | @end 18 | 19 | @implementation ViewController 20 | 21 | - (void)viewDidLoad { 22 | [super viewDidLoad]; 23 | // Do any additional setup after loading the view, typically from a nib. 24 | } 25 | 26 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 27 | 28 | return 50; 29 | } 30 | 31 | /* 32 | 33 | 34 | 说明:大家可以NSLog打印“[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]” 35 | 这个路径,然后进入这个路径去给Library -> Caches文件夹里面随便放文件,再次运行这个cell上显示的就是你文件夹真实的缓存 36 | 点击清除的时候,大家可以观察这个文件夹里面的东西,是会随之自动删除的 37 | 38 | 39 | 40 | 41 | 42 | 43 | */ 44 | 45 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 46 | static NSString *ID=@"cell"; 47 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID ]; 48 | if (cell==nil) { 49 | cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID]; 50 | } 51 | cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 52 | if (indexPath.row==0&&indexPath.section==0) { 53 | 54 | NSString *fileSize = [LBClearCacheTool getCacheSizeWithFilePath:filePath]; 55 | if ([fileSize integerValue] == 0) { 56 | cell.textLabel.text = @"清除缓存"; 57 | }else { 58 | cell.textLabel.text = [NSString stringWithFormat:@"清除缓存(%@)",fileSize]; 59 | } 60 | }else { 61 | cell.textLabel.text=[NSString stringWithFormat:@"这是第%zd组cell",indexPath.row]; 62 | 63 | } 64 | 65 | return cell; 66 | } 67 | 68 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 69 | { 70 | if (indexPath.row==0&&indexPath.section==0) { 71 | UIAlertController *alert=[UIAlertController alertControllerWithTitle:@"确定清除缓存吗?" message:nil preferredStyle:UIAlertControllerStyleActionSheet]; 72 | //创建一个取消和一个确定按钮 73 | UIAlertAction *actionCancle=[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]; 74 | //因为需要点击确定按钮后改变文字的值,所以需要在确定按钮这个block里面进行相应的操作 75 | UIAlertAction *actionOk=[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) { 76 | 77 | //清楚缓存 78 | BOOL isSuccess = [LBClearCacheTool clearCacheWithFilePath:filePath]; 79 | if (isSuccess) { 80 | [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; 81 | [SVProgressHUD setDefaultStyle:SVProgressHUDStyleDark]; 82 | [SVProgressHUD showSuccessWithStatus:@"清除成功"]; 83 | 84 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 85 | [SVProgressHUD dismiss]; 86 | }); 87 | } 88 | 89 | 90 | 91 | } ]; 92 | //将取消和确定按钮添加进弹框控制器 93 | [alert addAction:actionCancle]; 94 | [alert addAction:actionOk]; 95 | //添加一个文本框到弹框控制器 96 | 97 | 98 | //显示弹框控制器 99 | [self presentViewController:alert animated:YES completion:nil]; 100 | 101 | } 102 | 103 | } 104 | @end 105 | -------------------------------------------------------------------------------- /clearCache/clearCache/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // clearCache 4 | // 5 | // Created by li bo on 16/5/30. 6 | // Copyright © 2016年 li bo. 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 | --------------------------------------------------------------------------------