├── CLDashboardProgressView.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── lihui.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── lihui.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── CLDashboardProgressView.xcscheme │ └── xcschememanagement.plist ├── CLDashboardProgressView ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── CLDashboardProgressView │ ├── CLDashboardProgressLayer.h │ ├── CLDashboardProgressLayer.m │ ├── CLDashboardProgressView.h │ └── CLDashboardProgressView.m ├── Info.plist ├── ViewController.h ├── ViewController.m └── main.m ├── Demo.gif └── README.md /CLDashboardProgressView.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 9C6471541C22B04D0027200C /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C6471531C22B04D0027200C /* main.m */; }; 11 | 9C6471571C22B04D0027200C /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C6471561C22B04D0027200C /* AppDelegate.m */; }; 12 | 9C64715A1C22B04D0027200C /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C6471591C22B04D0027200C /* ViewController.m */; }; 13 | 9C64715D1C22B04D0027200C /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9C64715B1C22B04D0027200C /* Main.storyboard */; }; 14 | 9C64715F1C22B04D0027200C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9C64715E1C22B04D0027200C /* Assets.xcassets */; }; 15 | 9C6471621C22B04D0027200C /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9C6471601C22B04D0027200C /* LaunchScreen.storyboard */; }; 16 | 9C64716C1C22B0840027200C /* CLDashboardProgressView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C64716B1C22B0840027200C /* CLDashboardProgressView.m */; }; 17 | 9C64716F1C22B0C80027200C /* CLDashboardProgressLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C64716E1C22B0C80027200C /* CLDashboardProgressLayer.m */; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXFileReference section */ 21 | 9C64714F1C22B04D0027200C /* CLDashboardProgressView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CLDashboardProgressView.app; sourceTree = BUILT_PRODUCTS_DIR; }; 22 | 9C6471531C22B04D0027200C /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 23 | 9C6471551C22B04D0027200C /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 24 | 9C6471561C22B04D0027200C /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 25 | 9C6471581C22B04D0027200C /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 26 | 9C6471591C22B04D0027200C /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 27 | 9C64715C1C22B04D0027200C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 28 | 9C64715E1C22B04D0027200C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 29 | 9C6471611C22B04D0027200C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 30 | 9C6471631C22B04D0027200C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 31 | 9C64716A1C22B0840027200C /* CLDashboardProgressView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CLDashboardProgressView.h; path = CLDashboardProgressView/CLDashboardProgressView.h; sourceTree = ""; }; 32 | 9C64716B1C22B0840027200C /* CLDashboardProgressView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CLDashboardProgressView.m; path = CLDashboardProgressView/CLDashboardProgressView.m; sourceTree = ""; }; 33 | 9C64716D1C22B0C80027200C /* CLDashboardProgressLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CLDashboardProgressLayer.h; path = CLDashboardProgressView/CLDashboardProgressLayer.h; sourceTree = ""; }; 34 | 9C64716E1C22B0C80027200C /* CLDashboardProgressLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CLDashboardProgressLayer.m; path = CLDashboardProgressView/CLDashboardProgressLayer.m; sourceTree = ""; }; 35 | /* End PBXFileReference section */ 36 | 37 | /* Begin PBXFrameworksBuildPhase section */ 38 | 9C64714C1C22B04D0027200C /* Frameworks */ = { 39 | isa = PBXFrameworksBuildPhase; 40 | buildActionMask = 2147483647; 41 | files = ( 42 | ); 43 | runOnlyForDeploymentPostprocessing = 0; 44 | }; 45 | /* End PBXFrameworksBuildPhase section */ 46 | 47 | /* Begin PBXGroup section */ 48 | 9C6471461C22B04D0027200C = { 49 | isa = PBXGroup; 50 | children = ( 51 | 9C6471511C22B04D0027200C /* CLDashboardProgressView */, 52 | 9C6471501C22B04D0027200C /* Products */, 53 | ); 54 | sourceTree = ""; 55 | }; 56 | 9C6471501C22B04D0027200C /* Products */ = { 57 | isa = PBXGroup; 58 | children = ( 59 | 9C64714F1C22B04D0027200C /* CLDashboardProgressView.app */, 60 | ); 61 | name = Products; 62 | sourceTree = ""; 63 | }; 64 | 9C6471511C22B04D0027200C /* CLDashboardProgressView */ = { 65 | isa = PBXGroup; 66 | children = ( 67 | 9C6471691C22B05D0027200C /* CLDashboardProgressView */, 68 | 9C6471551C22B04D0027200C /* AppDelegate.h */, 69 | 9C6471561C22B04D0027200C /* AppDelegate.m */, 70 | 9C6471581C22B04D0027200C /* ViewController.h */, 71 | 9C6471591C22B04D0027200C /* ViewController.m */, 72 | 9C64715B1C22B04D0027200C /* Main.storyboard */, 73 | 9C64715E1C22B04D0027200C /* Assets.xcassets */, 74 | 9C6471601C22B04D0027200C /* LaunchScreen.storyboard */, 75 | 9C6471631C22B04D0027200C /* Info.plist */, 76 | 9C6471521C22B04D0027200C /* Supporting Files */, 77 | ); 78 | path = CLDashboardProgressView; 79 | sourceTree = ""; 80 | }; 81 | 9C6471521C22B04D0027200C /* Supporting Files */ = { 82 | isa = PBXGroup; 83 | children = ( 84 | 9C6471531C22B04D0027200C /* main.m */, 85 | ); 86 | name = "Supporting Files"; 87 | sourceTree = ""; 88 | }; 89 | 9C6471691C22B05D0027200C /* CLDashboardProgressView */ = { 90 | isa = PBXGroup; 91 | children = ( 92 | 9C64716A1C22B0840027200C /* CLDashboardProgressView.h */, 93 | 9C64716B1C22B0840027200C /* CLDashboardProgressView.m */, 94 | 9C64716D1C22B0C80027200C /* CLDashboardProgressLayer.h */, 95 | 9C64716E1C22B0C80027200C /* CLDashboardProgressLayer.m */, 96 | ); 97 | name = CLDashboardProgressView; 98 | sourceTree = ""; 99 | }; 100 | /* End PBXGroup section */ 101 | 102 | /* Begin PBXNativeTarget section */ 103 | 9C64714E1C22B04D0027200C /* CLDashboardProgressView */ = { 104 | isa = PBXNativeTarget; 105 | buildConfigurationList = 9C6471661C22B04D0027200C /* Build configuration list for PBXNativeTarget "CLDashboardProgressView" */; 106 | buildPhases = ( 107 | 9C64714B1C22B04D0027200C /* Sources */, 108 | 9C64714C1C22B04D0027200C /* Frameworks */, 109 | 9C64714D1C22B04D0027200C /* Resources */, 110 | ); 111 | buildRules = ( 112 | ); 113 | dependencies = ( 114 | ); 115 | name = CLDashboardProgressView; 116 | productName = CLDashboardProgressView; 117 | productReference = 9C64714F1C22B04D0027200C /* CLDashboardProgressView.app */; 118 | productType = "com.apple.product-type.application"; 119 | }; 120 | /* End PBXNativeTarget section */ 121 | 122 | /* Begin PBXProject section */ 123 | 9C6471471C22B04D0027200C /* Project object */ = { 124 | isa = PBXProject; 125 | attributes = { 126 | LastUpgradeCheck = 0720; 127 | ORGANIZATIONNAME = "李辉"; 128 | TargetAttributes = { 129 | 9C64714E1C22B04D0027200C = { 130 | CreatedOnToolsVersion = 7.2; 131 | DevelopmentTeam = 3V778BRDYP; 132 | }; 133 | }; 134 | }; 135 | buildConfigurationList = 9C64714A1C22B04D0027200C /* Build configuration list for PBXProject "CLDashboardProgressView" */; 136 | compatibilityVersion = "Xcode 3.2"; 137 | developmentRegion = English; 138 | hasScannedForEncodings = 0; 139 | knownRegions = ( 140 | en, 141 | Base, 142 | ); 143 | mainGroup = 9C6471461C22B04D0027200C; 144 | productRefGroup = 9C6471501C22B04D0027200C /* Products */; 145 | projectDirPath = ""; 146 | projectRoot = ""; 147 | targets = ( 148 | 9C64714E1C22B04D0027200C /* CLDashboardProgressView */, 149 | ); 150 | }; 151 | /* End PBXProject section */ 152 | 153 | /* Begin PBXResourcesBuildPhase section */ 154 | 9C64714D1C22B04D0027200C /* Resources */ = { 155 | isa = PBXResourcesBuildPhase; 156 | buildActionMask = 2147483647; 157 | files = ( 158 | 9C6471621C22B04D0027200C /* LaunchScreen.storyboard in Resources */, 159 | 9C64715F1C22B04D0027200C /* Assets.xcassets in Resources */, 160 | 9C64715D1C22B04D0027200C /* Main.storyboard in Resources */, 161 | ); 162 | runOnlyForDeploymentPostprocessing = 0; 163 | }; 164 | /* End PBXResourcesBuildPhase section */ 165 | 166 | /* Begin PBXSourcesBuildPhase section */ 167 | 9C64714B1C22B04D0027200C /* Sources */ = { 168 | isa = PBXSourcesBuildPhase; 169 | buildActionMask = 2147483647; 170 | files = ( 171 | 9C64715A1C22B04D0027200C /* ViewController.m in Sources */, 172 | 9C6471571C22B04D0027200C /* AppDelegate.m in Sources */, 173 | 9C6471541C22B04D0027200C /* main.m in Sources */, 174 | 9C64716F1C22B0C80027200C /* CLDashboardProgressLayer.m in Sources */, 175 | 9C64716C1C22B0840027200C /* CLDashboardProgressView.m in Sources */, 176 | ); 177 | runOnlyForDeploymentPostprocessing = 0; 178 | }; 179 | /* End PBXSourcesBuildPhase section */ 180 | 181 | /* Begin PBXVariantGroup section */ 182 | 9C64715B1C22B04D0027200C /* Main.storyboard */ = { 183 | isa = PBXVariantGroup; 184 | children = ( 185 | 9C64715C1C22B04D0027200C /* Base */, 186 | ); 187 | name = Main.storyboard; 188 | sourceTree = ""; 189 | }; 190 | 9C6471601C22B04D0027200C /* LaunchScreen.storyboard */ = { 191 | isa = PBXVariantGroup; 192 | children = ( 193 | 9C6471611C22B04D0027200C /* Base */, 194 | ); 195 | name = LaunchScreen.storyboard; 196 | sourceTree = ""; 197 | }; 198 | /* End PBXVariantGroup section */ 199 | 200 | /* Begin XCBuildConfiguration section */ 201 | 9C6471641C22B04D0027200C /* Debug */ = { 202 | isa = XCBuildConfiguration; 203 | buildSettings = { 204 | ALWAYS_SEARCH_USER_PATHS = NO; 205 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 206 | CLANG_CXX_LIBRARY = "libc++"; 207 | CLANG_ENABLE_MODULES = YES; 208 | CLANG_ENABLE_OBJC_ARC = YES; 209 | CLANG_WARN_BOOL_CONVERSION = YES; 210 | CLANG_WARN_CONSTANT_CONVERSION = YES; 211 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 212 | CLANG_WARN_EMPTY_BODY = YES; 213 | CLANG_WARN_ENUM_CONVERSION = YES; 214 | CLANG_WARN_INT_CONVERSION = YES; 215 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 216 | CLANG_WARN_UNREACHABLE_CODE = YES; 217 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 218 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 219 | COPY_PHASE_STRIP = NO; 220 | DEBUG_INFORMATION_FORMAT = dwarf; 221 | ENABLE_STRICT_OBJC_MSGSEND = YES; 222 | ENABLE_TESTABILITY = YES; 223 | GCC_C_LANGUAGE_STANDARD = gnu99; 224 | GCC_DYNAMIC_NO_PIC = NO; 225 | GCC_NO_COMMON_BLOCKS = YES; 226 | GCC_OPTIMIZATION_LEVEL = 0; 227 | GCC_PREPROCESSOR_DEFINITIONS = ( 228 | "DEBUG=1", 229 | "$(inherited)", 230 | ); 231 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 232 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 233 | GCC_WARN_UNDECLARED_SELECTOR = YES; 234 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 235 | GCC_WARN_UNUSED_FUNCTION = YES; 236 | GCC_WARN_UNUSED_VARIABLE = YES; 237 | IPHONEOS_DEPLOYMENT_TARGET = 9.2; 238 | MTL_ENABLE_DEBUG_INFO = YES; 239 | ONLY_ACTIVE_ARCH = YES; 240 | SDKROOT = iphoneos; 241 | TARGETED_DEVICE_FAMILY = "1,2"; 242 | }; 243 | name = Debug; 244 | }; 245 | 9C6471651C22B04D0027200C /* Release */ = { 246 | isa = XCBuildConfiguration; 247 | buildSettings = { 248 | ALWAYS_SEARCH_USER_PATHS = NO; 249 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 250 | CLANG_CXX_LIBRARY = "libc++"; 251 | CLANG_ENABLE_MODULES = YES; 252 | CLANG_ENABLE_OBJC_ARC = YES; 253 | CLANG_WARN_BOOL_CONVERSION = YES; 254 | CLANG_WARN_CONSTANT_CONVERSION = YES; 255 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 256 | CLANG_WARN_EMPTY_BODY = YES; 257 | CLANG_WARN_ENUM_CONVERSION = YES; 258 | CLANG_WARN_INT_CONVERSION = YES; 259 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 260 | CLANG_WARN_UNREACHABLE_CODE = YES; 261 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 262 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 263 | COPY_PHASE_STRIP = NO; 264 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 265 | ENABLE_NS_ASSERTIONS = NO; 266 | ENABLE_STRICT_OBJC_MSGSEND = YES; 267 | GCC_C_LANGUAGE_STANDARD = gnu99; 268 | GCC_NO_COMMON_BLOCKS = YES; 269 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 270 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 271 | GCC_WARN_UNDECLARED_SELECTOR = YES; 272 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 273 | GCC_WARN_UNUSED_FUNCTION = YES; 274 | GCC_WARN_UNUSED_VARIABLE = YES; 275 | IPHONEOS_DEPLOYMENT_TARGET = 9.2; 276 | MTL_ENABLE_DEBUG_INFO = NO; 277 | SDKROOT = iphoneos; 278 | TARGETED_DEVICE_FAMILY = "1,2"; 279 | VALIDATE_PRODUCT = YES; 280 | }; 281 | name = Release; 282 | }; 283 | 9C6471671C22B04D0027200C /* Debug */ = { 284 | isa = XCBuildConfiguration; 285 | buildSettings = { 286 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 287 | CODE_SIGN_IDENTITY = "iPhone Developer"; 288 | INFOPLIST_FILE = CLDashboardProgressView/Info.plist; 289 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 290 | PRODUCT_BUNDLE_IDENTIFIER = ChangeLee.CLDashboardProgressView; 291 | PRODUCT_NAME = "$(TARGET_NAME)"; 292 | }; 293 | name = Debug; 294 | }; 295 | 9C6471681C22B04D0027200C /* Release */ = { 296 | isa = XCBuildConfiguration; 297 | buildSettings = { 298 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 299 | CODE_SIGN_IDENTITY = "iPhone Developer"; 300 | INFOPLIST_FILE = CLDashboardProgressView/Info.plist; 301 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 302 | PRODUCT_BUNDLE_IDENTIFIER = ChangeLee.CLDashboardProgressView; 303 | PRODUCT_NAME = "$(TARGET_NAME)"; 304 | }; 305 | name = Release; 306 | }; 307 | /* End XCBuildConfiguration section */ 308 | 309 | /* Begin XCConfigurationList section */ 310 | 9C64714A1C22B04D0027200C /* Build configuration list for PBXProject "CLDashboardProgressView" */ = { 311 | isa = XCConfigurationList; 312 | buildConfigurations = ( 313 | 9C6471641C22B04D0027200C /* Debug */, 314 | 9C6471651C22B04D0027200C /* Release */, 315 | ); 316 | defaultConfigurationIsVisible = 0; 317 | defaultConfigurationName = Release; 318 | }; 319 | 9C6471661C22B04D0027200C /* Build configuration list for PBXNativeTarget "CLDashboardProgressView" */ = { 320 | isa = XCConfigurationList; 321 | buildConfigurations = ( 322 | 9C6471671C22B04D0027200C /* Debug */, 323 | 9C6471681C22B04D0027200C /* Release */, 324 | ); 325 | defaultConfigurationIsVisible = 0; 326 | }; 327 | /* End XCConfigurationList section */ 328 | }; 329 | rootObject = 9C6471471C22B04D0027200C /* Project object */; 330 | } 331 | -------------------------------------------------------------------------------- /CLDashboardProgressView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /CLDashboardProgressView.xcodeproj/project.xcworkspace/xcuserdata/lihui.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/changelee82/CLDashboardProgressView/a5f412d2a765ade5b7efb4bab534a421814f2821/CLDashboardProgressView.xcodeproj/project.xcworkspace/xcuserdata/lihui.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /CLDashboardProgressView.xcodeproj/xcuserdata/lihui.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /CLDashboardProgressView.xcodeproj/xcuserdata/lihui.xcuserdatad/xcschemes/CLDashboardProgressView.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /CLDashboardProgressView.xcodeproj/xcuserdata/lihui.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | CLDashboardProgressView.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 9C64714E1C22B04D0027200C 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /CLDashboardProgressView/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // CLDashboardProgressView 4 | // 5 | // Created by 李辉 on 15/12/17. 6 | // Copyright © 2015年 李辉. 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 | -------------------------------------------------------------------------------- /CLDashboardProgressView/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // CLDashboardProgressView 4 | // 5 | // Created by 李辉 on 15/12/17. 6 | // Copyright © 2015年 李辉. 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 | -------------------------------------------------------------------------------- /CLDashboardProgressView/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /CLDashboardProgressView/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 | -------------------------------------------------------------------------------- /CLDashboardProgressView/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 | 39 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /CLDashboardProgressView/CLDashboardProgressView/CLDashboardProgressLayer.h: -------------------------------------------------------------------------------- 1 | // 2 | // CLDashboardProgressLayer.h 3 | // CLDashboardProgressView 4 | // 5 | // Created by 李辉 on 15/12/17. 6 | // Copyright © 2015年 李辉. All rights reserved. 7 | // https://github.com/changelee82/CLDashboardProgressView 8 | // 9 | 10 | #import 11 | #import 12 | 13 | 14 | /** 仪表盘进度条层 */ 15 | @interface CLDashboardProgressLayer : CALayer 16 | 17 | @property (nonatomic, assign) CGFloat outerRadius; // 外圈半径 18 | @property (nonatomic, assign) CGFloat innerRadius; // 内圈半径 19 | @property (nonatomic, assign) CGFloat beginAngle; // 起始角度 20 | @property (nonatomic, assign) CGFloat blockAngle; // 每个进度块的角度 21 | @property (nonatomic, assign) CGFloat gapAngle; // 两个进度块的间隙的角度 22 | @property (nonatomic, strong) UIColor *progressColor; // 进度条填充色 23 | @property (nonatomic, strong) UIColor *trackColor; // 进度条痕迹填充色 24 | @property (nonatomic, strong) UIColor *outlineColor; // 进度条边框颜色 25 | @property (nonatomic, assign) CGFloat outlineWidth; // 进度条边框线宽 26 | 27 | @property (nonatomic, assign) NSUInteger blockCount; // 进度块的数量 28 | @property (nonatomic, assign) CGFloat minValue; // 进度条最小数值 29 | @property (nonatomic, assign) CGFloat maxValue; // 进度条最大数值 30 | @property (nonatomic, assign) CGFloat currentValue; // 进度条当前数值 31 | 32 | @property (nonatomic, assign) BOOL showShadow; // 是否显示阴影 33 | @property (nonatomic, assign) CGFloat shadowOuterRadius; // 阴影外圈半径 34 | @property (nonatomic, assign) CGFloat shadowInnerRadius; // 阴影内圈半径 35 | @property (nonatomic, strong) UIColor *shadowFillColor; // 阴影颜色 36 | 37 | /** 自动调整角度,使进度条开口向下并且左右对称,默认为NO */ 38 | @property (nonatomic, assign) BOOL autoAdjustAngle; 39 | 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /CLDashboardProgressView/CLDashboardProgressView/CLDashboardProgressLayer.m: -------------------------------------------------------------------------------- 1 | // 2 | // CLDashboardProgressLayer.m 3 | // CLDashboardProgressView 4 | // 5 | // Created by 李辉 on 15/12/17. 6 | // Copyright © 2015年 李辉. All rights reserved. 7 | // https://github.com/changelee82/CLDashboardProgressView 8 | // 9 | 10 | #import "CLDashboardProgressLayer.h" 11 | 12 | /** 2π */ 13 | static const CGFloat k2Pi = M_PI * 2.0f; 14 | 15 | 16 | 17 | @implementation CLDashboardProgressLayer 18 | 19 | /** 初始化方法,用于从代码中创建的类实例 */ 20 | - (instancetype)init 21 | { 22 | self = [super init]; 23 | if (self) 24 | { 25 | } 26 | return self; 27 | } 28 | 29 | /** 初始化方法 */ 30 | - (instancetype)initWithLayer:(id)layer 31 | { 32 | if (self = [super initWithLayer:layer]) 33 | { 34 | if ([layer isKindOfClass:[CLDashboardProgressLayer class]]) 35 | { 36 | } 37 | } 38 | return self; 39 | } 40 | 41 | /** 42 | * 创建及初始化层 43 | * 44 | * @return 新创建的层 45 | */ 46 | + (id)layer 47 | { 48 | CLDashboardProgressLayer *layer = [[CLDashboardProgressLayer alloc] init]; 49 | return layer; 50 | } 51 | 52 | // 下列属性改变,则刷新层 53 | /** 54 | * 指定属性改变时,layer刷新 55 | * 56 | * @param key 属性名 57 | * 58 | * @return 刷新:YES; 不刷新:NO 59 | */ 60 | + (BOOL)needsDisplayForKey:(NSString *)key 61 | { 62 | if ( [key isEqualToString:@"outerRadius"] 63 | || [key isEqualToString:@"innerRadius"] 64 | || [key isEqualToString:@"beginAngle"] 65 | || [key isEqualToString:@"blockAngle"] 66 | || [key isEqualToString:@"gapAngle"] 67 | || [key isEqualToString:@"progressColor"] 68 | || [key isEqualToString:@"trackColor"] 69 | || [key isEqualToString:@"outlineColor"] 70 | || [key isEqualToString:@"outlineWidth"] 71 | || [key isEqualToString:@"blockCount"] 72 | || [key isEqualToString:@"minValue"] 73 | || [key isEqualToString:@"maxValue"] 74 | || [key isEqualToString:@"currentValue"] 75 | || [key isEqualToString:@"showShadow"] 76 | || [key isEqualToString:@"shadowOuterRadius"] 77 | || [key isEqualToString:@"shadowInnerRadius"] 78 | || [key isEqualToString:@"shadowFillColor"] 79 | || [key isEqualToString:@"autoAdjustAngle"]) 80 | { 81 | return YES; 82 | } 83 | 84 | return [super needsDisplayForKey:key]; 85 | } 86 | 87 | 88 | /** 89 | * 绘制层 90 | * 91 | * @param ctx 设备上下文 92 | */ 93 | - (void)drawInContext:(CGContextRef)ctx 94 | { 95 | // 自动调整角度 96 | if (_autoAdjustAngle == YES) 97 | { 98 | CGFloat totalAngle = k2Pi - (self.blockAngle+self.gapAngle) * self.blockCount - self.gapAngle; 99 | _beginAngle = k2Pi * 0.25 + totalAngle * 0.5; 100 | } 101 | 102 | // 根据中点绘制层 103 | CGPoint center = CGPointMake(self.bounds.size.width * 0.5, self.bounds.size.height * 0.5); 104 | [self drawProgressionInContext:ctx atCenter:center]; 105 | } 106 | 107 | 108 | /** 109 | * 绘制进度条 110 | * 111 | * @param ctx 设备上下文 112 | * @param center 绘制中心点 113 | */ 114 | - (void)drawProgressionInContext:(CGContextRef)ctx 115 | atCenter:(CGPoint)center 116 | { 117 | // 计算当前进度显示到第几块 118 | CGFloat total = _maxValue - _minValue; 119 | CGFloat current = _currentValue - _minValue; 120 | CGFloat blockValue = total / _blockCount; 121 | NSUInteger currentBlock = current / blockValue; 122 | 123 | // 第一块的起始角度和终止角度 124 | CGFloat blockBeginAngle = _beginAngle; 125 | CGFloat blockEndAngle = _beginAngle + _blockAngle; 126 | 127 | // 绘制进度块 128 | BOOL isFill; 129 | for (NSUInteger i=1; i<=_blockCount; ++i) 130 | { 131 | if (i <= currentBlock) 132 | isFill = YES; 133 | else 134 | isFill = NO; 135 | 136 | // 绘制块 137 | [self drawBlockInContext:ctx center:center startAngle:blockBeginAngle endAngle:blockEndAngle isFill:isFill]; 138 | 139 | // 绘制阴影 140 | if (_showShadow) 141 | [self drawBlockShadowInContext:ctx center:center startAngle:blockBeginAngle endAngle:blockEndAngle]; 142 | 143 | // 下一块的起始角度和终止角度 144 | blockBeginAngle += _blockAngle + _gapAngle; 145 | blockEndAngle += _blockAngle + _gapAngle; 146 | } 147 | } 148 | 149 | /** 150 | * 绘制进度块,按照顺时针绘制 151 | * 152 | * @param ctx 设备上下文 153 | * @param center 进度条中心点 154 | * @param startAngle 块起始角度 155 | * @param endAngle 块终止角度 156 | * @param isFill 块是否被填充 157 | */ 158 | - (void)drawBlockInContext:(CGContextRef)ctx 159 | center:(CGPoint)center 160 | startAngle:(CGFloat)startAngle 161 | endAngle:(CGFloat)endAngle 162 | isFill:(BOOL)isFill 163 | { 164 | // 绘制扇形 165 | CGContextAddArc(ctx, center.x, center.y, _outerRadius, startAngle, endAngle, 0); 166 | CGContextAddArc(ctx, center.x, center.y, _innerRadius, endAngle, startAngle, 1); 167 | CGContextClosePath(ctx); 168 | 169 | UIColor *fillColor; 170 | if (isFill) 171 | fillColor = _progressColor; 172 | else 173 | fillColor = _trackColor; 174 | 175 | // 设置绘制参数 176 | CGContextSetLineWidth(ctx, _outlineWidth); 177 | CGContextSetStrokeColorWithColor(ctx, _outlineColor.CGColor); 178 | CGContextSetFillColorWithColor(ctx, fillColor.CGColor); 179 | 180 | // 绘制 181 | CGContextDrawPath(ctx, kCGPathFillStroke); 182 | } 183 | 184 | /** 185 | * 绘制进度块阴影 186 | * 187 | * @param ctx 设备上下文 188 | * @param center 进度条中心点 189 | * @param startAngle 块起始角度 190 | * @param endAngle 块终止角度 191 | */ 192 | - (void)drawBlockShadowInContext:(CGContextRef)ctx 193 | center:(CGPoint)center 194 | startAngle:(CGFloat)startAngle 195 | endAngle:(CGFloat)endAngle 196 | { 197 | // 绘制扇形 198 | CGContextAddArc(ctx, center.x, center.y, _shadowOuterRadius, startAngle, endAngle, 0); 199 | CGContextAddArc(ctx, center.x, center.y, _shadowInnerRadius, endAngle, startAngle, 1); 200 | CGContextClosePath(ctx); 201 | 202 | 203 | CGContextSetFillColorWithColor(ctx, _shadowFillColor.CGColor); 204 | CGContextFillPath(ctx); 205 | } 206 | 207 | 208 | @end 209 | -------------------------------------------------------------------------------- /CLDashboardProgressView/CLDashboardProgressView/CLDashboardProgressView.h: -------------------------------------------------------------------------------- 1 | // 2 | // CLDashboardProgressView.h 3 | // CLDashboardProgressView 4 | // 5 | // Created by 李辉 on 15/12/17. 6 | // Copyright © 2015年 李辉. All rights reserved. 7 | // https://github.com/changelee82/CLDashboardProgressView 8 | // 9 | 10 | #import 11 | 12 | 13 | /** 仪表盘进度条视图 */ 14 | @interface CLDashboardProgressView : UIView 15 | 16 | /** 外圈半径,默认为视图短边边长的一半 */ 17 | @property (nonatomic, assign) CGFloat outerRadius; 18 | /** 内圈半径,默认为(外圈半径-12) */ 19 | @property (nonatomic, assign) CGFloat innerRadius; 20 | 21 | /** 起始角度,单位是角度,3点钟方向为0度,顺时针旋转,默认值145度 */ 22 | @property (nonatomic, assign) CGFloat beginAngle; 23 | /** 每个进度块的角度范围,单位是角度,默认值8度 */ 24 | @property (nonatomic, assign) CGFloat blockAngle; 25 | /** 两个进度块的间隙的角度,单位是角度,默认值2度 */ 26 | @property (nonatomic, assign) CGFloat gapAngle; 27 | 28 | /** 进度条填充色,默认为绿色 */ 29 | @property (nonatomic, strong) UIColor *progressColor; 30 | /** 进度条痕迹填充色,默认为灰色 */ 31 | @property (nonatomic, strong) UIColor *trackColor; 32 | /** 进度条边框颜色,默认为无色 */ 33 | @property (nonatomic, strong) UIColor *outlineColor; 34 | /** 进度条边框线宽,默认为0 */ 35 | @property (nonatomic, assign) CGFloat outlineWidth; 36 | 37 | /** 进度块的数量,默认为26 */ 38 | @property (nonatomic, assign) NSUInteger blockCount; 39 | /** 进度条最小数值,默认为0 */ 40 | @property (nonatomic, assign) CGFloat minValue; 41 | /** 进度条最大数值,默认为100 */ 42 | @property (nonatomic, assign) CGFloat maxValue; 43 | /** 进度条当前数值 */ 44 | @property (nonatomic, assign) CGFloat currentValue; 45 | 46 | /** 是否显示阴影,默认为NO */ 47 | @property (nonatomic, assign) BOOL showShadow; 48 | /** 阴影外圈半径,默认为(内圈半径-5),最小值为0 */ 49 | @property (nonatomic, assign) CGFloat shadowOuterRadius; 50 | /** 阴影内圈半径,默认为10 */ 51 | @property (nonatomic, assign) CGFloat shadowInnerRadius; 52 | /** 阴影颜色,默认为0.3透明度的灰色 */ 53 | @property (nonatomic, strong) UIColor *shadowFillColor; 54 | 55 | /** 自动调整角度,使进度条开口向下并且左右对称,默认为YES */ 56 | @property (nonatomic, assign) BOOL autoAdjustAngle; 57 | 58 | @end 59 | -------------------------------------------------------------------------------- /CLDashboardProgressView/CLDashboardProgressView/CLDashboardProgressView.m: -------------------------------------------------------------------------------- 1 | // 2 | // CLDashboardProgressView.m 3 | // CLDashboardProgressView 4 | // 5 | // Created by 李辉 on 15/12/17. 6 | // Copyright © 2015年 李辉. All rights reserved. 7 | // https://github.com/changelee82/CLDashboardProgressView 8 | // 9 | 10 | #import "CLDashboardProgressView.h" 11 | #import "CLDashboardProgressLayer.h" 12 | 13 | 14 | #define DEGREES_TO_RADIANS(angle) ((angle) / 180.0 * M_PI) // 角度转弧度 15 | #define RADIANS_TO_DEGREES(radians) ((radians) * (180.0 / M_PI)) // 弧度转角度 16 | 17 | 18 | 19 | @implementation CLDashboardProgressView 20 | 21 | #pragma mark - 初始化 22 | 23 | /** 初始化方法,用于从代码中创建的类实例 */ 24 | - (instancetype)init 25 | { 26 | self = [super init]; 27 | if (self) 28 | { 29 | [self defaultInit]; 30 | } 31 | return self; 32 | } 33 | 34 | /** 初始化方法,用于从代码中创建的类实例 */ 35 | - (instancetype)initWithFrame:(CGRect)frame 36 | { 37 | self = [super initWithFrame:frame]; 38 | if (self) 39 | { 40 | [self defaultInit]; 41 | } 42 | return self; 43 | } 44 | 45 | /** 初始化方法,用于从xib文件中载入的类实例 */ 46 | - (instancetype)initWithCoder:(NSCoder *)decoder 47 | { 48 | self = [super initWithCoder:decoder]; 49 | if (self) 50 | { 51 | [self defaultInit]; 52 | } 53 | return self; 54 | } 55 | 56 | /** 默认的初始化方法 */ 57 | - (void)defaultInit 58 | { 59 | CGFloat minRadius = MIN(self.bounds.size.width, self.bounds.size.height); 60 | 61 | self.outerRadius = MIN(minRadius, 221) / 2; 62 | self.innerRadius = MAX(self.outerRadius - 12, 0); 63 | self.beginAngle = 145; 64 | self.blockAngle = 8; 65 | self.gapAngle = 2; 66 | self.progressColor = [UIColor greenColor]; 67 | self.trackColor = [UIColor grayColor]; 68 | self.outlineColor = [UIColor clearColor]; 69 | self.outlineWidth = 0; 70 | 71 | self.blockCount = 26; 72 | self.minValue = 0; 73 | self.maxValue = 100; 74 | self.currentValue = 50; 75 | 76 | self.showShadow = NO; 77 | self.shadowOuterRadius = MAX(self.innerRadius-5, 0); 78 | self.shadowInnerRadius = 10; 79 | self.shadowFillColor = [[UIColor grayColor] colorWithAlphaComponent:0.3]; 80 | 81 | self.autoAdjustAngle = YES; 82 | } 83 | 84 | // 重设默认层 85 | + (Class)layerClass 86 | { 87 | return [CLDashboardProgressLayer class]; 88 | } 89 | 90 | // 重新布局视图 91 | - (void)layoutSubviews 92 | { 93 | CLDashboardProgressLayer *layer = (CLDashboardProgressLayer *)self.layer; 94 | [layer setNeedsDisplay]; 95 | } 96 | 97 | 98 | 99 | #pragma mark - 属性 100 | 101 | - (CGFloat)outerRadius 102 | { 103 | CLDashboardProgressView *layer = (CLDashboardProgressView *)self.layer; 104 | 105 | return layer.outerRadius; 106 | } 107 | 108 | - (void)setOuterRadius:(CGFloat)outerRadius 109 | { 110 | if (self.outerRadius != outerRadius) 111 | { 112 | CLDashboardProgressView *layer = (CLDashboardProgressView *)self.layer; 113 | layer.outerRadius = outerRadius; 114 | [layer setNeedsDisplay]; 115 | } 116 | } 117 | 118 | - (CGFloat)innerRadius 119 | { 120 | CLDashboardProgressView *layer = (CLDashboardProgressView *)self.layer; 121 | 122 | return layer.innerRadius; 123 | } 124 | 125 | - (void)setInnerRadius:(CGFloat)innerRadius 126 | { 127 | if (self.innerRadius != innerRadius) 128 | { 129 | CLDashboardProgressView *layer = (CLDashboardProgressView *)self.layer; 130 | layer.innerRadius = innerRadius; 131 | [layer setNeedsDisplay]; 132 | } 133 | } 134 | 135 | - (CGFloat)beginAngle 136 | { 137 | CLDashboardProgressView *layer = (CLDashboardProgressView *)self.layer; 138 | 139 | return RADIANS_TO_DEGREES(layer.beginAngle); 140 | } 141 | 142 | - (void)setBeginAngle:(CGFloat)beginAngle 143 | { 144 | CGFloat radians = DEGREES_TO_RADIANS(beginAngle); 145 | if (self.beginAngle != radians) 146 | { 147 | CLDashboardProgressView *layer = (CLDashboardProgressView *)self.layer; 148 | layer.beginAngle = radians; 149 | [layer setNeedsDisplay]; 150 | } 151 | } 152 | 153 | - (CGFloat)blockAngle 154 | { 155 | CLDashboardProgressView *layer = (CLDashboardProgressView *)self.layer; 156 | 157 | return RADIANS_TO_DEGREES(layer.blockAngle); 158 | } 159 | 160 | - (void)setBlockAngle:(CGFloat)blockAngle 161 | { 162 | CGFloat radians = DEGREES_TO_RADIANS(blockAngle); 163 | if (self.blockAngle != blockAngle) 164 | { 165 | CLDashboardProgressView *layer = (CLDashboardProgressView *)self.layer; 166 | layer.blockAngle = radians; 167 | [layer setNeedsDisplay]; 168 | } 169 | } 170 | 171 | - (CGFloat)gapAngle 172 | { 173 | CLDashboardProgressView *layer = (CLDashboardProgressView *)self.layer; 174 | 175 | return RADIANS_TO_DEGREES(layer.gapAngle); 176 | } 177 | 178 | - (void)setGapAngle:(CGFloat)gapAngle 179 | { 180 | CGFloat radians = DEGREES_TO_RADIANS(gapAngle); 181 | if (self.gapAngle != radians) 182 | { 183 | CLDashboardProgressView *layer = (CLDashboardProgressView *)self.layer; 184 | layer.gapAngle = radians; 185 | [layer setNeedsDisplay]; 186 | } 187 | } 188 | 189 | - (UIColor *)progressColor 190 | { 191 | CLDashboardProgressView *layer = (CLDashboardProgressView *)self.layer; 192 | 193 | return layer.progressColor; 194 | } 195 | 196 | - (void)setProgressColor:(UIColor *)progressColor 197 | { 198 | if (![self.progressColor isEqual:progressColor]) 199 | { 200 | CLDashboardProgressView *layer = (CLDashboardProgressView *)self.layer; 201 | layer.progressColor = progressColor; 202 | [layer setNeedsDisplay]; 203 | } 204 | } 205 | 206 | - (UIColor *)trackColor 207 | { 208 | CLDashboardProgressView *layer = (CLDashboardProgressView *)self.layer; 209 | 210 | return layer.trackColor; 211 | } 212 | 213 | - (void)setTrackColor:(UIColor *)trackColor 214 | { 215 | if (![self.trackColor isEqual:trackColor]) 216 | { 217 | CLDashboardProgressView *layer = (CLDashboardProgressView *)self.layer; 218 | layer.trackColor = trackColor; 219 | [layer setNeedsDisplay]; 220 | } 221 | } 222 | 223 | - (UIColor *)outlineColor 224 | { 225 | CLDashboardProgressView *layer = (CLDashboardProgressView *)self.layer; 226 | 227 | return layer.outlineColor; 228 | } 229 | 230 | - (void)setOutlineColor:(UIColor *)outlineColor 231 | { 232 | if (![self.outlineColor isEqual:outlineColor]) 233 | { 234 | CLDashboardProgressView *layer = (CLDashboardProgressView *)self.layer; 235 | layer.outlineColor = outlineColor; 236 | [layer setNeedsDisplay]; 237 | } 238 | } 239 | 240 | - (CGFloat)outlineWidth 241 | { 242 | CLDashboardProgressView *layer = (CLDashboardProgressView *)self.layer; 243 | 244 | return layer.outlineWidth; 245 | } 246 | 247 | - (void)setOutlineWidth:(CGFloat)outlineWidth 248 | { 249 | if (self.outlineWidth != outlineWidth) 250 | { 251 | CLDashboardProgressView *layer = (CLDashboardProgressView *)self.layer; 252 | layer.outlineWidth = outlineWidth; 253 | [layer setNeedsDisplay]; 254 | } 255 | } 256 | 257 | - (NSUInteger)blockCount 258 | { 259 | CLDashboardProgressView *layer = (CLDashboardProgressView *)self.layer; 260 | 261 | return layer.blockCount; 262 | } 263 | 264 | - (void)setBlockCount:(NSUInteger)blockCount 265 | { 266 | if (self.blockCount != blockCount) 267 | { 268 | CLDashboardProgressView *layer = (CLDashboardProgressView *)self.layer; 269 | layer.blockCount = blockCount; 270 | [layer setNeedsDisplay]; 271 | } 272 | } 273 | 274 | - (CGFloat)minValue 275 | { 276 | CLDashboardProgressView *layer = (CLDashboardProgressView *)self.layer; 277 | 278 | return layer.minValue; 279 | } 280 | 281 | - (void)setMinValue:(CGFloat)minValue 282 | { 283 | if (self.minValue != minValue) 284 | { 285 | CLDashboardProgressView *layer = (CLDashboardProgressView *)self.layer; 286 | layer.minValue = minValue; 287 | [layer setNeedsDisplay]; 288 | } 289 | } 290 | 291 | - (CGFloat)maxValue 292 | { 293 | CLDashboardProgressView *layer = (CLDashboardProgressView *)self.layer; 294 | 295 | return layer.maxValue; 296 | } 297 | 298 | - (void)setMaxValue:(CGFloat)maxValue 299 | { 300 | if (self.maxValue != maxValue) 301 | { 302 | CLDashboardProgressView *layer = (CLDashboardProgressView *)self.layer; 303 | layer.maxValue = maxValue; 304 | [layer setNeedsDisplay]; 305 | } 306 | } 307 | 308 | - (CGFloat)currentValue 309 | { 310 | CLDashboardProgressView *layer = (CLDashboardProgressView *)self.layer; 311 | 312 | return layer.currentValue; 313 | } 314 | 315 | - (void)setCurrentValue:(CGFloat)currentValue 316 | { 317 | if (self.currentValue != currentValue) 318 | { 319 | CLDashboardProgressView *layer = (CLDashboardProgressView *)self.layer; 320 | layer.currentValue = currentValue; 321 | [layer setNeedsDisplay]; 322 | } 323 | } 324 | 325 | - (BOOL)showShadow 326 | { 327 | CLDashboardProgressView *layer = (CLDashboardProgressView *)self.layer; 328 | 329 | return layer.showShadow; 330 | } 331 | 332 | - (void)setShowShadow:(BOOL)showShadow 333 | { 334 | if (self.showShadow != showShadow) 335 | { 336 | CLDashboardProgressView *layer = (CLDashboardProgressView *)self.layer; 337 | layer.showShadow = showShadow; 338 | [layer setNeedsDisplay]; 339 | } 340 | } 341 | 342 | - (CGFloat)shadowOuterRadius 343 | { 344 | CLDashboardProgressView *layer = (CLDashboardProgressView *)self.layer; 345 | 346 | return layer.shadowOuterRadius; 347 | } 348 | 349 | - (void)setShadowOuterRadius:(CGFloat)shadowOuterRadius 350 | { 351 | if (self.shadowOuterRadius != shadowOuterRadius) 352 | { 353 | CLDashboardProgressView *layer = (CLDashboardProgressView *)self.layer; 354 | layer.shadowOuterRadius = shadowOuterRadius; 355 | [layer setNeedsDisplay]; 356 | } 357 | } 358 | 359 | - (CGFloat)shadowInnerRadius 360 | { 361 | CLDashboardProgressView *layer = (CLDashboardProgressView *)self.layer; 362 | 363 | return layer.shadowInnerRadius; 364 | } 365 | 366 | - (void)setShadowInnerRadius:(CGFloat)shadowInnerRadius 367 | { 368 | if (self.shadowInnerRadius != shadowInnerRadius) 369 | { 370 | CLDashboardProgressView *layer = (CLDashboardProgressView *)self.layer; 371 | layer.shadowInnerRadius = shadowInnerRadius; 372 | [layer setNeedsDisplay]; 373 | } 374 | } 375 | 376 | - (UIColor *)shadowFillColor 377 | { 378 | CLDashboardProgressView *layer = (CLDashboardProgressView *)self.layer; 379 | 380 | return layer.shadowFillColor; 381 | } 382 | 383 | - (void)setShadowFillColor:(UIColor *)shadowFillColor 384 | { 385 | if (![self.shadowFillColor isEqual:shadowFillColor]) 386 | { 387 | CLDashboardProgressView *layer = (CLDashboardProgressView *)self.layer; 388 | layer.shadowFillColor = shadowFillColor; 389 | [layer setNeedsDisplay]; 390 | } 391 | } 392 | 393 | - (BOOL)autoAdjustAngle 394 | { 395 | CLDashboardProgressView *layer = (CLDashboardProgressView *)self.layer; 396 | 397 | return layer.autoAdjustAngle; 398 | } 399 | 400 | - (void)setAutoAdjustAngle:(BOOL)autoAdjustAngle 401 | { 402 | if (self.autoAdjustAngle != autoAdjustAngle) 403 | { 404 | CLDashboardProgressView *layer = (CLDashboardProgressView *)self.layer; 405 | layer.autoAdjustAngle = autoAdjustAngle; 406 | [layer setNeedsDisplay]; 407 | } 408 | } 409 | 410 | @end 411 | -------------------------------------------------------------------------------- /CLDashboardProgressView/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /CLDashboardProgressView/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // CLDashboardProgressView 4 | // 5 | // Created by 李辉 on 15/12/17. 6 | // Copyright © 2015年 李辉. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /CLDashboardProgressView/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // CLDashboardProgressView 4 | // 5 | // Created by 李辉 on 15/12/17. 6 | // Copyright © 2015年 李辉. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "CLDashboardProgressView.h" 11 | 12 | 13 | @interface ViewController () 14 | 15 | @property (nonatomic, strong) CLDashboardProgressView *progress; 16 | @property (nonatomic, weak) IBOutlet UILabel *progressLabel; 17 | 18 | 19 | - (IBAction)addClick:(UIButton *)sender; 20 | 21 | @end 22 | 23 | @implementation ViewController 24 | 25 | - (void)viewDidLoad { 26 | [super viewDidLoad]; 27 | 28 | _progress = [[CLDashboardProgressView alloc] initWithFrame:CGRectMake(20, 60, 240, 240)]; 29 | _progress.center = CGPointMake([UIScreen mainScreen].bounds.size.width * 0.5, 190); 30 | _progress.backgroundColor = [UIColor blackColor]; 31 | 32 | _progress.outerRadius = 110; // 外圈半径 33 | _progress.innerRadius = 95; // 内圈半径 34 | _progress.beginAngle = 90; // 起始角度 35 | _progress.blockAngle = 8; // 每个进度块的角度 36 | _progress.gapAngle = 2; // 两个进度块的间隙的角度 37 | _progress.progressColor = [UIColor greenColor]; // 进度条填充色 38 | _progress.trackColor = [UIColor redColor]; // 进度条痕迹填充色 39 | _progress.outlineColor = [UIColor grayColor]; // 进度条边框颜色 40 | _progress.outlineWidth = 2; // 进度条边框线宽 41 | 42 | _progress.blockCount = 26; // 进度块的数量 43 | _progress.minValue = 0; // 进度条最小数值 44 | _progress.maxValue = 100; // 进度条最大数值 45 | _progress.currentValue = 10; // 进度条当前数值 46 | 47 | _progress.showShadow = YES; // 是否显示阴影 48 | _progress.shadowOuterRadius = 85; // 阴影外圈半径 49 | _progress.shadowInnerRadius = 10; // 阴影内圈半径 50 | _progress.shadowFillColor = [[UIColor grayColor] colorWithAlphaComponent:0.3]; // 阴影颜色 51 | 52 | _progress.autoAdjustAngle = YES; // 自动调整角度 53 | 54 | [self.view addSubview:_progress]; 55 | 56 | self.progressLabel.text = [NSString stringWithFormat:@"%.0f", _progress.currentValue]; 57 | } 58 | 59 | - (void)didReceiveMemoryWarning { 60 | [super didReceiveMemoryWarning]; 61 | // Dispose of any resources that can be recreated. 62 | } 63 | 64 | - (IBAction)addClick:(UIButton *)sender { 65 | 66 | CGFloat value = _progress.currentValue; 67 | _progress.currentValue = value + 5; 68 | self.progressLabel.text = [NSString stringWithFormat:@"%.0f", _progress.currentValue]; 69 | } 70 | @end 71 | -------------------------------------------------------------------------------- /CLDashboardProgressView/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // CLDashboardProgressView 4 | // 5 | // Created by 李辉 on 15/12/17. 6 | // Copyright © 2015年 李辉. 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 | -------------------------------------------------------------------------------- /Demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/changelee82/CLDashboardProgressView/a5f412d2a765ade5b7efb4bab534a421814f2821/Demo.gif -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CLDashboardProgressView 1.0 2 | 仪表盘样式的进度条 3 | 4 |
5 | 作者:李辉
6 | 联系方式:6545823@qq.com
7 | 编译环境:Xcode 7.2
8 | 运行环境:iOS 9.2 运行正常
9 | 您在使用该控件的过程中,如有任何疑问或建议,请通过邮箱联系我,谢谢!
10 | 11 |
12 | ![image](https://github.com/changelee82/CLDashboardProgressView/raw/master/Demo.gif) 13 |
14 | 15 | 使用方法 16 | =============== 17 | 可使用自动布局或代码添加该控件;
18 | _progress = [[CLDashboardProgressView alloc] initWithFrame:CGRectMake(20, 60, 240, 240)]; 19 | _progress.center = CGPointMake([UIScreen mainScreen].bounds.size.width * 0.5, 190); 20 | _progress.backgroundColor = [UIColor blackColor]; 21 | 22 | _progress.outerRadius = 110; // 外圈半径 23 | _progress.innerRadius = 95; // 内圈半径 24 | _progress.beginAngle = 90; // 起始角度 25 | _progress.blockAngle = 8; // 每个进度块的角度 26 | _progress.gapAngle = 2; // 两个进度块的间隙的角度 27 | _progress.progressColor = [UIColor greenColor]; // 进度条填充色 28 | _progress.trackColor = [UIColor redColor]; // 进度条痕迹填充色 29 | _progress.outlineColor = [UIColor grayColor]; // 进度条边框颜色 30 | _progress.outlineWidth = 2; // 进度条边框线宽 31 | 32 | _progress.blockCount = 26; // 进度块的数量 33 | _progress.minValue = 0; // 进度条最小数值 34 | _progress.maxValue = 100; // 进度条最大数值 35 | _progress.currentValue = 10; // 进度条当前数值 36 | 37 | _progress.showShadow = YES; // 是否显示阴影 38 | _progress.shadowOuterRadius = 85; // 阴影外圈半径 39 | _progress.shadowInnerRadius = 10; // 阴影内圈半径 40 | _progress.shadowFillColor = [[UIColor grayColor] colorWithAlphaComponent:0.3]; // 阴影颜色 41 | 42 | _progress.autoAdjustAngle = YES; // 自动调整角度,使开口向下 43 | 44 | [self.view addSubview:_progress]; 45 | 46 | 详细的示例请参考代码。
47 | 48 | 历史版本 49 | =============== 50 | v1.0 - 2015-12-18
51 | Added
52 | 基础功能完成
53 | --------------------------------------------------------------------------------