├── ClockView.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── liuyadi.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── liuyadi.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── ClockView.xcscheme │ └── xcschememanagement.plist ├── ClockView ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Info.plist ├── LightLoading │ ├── LightLoadingView.h │ └── LightLoadingView.m ├── ViewController.h ├── ViewController.m ├── YDSlider │ ├── YDSlider.h │ └── YDSlider.m └── main.m ├── ClockViewTests ├── ClockViewTests.m └── Info.plist ├── ClockViewUITests ├── ClockViewUITests.m └── Info.plist ├── README.md └── loading.gif /ClockView.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 5223B7151DDAB24000461828 /* YDSlider.m in Sources */ = {isa = PBXBuildFile; fileRef = 5223B7141DDAB24000461828 /* YDSlider.m */; }; 11 | 5295BA581DD42AF200841725 /* LightLoadingView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5295BA571DD42AF200841725 /* LightLoadingView.m */; }; 12 | 5297570A1DB4F249008B0E63 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 529757091DB4F249008B0E63 /* main.m */; }; 13 | 5297570D1DB4F249008B0E63 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5297570C1DB4F249008B0E63 /* AppDelegate.m */; }; 14 | 529757101DB4F249008B0E63 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5297570F1DB4F249008B0E63 /* ViewController.m */; }; 15 | 529757131DB4F249008B0E63 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 529757111DB4F249008B0E63 /* Main.storyboard */; }; 16 | 529757151DB4F249008B0E63 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 529757141DB4F249008B0E63 /* Assets.xcassets */; }; 17 | 529757181DB4F249008B0E63 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 529757161DB4F249008B0E63 /* LaunchScreen.storyboard */; }; 18 | 529757231DB4F249008B0E63 /* ClockViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 529757221DB4F249008B0E63 /* ClockViewTests.m */; }; 19 | 5297572E1DB4F249008B0E63 /* ClockViewUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5297572D1DB4F249008B0E63 /* ClockViewUITests.m */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXContainerItemProxy section */ 23 | 5297571F1DB4F249008B0E63 /* PBXContainerItemProxy */ = { 24 | isa = PBXContainerItemProxy; 25 | containerPortal = 529756FD1DB4F249008B0E63 /* Project object */; 26 | proxyType = 1; 27 | remoteGlobalIDString = 529757041DB4F249008B0E63; 28 | remoteInfo = ClockView; 29 | }; 30 | 5297572A1DB4F249008B0E63 /* PBXContainerItemProxy */ = { 31 | isa = PBXContainerItemProxy; 32 | containerPortal = 529756FD1DB4F249008B0E63 /* Project object */; 33 | proxyType = 1; 34 | remoteGlobalIDString = 529757041DB4F249008B0E63; 35 | remoteInfo = ClockView; 36 | }; 37 | /* End PBXContainerItemProxy section */ 38 | 39 | /* Begin PBXFileReference section */ 40 | 5223B7131DDAB24000461828 /* YDSlider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YDSlider.h; sourceTree = ""; }; 41 | 5223B7141DDAB24000461828 /* YDSlider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YDSlider.m; sourceTree = ""; }; 42 | 5295BA561DD42AF200841725 /* LightLoadingView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LightLoadingView.h; sourceTree = ""; }; 43 | 5295BA571DD42AF200841725 /* LightLoadingView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LightLoadingView.m; sourceTree = ""; }; 44 | 529757051DB4F249008B0E63 /* ClockView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ClockView.app; sourceTree = BUILT_PRODUCTS_DIR; }; 45 | 529757091DB4F249008B0E63 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 46 | 5297570B1DB4F249008B0E63 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 47 | 5297570C1DB4F249008B0E63 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 48 | 5297570E1DB4F249008B0E63 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 49 | 5297570F1DB4F249008B0E63 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 50 | 529757121DB4F249008B0E63 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 51 | 529757141DB4F249008B0E63 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 52 | 529757171DB4F249008B0E63 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 53 | 529757191DB4F249008B0E63 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 54 | 5297571E1DB4F249008B0E63 /* ClockViewTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ClockViewTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 55 | 529757221DB4F249008B0E63 /* ClockViewTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ClockViewTests.m; sourceTree = ""; }; 56 | 529757241DB4F249008B0E63 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 57 | 529757291DB4F249008B0E63 /* ClockViewUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ClockViewUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 58 | 5297572D1DB4F249008B0E63 /* ClockViewUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ClockViewUITests.m; sourceTree = ""; }; 59 | 5297572F1DB4F249008B0E63 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 60 | /* End PBXFileReference section */ 61 | 62 | /* Begin PBXFrameworksBuildPhase section */ 63 | 529757021DB4F249008B0E63 /* Frameworks */ = { 64 | isa = PBXFrameworksBuildPhase; 65 | buildActionMask = 2147483647; 66 | files = ( 67 | ); 68 | runOnlyForDeploymentPostprocessing = 0; 69 | }; 70 | 5297571B1DB4F249008B0E63 /* Frameworks */ = { 71 | isa = PBXFrameworksBuildPhase; 72 | buildActionMask = 2147483647; 73 | files = ( 74 | ); 75 | runOnlyForDeploymentPostprocessing = 0; 76 | }; 77 | 529757261DB4F249008B0E63 /* Frameworks */ = { 78 | isa = PBXFrameworksBuildPhase; 79 | buildActionMask = 2147483647; 80 | files = ( 81 | ); 82 | runOnlyForDeploymentPostprocessing = 0; 83 | }; 84 | /* End PBXFrameworksBuildPhase section */ 85 | 86 | /* Begin PBXGroup section */ 87 | 5223B7121DDAB24000461828 /* YDSlider */ = { 88 | isa = PBXGroup; 89 | children = ( 90 | 5223B7131DDAB24000461828 /* YDSlider.h */, 91 | 5223B7141DDAB24000461828 /* YDSlider.m */, 92 | ); 93 | path = YDSlider; 94 | sourceTree = ""; 95 | }; 96 | 5295BA551DD42AE200841725 /* LightLoading */ = { 97 | isa = PBXGroup; 98 | children = ( 99 | 5295BA561DD42AF200841725 /* LightLoadingView.h */, 100 | 5295BA571DD42AF200841725 /* LightLoadingView.m */, 101 | ); 102 | path = LightLoading; 103 | sourceTree = ""; 104 | }; 105 | 529756FC1DB4F249008B0E63 = { 106 | isa = PBXGroup; 107 | children = ( 108 | 529757071DB4F249008B0E63 /* ClockView */, 109 | 529757211DB4F249008B0E63 /* ClockViewTests */, 110 | 5297572C1DB4F249008B0E63 /* ClockViewUITests */, 111 | 529757061DB4F249008B0E63 /* Products */, 112 | ); 113 | sourceTree = ""; 114 | }; 115 | 529757061DB4F249008B0E63 /* Products */ = { 116 | isa = PBXGroup; 117 | children = ( 118 | 529757051DB4F249008B0E63 /* ClockView.app */, 119 | 5297571E1DB4F249008B0E63 /* ClockViewTests.xctest */, 120 | 529757291DB4F249008B0E63 /* ClockViewUITests.xctest */, 121 | ); 122 | name = Products; 123 | sourceTree = ""; 124 | }; 125 | 529757071DB4F249008B0E63 /* ClockView */ = { 126 | isa = PBXGroup; 127 | children = ( 128 | 5223B7121DDAB24000461828 /* YDSlider */, 129 | 5295BA551DD42AE200841725 /* LightLoading */, 130 | 5297570B1DB4F249008B0E63 /* AppDelegate.h */, 131 | 5297570C1DB4F249008B0E63 /* AppDelegate.m */, 132 | 5297570E1DB4F249008B0E63 /* ViewController.h */, 133 | 5297570F1DB4F249008B0E63 /* ViewController.m */, 134 | 529757111DB4F249008B0E63 /* Main.storyboard */, 135 | 529757141DB4F249008B0E63 /* Assets.xcassets */, 136 | 529757161DB4F249008B0E63 /* LaunchScreen.storyboard */, 137 | 529757191DB4F249008B0E63 /* Info.plist */, 138 | 529757081DB4F249008B0E63 /* Supporting Files */, 139 | ); 140 | path = ClockView; 141 | sourceTree = ""; 142 | }; 143 | 529757081DB4F249008B0E63 /* Supporting Files */ = { 144 | isa = PBXGroup; 145 | children = ( 146 | 529757091DB4F249008B0E63 /* main.m */, 147 | ); 148 | name = "Supporting Files"; 149 | sourceTree = ""; 150 | }; 151 | 529757211DB4F249008B0E63 /* ClockViewTests */ = { 152 | isa = PBXGroup; 153 | children = ( 154 | 529757221DB4F249008B0E63 /* ClockViewTests.m */, 155 | 529757241DB4F249008B0E63 /* Info.plist */, 156 | ); 157 | path = ClockViewTests; 158 | sourceTree = ""; 159 | }; 160 | 5297572C1DB4F249008B0E63 /* ClockViewUITests */ = { 161 | isa = PBXGroup; 162 | children = ( 163 | 5297572D1DB4F249008B0E63 /* ClockViewUITests.m */, 164 | 5297572F1DB4F249008B0E63 /* Info.plist */, 165 | ); 166 | path = ClockViewUITests; 167 | sourceTree = ""; 168 | }; 169 | /* End PBXGroup section */ 170 | 171 | /* Begin PBXNativeTarget section */ 172 | 529757041DB4F249008B0E63 /* ClockView */ = { 173 | isa = PBXNativeTarget; 174 | buildConfigurationList = 529757321DB4F249008B0E63 /* Build configuration list for PBXNativeTarget "ClockView" */; 175 | buildPhases = ( 176 | 529757011DB4F249008B0E63 /* Sources */, 177 | 529757021DB4F249008B0E63 /* Frameworks */, 178 | 529757031DB4F249008B0E63 /* Resources */, 179 | ); 180 | buildRules = ( 181 | ); 182 | dependencies = ( 183 | ); 184 | name = ClockView; 185 | productName = ClockView; 186 | productReference = 529757051DB4F249008B0E63 /* ClockView.app */; 187 | productType = "com.apple.product-type.application"; 188 | }; 189 | 5297571D1DB4F249008B0E63 /* ClockViewTests */ = { 190 | isa = PBXNativeTarget; 191 | buildConfigurationList = 529757351DB4F249008B0E63 /* Build configuration list for PBXNativeTarget "ClockViewTests" */; 192 | buildPhases = ( 193 | 5297571A1DB4F249008B0E63 /* Sources */, 194 | 5297571B1DB4F249008B0E63 /* Frameworks */, 195 | 5297571C1DB4F249008B0E63 /* Resources */, 196 | ); 197 | buildRules = ( 198 | ); 199 | dependencies = ( 200 | 529757201DB4F249008B0E63 /* PBXTargetDependency */, 201 | ); 202 | name = ClockViewTests; 203 | productName = ClockViewTests; 204 | productReference = 5297571E1DB4F249008B0E63 /* ClockViewTests.xctest */; 205 | productType = "com.apple.product-type.bundle.unit-test"; 206 | }; 207 | 529757281DB4F249008B0E63 /* ClockViewUITests */ = { 208 | isa = PBXNativeTarget; 209 | buildConfigurationList = 529757381DB4F249008B0E63 /* Build configuration list for PBXNativeTarget "ClockViewUITests" */; 210 | buildPhases = ( 211 | 529757251DB4F249008B0E63 /* Sources */, 212 | 529757261DB4F249008B0E63 /* Frameworks */, 213 | 529757271DB4F249008B0E63 /* Resources */, 214 | ); 215 | buildRules = ( 216 | ); 217 | dependencies = ( 218 | 5297572B1DB4F249008B0E63 /* PBXTargetDependency */, 219 | ); 220 | name = ClockViewUITests; 221 | productName = ClockViewUITests; 222 | productReference = 529757291DB4F249008B0E63 /* ClockViewUITests.xctest */; 223 | productType = "com.apple.product-type.bundle.ui-testing"; 224 | }; 225 | /* End PBXNativeTarget section */ 226 | 227 | /* Begin PBXProject section */ 228 | 529756FD1DB4F249008B0E63 /* Project object */ = { 229 | isa = PBXProject; 230 | attributes = { 231 | LastUpgradeCheck = 0800; 232 | ORGANIZATIONNAME = "Geek Zoo Studio"; 233 | TargetAttributes = { 234 | 529757041DB4F249008B0E63 = { 235 | CreatedOnToolsVersion = 8.0; 236 | ProvisioningStyle = Automatic; 237 | }; 238 | 5297571D1DB4F249008B0E63 = { 239 | CreatedOnToolsVersion = 8.0; 240 | ProvisioningStyle = Automatic; 241 | TestTargetID = 529757041DB4F249008B0E63; 242 | }; 243 | 529757281DB4F249008B0E63 = { 244 | CreatedOnToolsVersion = 8.0; 245 | ProvisioningStyle = Automatic; 246 | TestTargetID = 529757041DB4F249008B0E63; 247 | }; 248 | }; 249 | }; 250 | buildConfigurationList = 529757001DB4F249008B0E63 /* Build configuration list for PBXProject "ClockView" */; 251 | compatibilityVersion = "Xcode 3.2"; 252 | developmentRegion = English; 253 | hasScannedForEncodings = 0; 254 | knownRegions = ( 255 | en, 256 | Base, 257 | ); 258 | mainGroup = 529756FC1DB4F249008B0E63; 259 | productRefGroup = 529757061DB4F249008B0E63 /* Products */; 260 | projectDirPath = ""; 261 | projectRoot = ""; 262 | targets = ( 263 | 529757041DB4F249008B0E63 /* ClockView */, 264 | 5297571D1DB4F249008B0E63 /* ClockViewTests */, 265 | 529757281DB4F249008B0E63 /* ClockViewUITests */, 266 | ); 267 | }; 268 | /* End PBXProject section */ 269 | 270 | /* Begin PBXResourcesBuildPhase section */ 271 | 529757031DB4F249008B0E63 /* Resources */ = { 272 | isa = PBXResourcesBuildPhase; 273 | buildActionMask = 2147483647; 274 | files = ( 275 | 529757181DB4F249008B0E63 /* LaunchScreen.storyboard in Resources */, 276 | 529757151DB4F249008B0E63 /* Assets.xcassets in Resources */, 277 | 529757131DB4F249008B0E63 /* Main.storyboard in Resources */, 278 | ); 279 | runOnlyForDeploymentPostprocessing = 0; 280 | }; 281 | 5297571C1DB4F249008B0E63 /* Resources */ = { 282 | isa = PBXResourcesBuildPhase; 283 | buildActionMask = 2147483647; 284 | files = ( 285 | ); 286 | runOnlyForDeploymentPostprocessing = 0; 287 | }; 288 | 529757271DB4F249008B0E63 /* Resources */ = { 289 | isa = PBXResourcesBuildPhase; 290 | buildActionMask = 2147483647; 291 | files = ( 292 | ); 293 | runOnlyForDeploymentPostprocessing = 0; 294 | }; 295 | /* End PBXResourcesBuildPhase section */ 296 | 297 | /* Begin PBXSourcesBuildPhase section */ 298 | 529757011DB4F249008B0E63 /* Sources */ = { 299 | isa = PBXSourcesBuildPhase; 300 | buildActionMask = 2147483647; 301 | files = ( 302 | 529757101DB4F249008B0E63 /* ViewController.m in Sources */, 303 | 5297570D1DB4F249008B0E63 /* AppDelegate.m in Sources */, 304 | 5223B7151DDAB24000461828 /* YDSlider.m in Sources */, 305 | 5295BA581DD42AF200841725 /* LightLoadingView.m in Sources */, 306 | 5297570A1DB4F249008B0E63 /* main.m in Sources */, 307 | ); 308 | runOnlyForDeploymentPostprocessing = 0; 309 | }; 310 | 5297571A1DB4F249008B0E63 /* Sources */ = { 311 | isa = PBXSourcesBuildPhase; 312 | buildActionMask = 2147483647; 313 | files = ( 314 | 529757231DB4F249008B0E63 /* ClockViewTests.m in Sources */, 315 | ); 316 | runOnlyForDeploymentPostprocessing = 0; 317 | }; 318 | 529757251DB4F249008B0E63 /* Sources */ = { 319 | isa = PBXSourcesBuildPhase; 320 | buildActionMask = 2147483647; 321 | files = ( 322 | 5297572E1DB4F249008B0E63 /* ClockViewUITests.m in Sources */, 323 | ); 324 | runOnlyForDeploymentPostprocessing = 0; 325 | }; 326 | /* End PBXSourcesBuildPhase section */ 327 | 328 | /* Begin PBXTargetDependency section */ 329 | 529757201DB4F249008B0E63 /* PBXTargetDependency */ = { 330 | isa = PBXTargetDependency; 331 | target = 529757041DB4F249008B0E63 /* ClockView */; 332 | targetProxy = 5297571F1DB4F249008B0E63 /* PBXContainerItemProxy */; 333 | }; 334 | 5297572B1DB4F249008B0E63 /* PBXTargetDependency */ = { 335 | isa = PBXTargetDependency; 336 | target = 529757041DB4F249008B0E63 /* ClockView */; 337 | targetProxy = 5297572A1DB4F249008B0E63 /* PBXContainerItemProxy */; 338 | }; 339 | /* End PBXTargetDependency section */ 340 | 341 | /* Begin PBXVariantGroup section */ 342 | 529757111DB4F249008B0E63 /* Main.storyboard */ = { 343 | isa = PBXVariantGroup; 344 | children = ( 345 | 529757121DB4F249008B0E63 /* Base */, 346 | ); 347 | name = Main.storyboard; 348 | sourceTree = ""; 349 | }; 350 | 529757161DB4F249008B0E63 /* LaunchScreen.storyboard */ = { 351 | isa = PBXVariantGroup; 352 | children = ( 353 | 529757171DB4F249008B0E63 /* Base */, 354 | ); 355 | name = LaunchScreen.storyboard; 356 | sourceTree = ""; 357 | }; 358 | /* End PBXVariantGroup section */ 359 | 360 | /* Begin XCBuildConfiguration section */ 361 | 529757301DB4F249008B0E63 /* Debug */ = { 362 | isa = XCBuildConfiguration; 363 | buildSettings = { 364 | ALWAYS_SEARCH_USER_PATHS = NO; 365 | CLANG_ANALYZER_NONNULL = YES; 366 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 367 | CLANG_CXX_LIBRARY = "libc++"; 368 | CLANG_ENABLE_MODULES = YES; 369 | CLANG_ENABLE_OBJC_ARC = YES; 370 | CLANG_WARN_BOOL_CONVERSION = YES; 371 | CLANG_WARN_CONSTANT_CONVERSION = YES; 372 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 373 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 374 | CLANG_WARN_EMPTY_BODY = YES; 375 | CLANG_WARN_ENUM_CONVERSION = YES; 376 | CLANG_WARN_INFINITE_RECURSION = YES; 377 | CLANG_WARN_INT_CONVERSION = YES; 378 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 379 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 380 | CLANG_WARN_UNREACHABLE_CODE = YES; 381 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 382 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 383 | COPY_PHASE_STRIP = NO; 384 | DEBUG_INFORMATION_FORMAT = dwarf; 385 | ENABLE_STRICT_OBJC_MSGSEND = YES; 386 | ENABLE_TESTABILITY = YES; 387 | GCC_C_LANGUAGE_STANDARD = gnu99; 388 | GCC_DYNAMIC_NO_PIC = NO; 389 | GCC_NO_COMMON_BLOCKS = YES; 390 | GCC_OPTIMIZATION_LEVEL = 0; 391 | GCC_PREPROCESSOR_DEFINITIONS = ( 392 | "DEBUG=1", 393 | "$(inherited)", 394 | ); 395 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 396 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 397 | GCC_WARN_UNDECLARED_SELECTOR = YES; 398 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 399 | GCC_WARN_UNUSED_FUNCTION = YES; 400 | GCC_WARN_UNUSED_VARIABLE = YES; 401 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 402 | MTL_ENABLE_DEBUG_INFO = YES; 403 | ONLY_ACTIVE_ARCH = YES; 404 | SDKROOT = iphoneos; 405 | }; 406 | name = Debug; 407 | }; 408 | 529757311DB4F249008B0E63 /* Release */ = { 409 | isa = XCBuildConfiguration; 410 | buildSettings = { 411 | ALWAYS_SEARCH_USER_PATHS = NO; 412 | CLANG_ANALYZER_NONNULL = YES; 413 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 414 | CLANG_CXX_LIBRARY = "libc++"; 415 | CLANG_ENABLE_MODULES = YES; 416 | CLANG_ENABLE_OBJC_ARC = YES; 417 | CLANG_WARN_BOOL_CONVERSION = YES; 418 | CLANG_WARN_CONSTANT_CONVERSION = YES; 419 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 420 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 421 | CLANG_WARN_EMPTY_BODY = YES; 422 | CLANG_WARN_ENUM_CONVERSION = YES; 423 | CLANG_WARN_INFINITE_RECURSION = YES; 424 | CLANG_WARN_INT_CONVERSION = YES; 425 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 426 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 427 | CLANG_WARN_UNREACHABLE_CODE = YES; 428 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 429 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 430 | COPY_PHASE_STRIP = NO; 431 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 432 | ENABLE_NS_ASSERTIONS = NO; 433 | ENABLE_STRICT_OBJC_MSGSEND = YES; 434 | GCC_C_LANGUAGE_STANDARD = gnu99; 435 | GCC_NO_COMMON_BLOCKS = YES; 436 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 437 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 438 | GCC_WARN_UNDECLARED_SELECTOR = YES; 439 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 440 | GCC_WARN_UNUSED_FUNCTION = YES; 441 | GCC_WARN_UNUSED_VARIABLE = YES; 442 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 443 | MTL_ENABLE_DEBUG_INFO = NO; 444 | SDKROOT = iphoneos; 445 | VALIDATE_PRODUCT = YES; 446 | }; 447 | name = Release; 448 | }; 449 | 529757331DB4F249008B0E63 /* Debug */ = { 450 | isa = XCBuildConfiguration; 451 | buildSettings = { 452 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 453 | INFOPLIST_FILE = ClockView/Info.plist; 454 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 455 | PRODUCT_BUNDLE_IDENTIFIER = "Geek-Zoo-Studio.ClockView"; 456 | PRODUCT_NAME = "$(TARGET_NAME)"; 457 | }; 458 | name = Debug; 459 | }; 460 | 529757341DB4F249008B0E63 /* Release */ = { 461 | isa = XCBuildConfiguration; 462 | buildSettings = { 463 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 464 | INFOPLIST_FILE = ClockView/Info.plist; 465 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 466 | PRODUCT_BUNDLE_IDENTIFIER = "Geek-Zoo-Studio.ClockView"; 467 | PRODUCT_NAME = "$(TARGET_NAME)"; 468 | }; 469 | name = Release; 470 | }; 471 | 529757361DB4F249008B0E63 /* Debug */ = { 472 | isa = XCBuildConfiguration; 473 | buildSettings = { 474 | BUNDLE_LOADER = "$(TEST_HOST)"; 475 | INFOPLIST_FILE = ClockViewTests/Info.plist; 476 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 477 | PRODUCT_BUNDLE_IDENTIFIER = "Geek-Zoo-Studio.ClockViewTests"; 478 | PRODUCT_NAME = "$(TARGET_NAME)"; 479 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ClockView.app/ClockView"; 480 | }; 481 | name = Debug; 482 | }; 483 | 529757371DB4F249008B0E63 /* Release */ = { 484 | isa = XCBuildConfiguration; 485 | buildSettings = { 486 | BUNDLE_LOADER = "$(TEST_HOST)"; 487 | INFOPLIST_FILE = ClockViewTests/Info.plist; 488 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 489 | PRODUCT_BUNDLE_IDENTIFIER = "Geek-Zoo-Studio.ClockViewTests"; 490 | PRODUCT_NAME = "$(TARGET_NAME)"; 491 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ClockView.app/ClockView"; 492 | }; 493 | name = Release; 494 | }; 495 | 529757391DB4F249008B0E63 /* Debug */ = { 496 | isa = XCBuildConfiguration; 497 | buildSettings = { 498 | INFOPLIST_FILE = ClockViewUITests/Info.plist; 499 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 500 | PRODUCT_BUNDLE_IDENTIFIER = "Geek-Zoo-Studio.ClockViewUITests"; 501 | PRODUCT_NAME = "$(TARGET_NAME)"; 502 | TEST_TARGET_NAME = ClockView; 503 | }; 504 | name = Debug; 505 | }; 506 | 5297573A1DB4F249008B0E63 /* Release */ = { 507 | isa = XCBuildConfiguration; 508 | buildSettings = { 509 | INFOPLIST_FILE = ClockViewUITests/Info.plist; 510 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 511 | PRODUCT_BUNDLE_IDENTIFIER = "Geek-Zoo-Studio.ClockViewUITests"; 512 | PRODUCT_NAME = "$(TARGET_NAME)"; 513 | TEST_TARGET_NAME = ClockView; 514 | }; 515 | name = Release; 516 | }; 517 | /* End XCBuildConfiguration section */ 518 | 519 | /* Begin XCConfigurationList section */ 520 | 529757001DB4F249008B0E63 /* Build configuration list for PBXProject "ClockView" */ = { 521 | isa = XCConfigurationList; 522 | buildConfigurations = ( 523 | 529757301DB4F249008B0E63 /* Debug */, 524 | 529757311DB4F249008B0E63 /* Release */, 525 | ); 526 | defaultConfigurationIsVisible = 0; 527 | defaultConfigurationName = Release; 528 | }; 529 | 529757321DB4F249008B0E63 /* Build configuration list for PBXNativeTarget "ClockView" */ = { 530 | isa = XCConfigurationList; 531 | buildConfigurations = ( 532 | 529757331DB4F249008B0E63 /* Debug */, 533 | 529757341DB4F249008B0E63 /* Release */, 534 | ); 535 | defaultConfigurationIsVisible = 0; 536 | defaultConfigurationName = Release; 537 | }; 538 | 529757351DB4F249008B0E63 /* Build configuration list for PBXNativeTarget "ClockViewTests" */ = { 539 | isa = XCConfigurationList; 540 | buildConfigurations = ( 541 | 529757361DB4F249008B0E63 /* Debug */, 542 | 529757371DB4F249008B0E63 /* Release */, 543 | ); 544 | defaultConfigurationIsVisible = 0; 545 | defaultConfigurationName = Release; 546 | }; 547 | 529757381DB4F249008B0E63 /* Build configuration list for PBXNativeTarget "ClockViewUITests" */ = { 548 | isa = XCConfigurationList; 549 | buildConfigurations = ( 550 | 529757391DB4F249008B0E63 /* Debug */, 551 | 5297573A1DB4F249008B0E63 /* Release */, 552 | ); 553 | defaultConfigurationIsVisible = 0; 554 | defaultConfigurationName = Release; 555 | }; 556 | /* End XCConfigurationList section */ 557 | }; 558 | rootObject = 529756FD1DB4F249008B0E63 /* Project object */; 559 | } 560 | -------------------------------------------------------------------------------- /ClockView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ClockView.xcodeproj/project.xcworkspace/xcuserdata/liuyadi.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yadea-Web/ClockView/bae58f75458f586968b4a14549dd00743b481970/ClockView.xcodeproj/project.xcworkspace/xcuserdata/liuyadi.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /ClockView.xcodeproj/xcuserdata/liuyadi.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /ClockView.xcodeproj/xcuserdata/liuyadi.xcuserdatad/xcschemes/ClockView.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 74 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /ClockView.xcodeproj/xcuserdata/liuyadi.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | ClockView.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 529757041DB4F249008B0E63 16 | 17 | primary 18 | 19 | 20 | 5297571D1DB4F249008B0E63 21 | 22 | primary 23 | 24 | 25 | 529757281DB4F249008B0E63 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /ClockView/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // ClockView 4 | // 5 | // Created by liuyadi on 2016/10/17. 6 | // Copyright © 2016年 Geek Zoo Studio. 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 | -------------------------------------------------------------------------------- /ClockView/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // ClockView 4 | // 5 | // Created by liuyadi on 2016/10/17. 6 | // Copyright © 2016年 Geek Zoo Studio. 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 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // 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. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // 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. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // 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. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /ClockView/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 | } -------------------------------------------------------------------------------- /ClockView/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 | -------------------------------------------------------------------------------- /ClockView/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 | -------------------------------------------------------------------------------- /ClockView/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 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /ClockView/LightLoading/LightLoadingView.h: -------------------------------------------------------------------------------- 1 | // 2 | // LightLoadingView.h 3 | // ClockView 4 | // 5 | // Created by liuyadi on 2016/11/10. 6 | // Copyright © 2016年 Geek Zoo Studio. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface LightLoadingView : UIView 12 | 13 | /** 14 | 设置进度值的显示的字体大小 15 | */ 16 | @property (nonatomic, strong) UIFont *progressLabelFont; 17 | 18 | /** 19 | @param frame 坐标 20 | @param tintColor 一般状态下的颜色 21 | @param selectedColor 经过的进度条的颜色 22 | @param value 进度条的初始值, 0 - 1之间 23 | @param animated 动画(是否有动画只能在初始化时指定) 24 | */ 25 | - (instancetype)initLightLoadingViewWithFrame:(CGRect)frame tintColor:(UIColor *)tintColor selectedColor:(UIColor *)selectedColor value:(CGFloat)value animated:(BOOL)animated; 26 | 27 | /** 28 | 设置进度条的值 29 | 30 | @param value 进度条的值 31 | */ 32 | - (void)setProgressValue:(CGFloat)value; 33 | 34 | /** 35 | 无限循环 36 | */ 37 | - (void)infineLoop; 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /ClockView/LightLoading/LightLoadingView.m: -------------------------------------------------------------------------------- 1 | // 2 | // LightLoadingView.m 3 | // ClockView 4 | // 5 | // Created by liuyadi on 2016/11/10. 6 | // Copyright © 2016年 Geek Zoo Studio. All rights reserved. 7 | // 8 | 9 | #import "LightLoadingView.h" 10 | 11 | #define kTimeDuration 5.0 12 | 13 | @interface LightLoadingView() 14 | 15 | @property (nonatomic, strong) UIColor *tintColor; 16 | @property (nonatomic, strong) UIColor *selectedColor; 17 | @property (nonatomic, assign) CGFloat selectedValue; 18 | 19 | @property (nonatomic, strong) CAShapeLayer *selectedCircleLayer; 20 | @property (nonatomic, strong) CAShapeLayer *selectedLightLayer; 21 | @property (nonatomic, strong) CAShapeLayer *pointLayer; 22 | 23 | @property (nonatomic, assign) BOOL animated; 24 | @property (nonatomic, assign) BOOL isInfineLoop; 25 | @property (nonatomic, assign) CGRect viewFrame; 26 | 27 | @property (nonatomic, strong) UILabel *progressLabel; 28 | 29 | @end 30 | 31 | @implementation LightLoadingView 32 | 33 | - (instancetype)initLightLoadingViewWithFrame:(CGRect)frame tintColor:(UIColor *)tintColor selectedColor:(UIColor *)selectedColor value:(CGFloat)value animated:(BOOL)animated { 34 | self = [super initWithFrame:frame]; 35 | if (self) { 36 | self.tintColor = tintColor; 37 | self.selectedColor = selectedColor; 38 | self.selectedValue = value; 39 | self.animated = animated; 40 | self.viewFrame = frame; 41 | } 42 | return self; 43 | } 44 | 45 | - (void)setProgressValue:(CGFloat)value { 46 | if (value == 0) { 47 | [self initLayerPath]; 48 | } else { 49 | // 里面圆的进度条 50 | [self setSelectedCircleWithValue:value preValue:self.selectedValue]; 51 | 52 | // 实际的散光的值 53 | [self setSelectedLightLineWithValue:value preValue:self.selectedValue]; 54 | 55 | // 带头的小圆点 56 | [self setSelectedPointWithValue:value preValue:self.selectedValue]; 57 | } 58 | 59 | self.selectedValue = value; 60 | } 61 | 62 | - (void)initLayerPath { 63 | self.selectedCircleLayer.path = nil; 64 | self.selectedLightLayer.path = nil; 65 | self.pointLayer.path = nil; 66 | [self setSelectedPointWithValue:0 preValue:0]; 67 | } 68 | 69 | - (void)infineLoop { 70 | self.isInfineLoop = YES; 71 | [self setProgressValue:0.0]; 72 | [NSTimer scheduledTimerWithTimeInterval:kTimeDuration 73 | target:self 74 | selector:@selector(repeatLoading) 75 | userInfo:nil 76 | repeats:YES]; 77 | [self setProgressValue:1.0]; 78 | } 79 | 80 | - (void)repeatLoading { 81 | [self setProgressValue:0.0]; 82 | [self setProgressValue:1.0]; 83 | } 84 | 85 | #pragma mark - lazy load 86 | 87 | - (CAShapeLayer *)pointLayer { 88 | if (!_pointLayer) { 89 | _pointLayer = [[CAShapeLayer alloc] init]; 90 | _pointLayer.frame = self.bounds; 91 | _pointLayer.fillColor = self.selectedColor.CGColor; 92 | [self.layer addSublayer:_pointLayer]; 93 | } 94 | return _pointLayer; 95 | } 96 | 97 | - (CAShapeLayer *)selectedCircleLayer { 98 | if (!_selectedCircleLayer) { 99 | _selectedCircleLayer = [[CAShapeLayer alloc] init]; 100 | _selectedCircleLayer.frame = self.bounds; 101 | _selectedCircleLayer.fillColor = nil; 102 | _selectedCircleLayer.strokeColor = self.selectedColor.CGColor; 103 | [self.layer addSublayer:_selectedCircleLayer]; 104 | } 105 | return _selectedCircleLayer; 106 | } 107 | 108 | - (CAShapeLayer *)selectedLightLayer { 109 | if (!_selectedLightLayer) { 110 | _selectedLightLayer = [[CAShapeLayer alloc] init]; 111 | _selectedLightLayer.frame = self.bounds; 112 | _selectedLightLayer.fillColor = nil; 113 | _selectedLightLayer.strokeColor = self.selectedColor.CGColor; 114 | [self.layer addSublayer:_selectedLightLayer]; 115 | } 116 | return _selectedLightLayer; 117 | } 118 | 119 | - (UILabel *)progressLabel { 120 | if (!_progressLabel) { 121 | CGFloat radius = self.viewFrame.size.width / 2; 122 | _progressLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, radius, radius)]; 123 | _progressLabel.center = CGPointMake(radius, radius); 124 | _progressLabel.textColor = self.selectedColor; 125 | _progressLabel.textAlignment = NSTextAlignmentCenter; 126 | [self addSubview:_progressLabel]; 127 | } 128 | return _progressLabel; 129 | } 130 | 131 | - (void)setProgressLabelFont:(UIFont *)progressLabelFont { 132 | self.progressLabel.font = progressLabelFont; 133 | } 134 | 135 | - (void)drawRect:(CGRect)rect { 136 | [super drawRect:rect]; 137 | 138 | // 整个圆 139 | [self setNormalCircle]; 140 | 141 | // 里面圆的进度条 142 | [self setSelectedCircleWithValue:self.selectedValue preValue:0]; 143 | 144 | // 外面散光的那个 145 | [self setNormalLightLine]; 146 | 147 | // 实际的散光的值 148 | [self setSelectedLightLineWithValue:self.selectedValue preValue:0]; 149 | 150 | // 带头的小圆点 151 | [self setSelectedPointWithValue:self.selectedValue preValue:0]; 152 | } 153 | 154 | - (void)setNormalCircle { 155 | UIColor *color = self.tintColor; 156 | [color set]; //设置线条颜色 157 | 158 | CGFloat radius = self.viewFrame.size.width / 2; 159 | CGFloat point = self.viewFrame.size.width / 4; 160 | 161 | UIBezierPath *circlePath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(point, point, radius, radius)]; 162 | circlePath.lineWidth = 1.0; 163 | circlePath.lineCapStyle = kCGLineCapRound; //线条拐角 164 | circlePath.lineJoinStyle = kCGLineCapRound; //终点处理 165 | [circlePath stroke]; 166 | } 167 | 168 | - (void)setSelectedCircleWithValue:(CGFloat)value preValue:(CGFloat)preValue { 169 | 170 | CGFloat radius = self.viewFrame.size.width / 2; 171 | 172 | UIBezierPath *circlePath; 173 | 174 | if (self.animated) { 175 | // 有动画 176 | circlePath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(radius, radius) 177 | radius:radius/2 178 | startAngle:-M_PI_2 179 | endAngle:M_PI + M_PI_2 180 | clockwise:YES]; 181 | CABasicAnimation *strokeAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; 182 | strokeAnimation.fromValue = [NSNumber numberWithFloat:preValue]; 183 | strokeAnimation.toValue = [NSNumber numberWithFloat:value]; 184 | strokeAnimation.duration = kTimeDuration; 185 | strokeAnimation.beginTime = 0.0; 186 | strokeAnimation.fillMode = kCAFillModeForwards; 187 | strokeAnimation.removedOnCompletion = NO; 188 | [self.selectedCircleLayer addAnimation:strokeAnimation forKey:@"strokeEndAnimation"]; 189 | } else { 190 | CGFloat angle = value * 100 * 0.6 * 6 * M_PI / 180; 191 | circlePath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(radius, radius) 192 | radius:radius/2 193 | startAngle:-M_PI_2 194 | endAngle:-M_PI_2 + angle 195 | clockwise:YES]; 196 | } 197 | self.selectedCircleLayer.path = circlePath.CGPath; 198 | } 199 | 200 | - (UIBezierPath *)lightPathWithAngle:(CGFloat)angle { 201 | CGFloat radius = self.viewFrame.size.width / 2; 202 | CGFloat point = self.viewFrame.size.width / 4; 203 | 204 | UIBezierPath *path1 = [UIBezierPath bezierPath]; 205 | [path1 moveToPoint:CGPointMake(0, -radius + point - 10)]; 206 | [path1 addLineToPoint:CGPointMake(0, -radius + point - 20)]; 207 | path1.lineWidth = 1.0; 208 | path1.lineCapStyle = kCGLineCapRound; //线条拐角 209 | path1.lineJoinStyle = kCGLineCapRound; //终点处理 210 | [path1 applyTransform:CGAffineTransformMakeRotation(angle)]; 211 | [path1 applyTransform:CGAffineTransformMakeTranslation(radius, radius)]; 212 | 213 | return path1; 214 | } 215 | 216 | - (void)setNormalLightLine { 217 | UIColor *color = self.tintColor; 218 | [color set]; //设置线条颜色 219 | 220 | for (int i = 0; i < 60; i++) { 221 | CGFloat angle = i * 6 * M_PI / 180; 222 | UIBezierPath *path1 = [self lightPathWithAngle:angle]; 223 | [path1 stroke]; 224 | } 225 | } 226 | 227 | - (void)setSelectedLightLineWithValue:(CGFloat)value preValue:(CGFloat)preValue { 228 | UIBezierPath *path = [UIBezierPath bezierPath]; 229 | 230 | UIColor *color = self.selectedColor; 231 | [color set]; //设置线条颜色 232 | 233 | if (self.animated) { 234 | for (int i = 0; i < 60; i++) { 235 | CGFloat angle = i * 6 * M_PI / 180; 236 | UIBezierPath *path1 = [self lightPathWithAngle:angle]; 237 | [path appendPath:path1]; 238 | } 239 | 240 | // 有动画 241 | CABasicAnimation *strokeAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; 242 | strokeAnimation.fromValue = [NSNumber numberWithFloat:preValue]; 243 | strokeAnimation.toValue = [NSNumber numberWithFloat:value]; 244 | strokeAnimation.duration = kTimeDuration; 245 | strokeAnimation.beginTime = 0.0; 246 | strokeAnimation.fillMode = kCAFillModeForwards; 247 | strokeAnimation.removedOnCompletion = NO; 248 | [self.selectedLightLayer addAnimation:strokeAnimation forKey:@"strokeEndAnimation"]; 249 | } else { 250 | value = value * 100 * 0.6; 251 | for (int i = 0; i < value; i++) { 252 | CGFloat angle = i * 6 * M_PI / 180; 253 | UIBezierPath *path1 = [self lightPathWithAngle:angle]; 254 | [path appendPath:path1]; 255 | } 256 | } 257 | 258 | self.selectedLightLayer.path = path.CGPath; 259 | } 260 | 261 | - (void)setSelectedPointWithValue:(CGFloat)value preValue:(CGFloat)preValue { 262 | CGFloat angle = (value * 100 * 0.6) * 6 * M_PI / 180; 263 | CGFloat preAngle = (preValue * 100 * 0.6) * 6 * M_PI / 180; 264 | 265 | CGFloat radius = self.viewFrame.size.width / 2; 266 | CGFloat point = self.viewFrame.size.width / 4; 267 | 268 | UIBezierPath *pointPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(radius - 2, point - 2, 5, 5)]; 269 | pointPath.lineWidth = 1.0; 270 | 271 | if (self.animated) { 272 | // 有动画 273 | CABasicAnimation *zRotateAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; 274 | zRotateAnimation.fromValue = [NSNumber numberWithFloat:preAngle]; 275 | zRotateAnimation.toValue = [NSNumber numberWithFloat:angle]; 276 | zRotateAnimation.duration = kTimeDuration; 277 | zRotateAnimation.beginTime = 0.0; 278 | zRotateAnimation.fillMode = kCAFillModeForwards; 279 | zRotateAnimation.removedOnCompletion = NO; 280 | [self.pointLayer addAnimation:zRotateAnimation forKey:@"rotateAnimation"]; 281 | } else { 282 | [CATransaction begin]; 283 | [CATransaction setDisableActions:YES]; 284 | self.pointLayer.affineTransform = CGAffineTransformMakeRotation(angle); 285 | [CATransaction commit]; 286 | } 287 | self.pointLayer.path = pointPath.CGPath; 288 | if (!self.isInfineLoop) { 289 | self.progressLabel.text = [NSString stringWithFormat:@"%.0f", value * 100]; 290 | } 291 | } 292 | 293 | @end 294 | -------------------------------------------------------------------------------- /ClockView/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // ClockView 4 | // 5 | // Created by liuyadi on 2016/10/17. 6 | // Copyright © 2016年 Geek Zoo Studio. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /ClockView/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // ClockView 4 | // 5 | // Created by liuyadi on 2016/10/17. 6 | // Copyright © 2016年 Geek Zoo Studio. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "LightLoadingView.h" 11 | #import "YDSlider.h" 12 | 13 | @interface ViewController () 14 | 15 | @property (nonatomic, strong) LightLoadingView *lightLoading1; 16 | @property (nonatomic, strong) LightLoadingView *lightLoading2; 17 | @property (nonatomic, strong) LightLoadingView *lightLoading3; 18 | @property (nonatomic, strong) LightLoadingView *lightLoading4; 19 | 20 | @end 21 | 22 | @implementation ViewController 23 | 24 | - (void)viewDidLoad { 25 | [super viewDidLoad]; 26 | // Do any additional setup after loading the view, typically from a nib. 27 | 28 | [self.view addSubview:self.lightLoading1]; 29 | [self.view addSubview:self.lightLoading2]; 30 | [self.view addSubview:self.lightLoading3]; 31 | [self.view addSubview:self.lightLoading4]; 32 | [self.lightLoading4 infineLoop]; 33 | 34 | YDSlider *slider1 = [[YDSlider alloc] initWithFrame:CGRectMake(20, 350, 300, 40) indexLabelType:SLIDER_INDEX_TYPE_CENTER]; 35 | slider1.delegate = self; 36 | slider1.tag = 1; 37 | slider1.minimumValue = 0; 38 | slider1.maximumValue = 100; 39 | slider1.minimumTrackTintColor = [self colorWithRGBValue:0xC9E4DA]; 40 | slider1.maximumTrackTintColor = [self colorWithRGBValue:0x008C5E]; 41 | [self.view addSubview:slider1]; 42 | 43 | YDSlider *slider2 = [[YDSlider alloc] initWithFrame:CGRectMake(20, 400, 300, 40) indexLabelType:SLIDER_INDEX_TYPE_CENTER]; 44 | slider2.delegate = self; 45 | slider2.tag = 2; 46 | slider2.minimumValue = 0; 47 | slider2.maximumValue = 100; 48 | slider2.minimumTrackTintColor = [self colorWithRGBValue:0xBFCAE6]; 49 | slider2.maximumTrackTintColor = [self colorWithRGBValue:0x103667]; 50 | [self.view addSubview:slider2]; 51 | 52 | YDSlider *slider3 = [[YDSlider alloc] initWithFrame:CGRectMake(20, 450, 300, 40) indexLabelType:SLIDER_INDEX_TYPE_CENTER]; 53 | slider3.delegate = self; 54 | slider3.tag = 3; 55 | slider3.minimumValue = 0; 56 | slider3.maximumValue = 100; 57 | slider3.minimumTrackTintColor = [self colorWithRGBValue:0xFCD9C4]; 58 | slider3.maximumTrackTintColor = [self colorWithRGBValue:0x8E1E20]; 59 | [self.view addSubview:slider3]; 60 | 61 | UIButton *button1 = [[UIButton alloc] initWithFrame:CGRectMake(20, 500, 100, 50)]; 62 | [button1 setTitle:@"Loading1" forState:UIControlStateNormal]; 63 | [button1 setTitleColor:[self colorWithRGBValue:0x008C5E] forState:UIControlStateNormal]; 64 | [button1 setBackgroundColor:[self colorWithRGBValue:0xC9E4DA]]; 65 | [button1 addTarget:self action:@selector(changeProgressView1) forControlEvents:UIControlEventTouchUpInside]; 66 | button1.layer.cornerRadius = 4; 67 | button1.layer.masksToBounds = YES; 68 | [self.view addSubview:button1]; 69 | 70 | UIButton *button2 = [[UIButton alloc] initWithFrame:CGRectMake(130, 500, 100, 50)]; 71 | [button2 setTitle:@"Loading2" forState:UIControlStateNormal]; 72 | [button2 setTitleColor:[self colorWithRGBValue:0x103667] forState:UIControlStateNormal]; 73 | [button2 setBackgroundColor:[self colorWithRGBValue:0xBFCAE6]]; 74 | [button2 addTarget:self action:@selector(changeProgressView2) forControlEvents:UIControlEventTouchUpInside]; 75 | button2.layer.cornerRadius = 4; 76 | button2.layer.masksToBounds = YES; 77 | [self.view addSubview:button2]; 78 | 79 | UIButton *button3 = [[UIButton alloc] initWithFrame:CGRectMake(240, 500, 100, 50)]; 80 | [button3 setTitle:@"Loading3" forState:UIControlStateNormal]; 81 | [button3 setTitleColor:[self colorWithRGBValue:0x8E1E20] forState:UIControlStateNormal]; 82 | [button3 setBackgroundColor:[self colorWithRGBValue:0xFCD9C4]]; 83 | [button3 addTarget:self action:@selector(changeProgressView3) forControlEvents:UIControlEventTouchUpInside]; 84 | button3.layer.cornerRadius = 4; 85 | button3.layer.masksToBounds = YES; 86 | [self.view addSubview:button3]; 87 | } 88 | 89 | - (void)changeProgress { 90 | [self.lightLoading1 setProgressValue:0.8]; 91 | } 92 | 93 | - (LightLoadingView *)lightLoading1 { 94 | if (!_lightLoading1) { 95 | _lightLoading1 = [[LightLoadingView alloc] initLightLoadingViewWithFrame:CGRectMake(10, 10, 150, 150) tintColor:[self colorWithRGBValue:0xC9E4DA] selectedColor:[self colorWithRGBValue:0x008C5E] value:0.2 animated:NO]; 96 | _lightLoading1.backgroundColor = [UIColor whiteColor]; 97 | } 98 | return _lightLoading1; 99 | } 100 | 101 | - (LightLoadingView *)lightLoading2 { 102 | if (!_lightLoading2) { 103 | _lightLoading2 = [[LightLoadingView alloc] initLightLoadingViewWithFrame:CGRectMake(170, 10, 150, 150) tintColor:[self colorWithRGBValue:0xBFCAE6] selectedColor:[self colorWithRGBValue:0x103667] value:0.2 animated:YES]; 104 | _lightLoading2.backgroundColor = [UIColor whiteColor]; 105 | } 106 | return _lightLoading2; 107 | } 108 | 109 | - (LightLoadingView *)lightLoading3 { 110 | if (!_lightLoading3) { 111 | _lightLoading3= [[LightLoadingView alloc] initLightLoadingViewWithFrame:CGRectMake(10, 170, 100, 100) tintColor:[self colorWithRGBValue:0xFCD9C4] selectedColor:[self colorWithRGBValue:0x8E1E20] value:0.2 animated:YES]; 112 | _lightLoading3.backgroundColor = [UIColor whiteColor]; 113 | _lightLoading3.progressLabelFont = [UIFont systemFontOfSize:12]; 114 | } 115 | return _lightLoading3; 116 | } 117 | 118 | - (LightLoadingView *)lightLoading4 { 119 | if (!_lightLoading4) { 120 | _lightLoading4 = [[LightLoadingView alloc] initLightLoadingViewWithFrame:CGRectMake(170, 170, 200, 200) tintColor:[self colorWithRGBValue:0xE8D3E3] selectedColor:[self colorWithRGBValue:0x64004B] value:0.2 animated:YES]; 121 | _lightLoading4.backgroundColor = [UIColor whiteColor]; 122 | } 123 | return _lightLoading4; 124 | } 125 | 126 | - (UIColor *)colorWithRGBValue:(uint)value { 127 | uint r = (value & 0x00FF0000) >> 16; 128 | uint g = (value & 0x0000FF00) >> 8; 129 | uint b = (value & 0x000000FF); 130 | 131 | return [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1.0]; 132 | } 133 | 134 | #pragma mark - YDSliderDelegate 135 | 136 | - (void)sliderValueChanged:(YDSlider *)slider { 137 | CGFloat value = slider.value / 100; 138 | if (slider.tag == 1) { 139 | [self.lightLoading1 setProgressValue:value]; 140 | } else if (slider.tag == 2) { 141 | [self.lightLoading2 setProgressValue:value]; 142 | } else if (slider.tag == 3) { 143 | [self.lightLoading3 setProgressValue:value]; 144 | } 145 | } 146 | 147 | - (void)changeProgressView1 { 148 | [self.lightLoading1 setProgressValue:0.1]; 149 | } 150 | 151 | - (void)changeProgressView2 { 152 | [self.lightLoading2 setProgressValue:0.7]; 153 | } 154 | 155 | - (void)changeProgressView3 { 156 | [self.lightLoading3 setProgressValue:0.8]; 157 | } 158 | 159 | @end 160 | -------------------------------------------------------------------------------- /ClockView/YDSlider/YDSlider.h: -------------------------------------------------------------------------------- 1 | // 2 | // YDSlider.h 3 | // YDSliderView 4 | // 5 | // Created by liuyadi on 2016/11/14. 6 | // Copyright © 2016年 Geek Zoo Studio. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class YDSlider; 12 | 13 | typedef NS_ENUM(NSInteger, SLIDER_INDEX_TYPE) { 14 | SLIDER_INDEX_TYPE_CENTER, 15 | SLIDER_INDEX_TYPE_TOP, 16 | SLIDER_INDEX_TYPE_BOTTOM, 17 | }; 18 | 19 | @protocol YDSliderDelegate 20 | 21 | @optional 22 | - (void)sliderValueChanged:(YDSlider *)slider; 23 | 24 | @end 25 | 26 | @interface YDSlider : UIView 27 | 28 | - (instancetype)initWithFrame:(CGRect)frame indexLabelType:(SLIDER_INDEX_TYPE)type; 29 | @property (nonatomic, weak) id delegate; 30 | 31 | @property(nonatomic) float value; // default 0.0. this value will be pinned to min/max 32 | @property(nonatomic) float minimumValue; // default 0.0. the current value may change if outside new min value 33 | @property(nonatomic) float maximumValue; // default 1.0. the current value may change if outside new max value 34 | 35 | @property(nullable, nonatomic,strong) UIImage *minimumValueImage; // default is nil. image that appears to left of control (e.g. speaker off) 36 | @property(nullable, nonatomic,strong) UIImage *maximumValueImage; // default is nil. image that appears to right of control (e.g. speaker max) 37 | 38 | @property(nonatomic,getter=isContinuous) BOOL continuous; // if set, value change events are generated any time the value changes due to dragging. default = YES 39 | 40 | @property(nullable, nonatomic,strong) UIColor *minimumTrackTintColor NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR; 41 | @property(nullable, nonatomic,strong) UIColor *maximumTrackTintColor NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR; 42 | @property(nullable, nonatomic,strong) UIColor *thumbTintColor NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR; 43 | 44 | - (void)setValue:(float)value animated:(BOOL)animated; // move slider at fixed velocity (i.e. duration depends on distance). does not send action 45 | 46 | - (void)setThumbImage:(nullable UIImage *)image forState:(UIControlState)state; 47 | - (void)setMinimumTrackImage:(nullable UIImage *)image forState:(UIControlState)state; 48 | - (void)setMaximumTrackImage:(nullable UIImage *)image forState:(UIControlState)state; 49 | 50 | - (nullable UIImage *)thumbImageForState:(UIControlState)state; 51 | - (nullable UIImage *)minimumTrackImageForState:(UIControlState)state; 52 | - (nullable UIImage *)maximumTrackImageForState:(UIControlState)state; 53 | 54 | @property(nullable,nonatomic,readonly) UIImage *currentThumbImage; 55 | @property(nullable,nonatomic,readonly) UIImage *currentMinimumTrackImage; 56 | @property(nullable,nonatomic,readonly) UIImage *currentMaximumTrackImage; 57 | 58 | - (CGRect)minimumValueImageRectForBounds:(CGRect)bounds; 59 | - (CGRect)maximumValueImageRectForBounds:(CGRect)bounds; 60 | - (CGRect)trackRectForBounds:(CGRect)bounds; 61 | - (CGRect)thumbRectForBounds:(CGRect)bounds trackRect:(CGRect)rect value:(float)value; 62 | 63 | @end 64 | -------------------------------------------------------------------------------- /ClockView/YDSlider/YDSlider.m: -------------------------------------------------------------------------------- 1 | // 2 | // YDSlider.m 3 | // YDSliderView 4 | // 5 | // Created by liuyadi on 2016/11/14. 6 | // Copyright © 2016年 Geek Zoo Studio. All rights reserved. 7 | // 8 | 9 | #import "YDSlider.h" 10 | 11 | @interface YDSlider () 12 | 13 | @property (nonatomic, strong) UILabel *indexLabel; 14 | @property (nonatomic, strong) UISlider *slider; 15 | @property (nonatomic, assign) SLIDER_INDEX_TYPE type; 16 | 17 | @end 18 | 19 | @implementation YDSlider 20 | 21 | - (instancetype)initWithFrame:(CGRect)frame indexLabelType:(SLIDER_INDEX_TYPE)type { 22 | self = [super initWithFrame:frame]; 23 | if (self) { 24 | self.type = type; 25 | [self addSubview:self.slider]; 26 | [self addSubview:self.indexLabel]; 27 | } 28 | return self; 29 | } 30 | 31 | - (UISlider *)slider { 32 | if (!_slider) { 33 | _slider = [[UISlider alloc] initWithFrame:self.bounds]; 34 | [_slider addTarget:self action:@selector(sliderValueChanged:) forControlEvents:UIControlEventValueChanged]; 35 | } 36 | return _slider; 37 | } 38 | 39 | - (UILabel *)indexLabel { 40 | if (!_indexLabel) { 41 | _indexLabel = [[UILabel alloc] init]; 42 | _indexLabel.textColor = [UIColor blackColor]; 43 | _indexLabel.font = [UIFont systemFontOfSize:10]; 44 | _indexLabel.backgroundColor = [UIColor clearColor]; 45 | _indexLabel.textAlignment = NSTextAlignmentCenter; 46 | 47 | [self setIndexLabelFrame]; 48 | } 49 | return _indexLabel; 50 | } 51 | 52 | - (void)sliderValueChanged:(UISlider *)slider { 53 | [self setIndexLabelFrame]; 54 | if (self.delegate && [self.delegate respondsToSelector:@selector(sliderValueChanged:)]) { 55 | [self.delegate sliderValueChanged:self]; 56 | } 57 | } 58 | 59 | - (void)setIndexLabelFrame { 60 | CGRect trackRect = [self.slider trackRectForBounds:self.bounds]; 61 | CGRect thumbRect = [self.slider thumbRectForBounds:self.bounds 62 | trackRect:trackRect 63 | value:self.slider.value]; 64 | 65 | self.indexLabel.frame = CGRectMake(0, 0, thumbRect.size.width - 10, thumbRect.size.height - 10); 66 | if (self.type == SLIDER_INDEX_TYPE_CENTER) { 67 | self.indexLabel.center = CGPointMake(thumbRect.origin.x + (thumbRect.size.width / 2), thumbRect.origin.y + (thumbRect.size.height / 2)); 68 | } else if (self.type == SLIDER_INDEX_TYPE_TOP) { 69 | self.indexLabel.center = CGPointMake(thumbRect.origin.x + (thumbRect.size.width / 2), thumbRect.origin.y - 15); 70 | } else if (self.type == SLIDER_INDEX_TYPE_BOTTOM) { 71 | self.indexLabel.center = CGPointMake(thumbRect.origin.x + (thumbRect.size.width / 2), thumbRect.origin.y +thumbRect.size.height + 15); 72 | } 73 | 74 | self.indexLabel.text = [NSString stringWithFormat:@"%.0f", self.slider.value]; 75 | } 76 | 77 | #pragma UISlider 78 | 79 | - (float)value { 80 | return self.slider.value; 81 | } 82 | 83 | - (float)minimumValue { 84 | return self.slider.minimumValue; 85 | } 86 | 87 | - (float)maximumValue { 88 | return self.slider.maximumValue; 89 | } 90 | 91 | - (void)setValue:(float)value { 92 | self.slider.value = value; 93 | } 94 | 95 | - (void)setMinimumValue:(float)minimumValue { 96 | self.slider.minimumValue = minimumValue; 97 | } 98 | 99 | - (void)setMaximumValue:(float)maximumValue { 100 | self.slider.maximumValue = maximumValue; 101 | } 102 | 103 | - (UIImage *)minimumValueImage { 104 | return self.slider.minimumValueImage; 105 | } 106 | 107 | - (UIImage *)maximumValueImage { 108 | return self.slider.maximumValueImage; 109 | } 110 | 111 | - (void)setMinimumValueImage:(UIImage *)minimumValueImage { 112 | self.slider.minimumValueImage = minimumValueImage; 113 | } 114 | 115 | - (void)setMaximumValueImage:(UIImage *)maximumValueImage { 116 | self.slider.maximumValueImage = maximumValueImage; 117 | } 118 | 119 | - (BOOL)isContinuous { 120 | return self.slider.isContinuous; 121 | } 122 | 123 | - (void)setContinuous:(BOOL)continuous { 124 | self.slider.continuous = continuous; 125 | } 126 | 127 | - (UIColor *)minimumTrackTintColor { 128 | return self.slider.minimumTrackTintColor; 129 | } 130 | 131 | - (UIColor *)maximumTrackTintColor { 132 | return self.slider.maximumTrackTintColor; 133 | } 134 | 135 | - (UIColor *)thumbTintColor { 136 | return self.slider.thumbTintColor; 137 | } 138 | 139 | - (void)setMinimumTrackTintColor:(UIColor *)minimumTrackTintColor { 140 | self.slider.minimumTrackTintColor = minimumTrackTintColor; 141 | } 142 | 143 | - (void)setMaximumTrackTintColor:(UIColor *)maximumTrackTintColor { 144 | self.slider.maximumTrackTintColor = maximumTrackTintColor; 145 | } 146 | 147 | - (void)setThumbTintColor:(UIColor *)thumbTintColor { 148 | self.slider.thumbTintColor = thumbTintColor; 149 | } 150 | 151 | - (void)setValue:(float)value animated:(BOOL)animated { 152 | [self.slider setValue:value animated:animated]; 153 | } 154 | 155 | - (void)setThumbImage:(nullable UIImage *)image forState:(UIControlState)state { 156 | [self.slider setThumbImage:image forState:state]; 157 | } 158 | 159 | - (void)setMinimumTrackImage:(nullable UIImage *)image forState:(UIControlState)state { 160 | [self.slider setMinimumTrackImage:image forState:state]; 161 | } 162 | 163 | - (void)setMaximumTrackImage:(nullable UIImage *)image forState:(UIControlState)state { 164 | [self.slider setMaximumTrackImage:image forState:state]; 165 | } 166 | 167 | - (nullable UIImage *)thumbImageForState:(UIControlState)state { 168 | return [self.slider thumbImageForState:state]; 169 | } 170 | 171 | - (nullable UIImage *)minimumTrackImageForState:(UIControlState)state { 172 | return [self.slider minimumTrackImageForState:state]; 173 | } 174 | 175 | - (nullable UIImage *)maximumTrackImageForState:(UIControlState)state { 176 | return [self.slider maximumTrackImageForState:state]; 177 | } 178 | 179 | - (UIImage *)currentThumbImage { 180 | return self.slider.currentThumbImage; 181 | } 182 | 183 | - (UIImage *)currentMinimumTrackImage { 184 | return self.slider.currentMinimumTrackImage; 185 | } 186 | 187 | - (UIImage *)currentMaximumTrackImage { 188 | return self.slider.currentMaximumTrackImage; 189 | } 190 | 191 | - (CGRect)minimumValueImageRectForBounds:(CGRect)bounds { 192 | return [self.slider minimumValueImageRectForBounds:bounds]; 193 | } 194 | 195 | - (CGRect)maximumValueImageRectForBounds:(CGRect)bounds { 196 | return [self.slider maximumValueImageRectForBounds:bounds]; 197 | } 198 | 199 | - (CGRect)trackRectForBounds:(CGRect)bounds { 200 | return [self.slider trackRectForBounds:bounds]; 201 | } 202 | 203 | - (CGRect)thumbRectForBounds:(CGRect)bounds trackRect:(CGRect)rect value:(float)value { 204 | return [self.slider thumbRectForBounds:bounds trackRect:rect value:value]; 205 | } 206 | 207 | @end 208 | -------------------------------------------------------------------------------- /ClockView/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // ClockView 4 | // 5 | // Created by liuyadi on 2016/10/17. 6 | // Copyright © 2016年 Geek Zoo Studio. 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 | -------------------------------------------------------------------------------- /ClockViewTests/ClockViewTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // ClockViewTests.m 3 | // ClockViewTests 4 | // 5 | // Created by liuyadi on 2016/10/17. 6 | // Copyright © 2016年 Geek Zoo Studio. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ClockViewTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation ClockViewTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /ClockViewTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /ClockViewUITests/ClockViewUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // ClockViewUITests.m 3 | // ClockViewUITests 4 | // 5 | // Created by liuyadi on 2016/10/17. 6 | // Copyright © 2016年 Geek Zoo Studio. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ClockViewUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation ClockViewUITests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | 22 | // In UI tests it is usually best to stop immediately when a failure occurs. 23 | self.continueAfterFailure = NO; 24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 25 | [[[XCUIApplication alloc] init] launch]; 26 | 27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 28 | } 29 | 30 | - (void)tearDown { 31 | // Put teardown code here. This method is called after the invocation of each test method in the class. 32 | [super tearDown]; 33 | } 34 | 35 | - (void)testExample { 36 | // Use recording to get started writing UI tests. 37 | // Use XCTAssert and related functions to verify your tests produce the correct results. 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /ClockViewUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## ClockView 2 | 3 | 4 | ### Description 5 | 6 | * 像太阳光一样散光的进度条,用UIBezierPath画的 7 | 8 | ### Demo 9 | 10 | ![](https://github.com/miss-yadi/ClockView/blob/master/loading.gif) 11 | 12 | ### Usage 13 | #### 初始化:设置frame,默认颜色、选中颜色、初始值、是否有动画 14 | 15 | LightLoadingView *lightLoading1 = [[LightLoadingView alloc] initLightLoadingViewWithFrame:CGRectMake(10, 10, 150, 150) tintColor:[self colorWithRGBValue:0xC9E4DA] selectedColor:[self colorWithRGBValue:0x008C5E] value:0.2 animated:YES]; 16 | 17 | #### 如果想一直循环转的话,就调用 18 | 19 | [self.lightLoading1 infineLoop]; 20 | 21 | #### 设置进度条的值,0-1之间 22 | 23 | [self.lightLoading1 setProgressValue:0.8]; -------------------------------------------------------------------------------- /loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yadea-Web/ClockView/bae58f75458f586968b4a14549dd00743b481970/loading.gif --------------------------------------------------------------------------------