├── .gitignore ├── .travis.yml ├── Example ├── Classes │ ├── LLAAppDelegate.h │ ├── LLAAppDelegate.m │ ├── LLAExampleViewController.h │ └── LLAExampleViewController.m ├── Other Sources │ ├── LLACircularProgressView-Prefix.pch │ └── main.m └── Resources │ └── LLACircularProgressView-Info.plist ├── LICENSE ├── LLACircularProgressView.podspec ├── LLACircularProgressView.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcshareddata │ └── xcschemes │ └── LLACircularProgressView.xcscheme ├── LLACircularProgressView.xcworkspace └── contents.xcworkspacedata ├── LLACircularProgressView ├── LLACircularProgressView.h └── LLACircularProgressView.m ├── Podfile ├── README.md ├── Rakefile └── Tests ├── LLACircularProgressViewTests.m ├── ReferenceImages └── LLACircularProgressViewSpec │ └── should_fit_in_bounds@2x.png ├── Tests-Info.plist └── Tests-Prefix.pch /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | .DS_Store 3 | */build/* 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | profile 14 | *.moved-aside 15 | DerivedData 16 | .idea/ 17 | *.hmap 18 | *.swp 19 | *.lock 20 | *.xccheckout 21 | ./*.xcworkspace 22 | 23 | #CocoaPods 24 | Pods 25 | Podfile.lock 26 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | before_install: 3 | - brew update 4 | - brew uninstall xctool 5 | - brew install xctool 6 | - export LANG=en_US.UTF-8 7 | - gem i cocoapods --no-ri --no-rdoc 8 | xcode_workspace: LLACircularProgressView.xcworkspace 9 | xcode_scheme: LLACircularProgressView 10 | xcode_sdk: iphonesimulator 11 | -------------------------------------------------------------------------------- /Example/Classes/LLAAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // LLAAppDelegate.h 3 | // LLACircularProgressView 4 | // 5 | // Created by Lukas Lipka on 26/10/13. 6 | // Copyright (c) 2013 Lukas Lipka. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface LLAAppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Example/Classes/LLAAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // LLAAppDelegate.m 3 | // LLACircularProgressView 4 | // 5 | // Created by Lukas Lipka on 26/10/13. 6 | // Copyright (c) 2013 Lukas Lipka. All rights reserved. 7 | // 8 | 9 | #import "LLAAppDelegate.h" 10 | #import "LLAExampleViewController.h" 11 | 12 | @implementation LLAAppDelegate 13 | 14 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 15 | { 16 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 17 | self.window.rootViewController = [[LLAExampleViewController alloc] init]; 18 | self.window.backgroundColor = [UIColor whiteColor]; 19 | //self.window.tintColor = [UIColor redColor]; 20 | [self.window makeKeyAndVisible]; 21 | return YES; 22 | } 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application 25 | { 26 | // 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. 27 | // 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. 28 | } 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application 31 | { 32 | // 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. 33 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 34 | } 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application 37 | { 38 | // 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. 39 | } 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application 42 | { 43 | // 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. 44 | } 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application 47 | { 48 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 49 | } 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /Example/Classes/LLAExampleViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // LLAExampleViewController.h 3 | // LLACircularProgressView 4 | // 5 | // Created by Lukas Lipka on 26/10/13. 6 | // Copyright (c) 2013 Lukas Lipka. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface LLAExampleViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/Classes/LLAExampleViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // LLAExampleViewController.m 3 | // LLACircularProgressView 4 | // 5 | // Created by Lukas Lipka on 26/10/13. 6 | // Copyright (c) 2013 Lukas Lipka. All rights reserved. 7 | // 8 | 9 | #import "LLAExampleViewController.h" 10 | #import "LLACircularProgressView.h" 11 | 12 | @interface LLAExampleViewController () 13 | 14 | @property (nonatomic, strong) LLACircularProgressView *circularProgressView; 15 | 16 | @end 17 | 18 | @implementation LLAExampleViewController { 19 | NSTimer *_timer; 20 | } 21 | 22 | - (void)viewDidLoad { 23 | [super viewDidLoad]; 24 | 25 | self.circularProgressView = [[LLACircularProgressView alloc] init]; 26 | self.circularProgressView.frame = CGRectMake(0, 0, 30, 30); 27 | self.circularProgressView.center = CGPointMake(CGRectGetMidX(self.view.bounds), 50); 28 | [self.circularProgressView addTarget:self action:@selector(stop:) forControlEvents:UIControlEventTouchUpInside]; 29 | [self.view addSubview:self.circularProgressView]; 30 | 31 | _timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(tick:) userInfo:nil repeats:YES]; 32 | } 33 | 34 | - (void)tick:(NSTimer *)timer { 35 | CGFloat progress = self.circularProgressView.progress; 36 | [self.circularProgressView setProgress:(progress <= 1.00f ? progress + 0.1f : 0.0f) animated:YES]; 37 | } 38 | 39 | - (void)stop:(id)sender { 40 | [_timer invalidate]; 41 | 42 | UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"LLACircularProgressView" message:@"Yep, it's done. Check the dimmed colors effect." delegate:nil cancelButtonTitle:@"Done" otherButtonTitles:nil]; 43 | [alertView show]; 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /Example/Other Sources/LLACircularProgressView-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_3_0 10 | #warning "This project uses features only available in iOS SDK 3.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | #import 16 | #endif 17 | -------------------------------------------------------------------------------- /Example/Other Sources/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // LLACircularProgressView 4 | // 5 | // Created by Lukas Lipka on 26/10/13. 6 | // Copyright (c) 2013 Lukas Lipka. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "LLAAppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([LLAAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Example/Resources/LLACircularProgressView-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | com.lukaslipka.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Lukas Lipka 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /LLACircularProgressView.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "LLACircularProgressView" 3 | s.version = "0.1.1" 4 | s.homepage = "https://github.com/lipka/LLACircularProgressView" 5 | s.summary = "An animated ring spinner view for displaying indeterminate progress." 6 | s.source = { :git => "https://github.com/lipka/LLACircularProgressView.git", :tag => s.version.to_s } 7 | s.license = { :type => 'MIT', :file => 'LICENSE' } 8 | s.author = { "Lukas Lipka" => "lukaslipka@gmail.com" } 9 | s.social_media_url = "http://twitter.com/lipec" 10 | 11 | s.platform = :ios, '7.0' 12 | s.frameworks = 'UIKit', 'CoreGraphics' 13 | s.requires_arc = true 14 | 15 | s.source_files = 'LLACircularProgressView' 16 | end 17 | -------------------------------------------------------------------------------- /LLACircularProgressView.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0AD90550626448ED8ED94EC1 /* libPods-LLACircularProgressView.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EB4EAA7215C943708C46DF64 /* libPods-LLACircularProgressView.a */; }; 11 | 3309952F1994B9F100051263 /* Tests-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3309952D1994B9F100051263 /* Tests-Info.plist */; }; 12 | 330995321994BA1400051263 /* LLACircularProgressViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3309952E1994B9F100051263 /* LLACircularProgressViewTests.m */; }; 13 | 33C870ED181BCA9B00523CAE /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33C870EC181BCA9B00523CAE /* Foundation.framework */; }; 14 | 33C870EF181BCA9B00523CAE /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33C870EE181BCA9B00523CAE /* CoreGraphics.framework */; }; 15 | 33C870F1181BCA9B00523CAE /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33C870F0181BCA9B00523CAE /* UIKit.framework */; }; 16 | 33C87106181BCA9B00523CAE /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33C87105181BCA9B00523CAE /* XCTest.framework */; }; 17 | 33C87107181BCA9B00523CAE /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33C870EC181BCA9B00523CAE /* Foundation.framework */; }; 18 | 33C87108181BCA9B00523CAE /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33C870F0181BCA9B00523CAE /* UIKit.framework */; }; 19 | 33C87124181BCC6300523CAE /* LLAAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 33C8711E181BCC6300523CAE /* LLAAppDelegate.m */; }; 20 | 33C87125181BCC6300523CAE /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 33C87121181BCC6300523CAE /* main.m */; }; 21 | 33C8712D181BD1A000523CAE /* LLAExampleViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 33C8712C181BD1A000523CAE /* LLAExampleViewController.m */; }; 22 | 5AF51FDD58904B26B3C27FF0 /* libPods-Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7CD1DE80642A45ADB4A04B8D /* libPods-Tests.a */; }; 23 | /* End PBXBuildFile section */ 24 | 25 | /* Begin PBXContainerItemProxy section */ 26 | 33C87109181BCA9B00523CAE /* PBXContainerItemProxy */ = { 27 | isa = PBXContainerItemProxy; 28 | containerPortal = 33C870E1181BCA9B00523CAE /* Project object */; 29 | proxyType = 1; 30 | remoteGlobalIDString = 33C870E8181BCA9B00523CAE; 31 | remoteInfo = LLACircularProgressView; 32 | }; 33 | /* End PBXContainerItemProxy section */ 34 | 35 | /* Begin PBXFileReference section */ 36 | 06DDA7C7EA834A56885C1A19 /* Pods-Tests.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests.xcconfig"; path = "Pods/Pods-Tests.xcconfig"; sourceTree = ""; }; 37 | 3309952D1994B9F100051263 /* Tests-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Tests-Info.plist"; sourceTree = ""; }; 38 | 3309952E1994B9F100051263 /* LLACircularProgressViewTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LLACircularProgressViewTests.m; sourceTree = ""; }; 39 | 330995311994BA0700051263 /* Tests-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Tests-Prefix.pch"; sourceTree = ""; }; 40 | 33C870E9181BCA9B00523CAE /* LLACircularProgressView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LLACircularProgressView.app; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | 33C870EC181BCA9B00523CAE /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 42 | 33C870EE181BCA9B00523CAE /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 43 | 33C870F0181BCA9B00523CAE /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 44 | 33C87104181BCA9B00523CAE /* Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 45 | 33C87105181BCA9B00523CAE /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 46 | 33C8711D181BCC6300523CAE /* LLAAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LLAAppDelegate.h; sourceTree = ""; }; 47 | 33C8711E181BCC6300523CAE /* LLAAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LLAAppDelegate.m; sourceTree = ""; }; 48 | 33C87120181BCC6300523CAE /* LLACircularProgressView-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "LLACircularProgressView-Prefix.pch"; sourceTree = ""; }; 49 | 33C87121181BCC6300523CAE /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 50 | 33C87123181BCC6300523CAE /* LLACircularProgressView-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "LLACircularProgressView-Info.plist"; sourceTree = ""; }; 51 | 33C8712B181BD1A000523CAE /* LLAExampleViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LLAExampleViewController.h; sourceTree = ""; }; 52 | 33C8712C181BD1A000523CAE /* LLAExampleViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LLAExampleViewController.m; sourceTree = ""; }; 53 | 74C462436C7348AA82BAE298 /* Pods-LLACircularProgressView.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LLACircularProgressView.xcconfig"; path = "Pods/Pods-LLACircularProgressView.xcconfig"; sourceTree = ""; }; 54 | 7CD1DE80642A45ADB4A04B8D /* libPods-Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 55 | EB4EAA7215C943708C46DF64 /* libPods-LLACircularProgressView.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-LLACircularProgressView.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 56 | /* End PBXFileReference section */ 57 | 58 | /* Begin PBXFrameworksBuildPhase section */ 59 | 33C870E6181BCA9B00523CAE /* Frameworks */ = { 60 | isa = PBXFrameworksBuildPhase; 61 | buildActionMask = 2147483647; 62 | files = ( 63 | 33C870EF181BCA9B00523CAE /* CoreGraphics.framework in Frameworks */, 64 | 33C870F1181BCA9B00523CAE /* UIKit.framework in Frameworks */, 65 | 33C870ED181BCA9B00523CAE /* Foundation.framework in Frameworks */, 66 | 0AD90550626448ED8ED94EC1 /* libPods-LLACircularProgressView.a in Frameworks */, 67 | ); 68 | runOnlyForDeploymentPostprocessing = 0; 69 | }; 70 | 33C87101181BCA9B00523CAE /* Frameworks */ = { 71 | isa = PBXFrameworksBuildPhase; 72 | buildActionMask = 2147483647; 73 | files = ( 74 | 33C87106181BCA9B00523CAE /* XCTest.framework in Frameworks */, 75 | 33C87108181BCA9B00523CAE /* UIKit.framework in Frameworks */, 76 | 33C87107181BCA9B00523CAE /* Foundation.framework in Frameworks */, 77 | 5AF51FDD58904B26B3C27FF0 /* libPods-Tests.a in Frameworks */, 78 | ); 79 | runOnlyForDeploymentPostprocessing = 0; 80 | }; 81 | /* End PBXFrameworksBuildPhase section */ 82 | 83 | /* Begin PBXGroup section */ 84 | 3309952C1994B9F100051263 /* Tests */ = { 85 | isa = PBXGroup; 86 | children = ( 87 | 3309952D1994B9F100051263 /* Tests-Info.plist */, 88 | 3309952E1994B9F100051263 /* LLACircularProgressViewTests.m */, 89 | 330995311994BA0700051263 /* Tests-Prefix.pch */, 90 | ); 91 | path = Tests; 92 | sourceTree = ""; 93 | }; 94 | 33C870E0181BCA9B00523CAE = { 95 | isa = PBXGroup; 96 | children = ( 97 | 33C8711C181BCC6300523CAE /* Classes */, 98 | 33C8711F181BCC6300523CAE /* Other Sources */, 99 | 33C87122181BCC6300523CAE /* Resources */, 100 | 3309952C1994B9F100051263 /* Tests */, 101 | 33C870EB181BCA9B00523CAE /* Frameworks */, 102 | 33C870EA181BCA9B00523CAE /* Products */, 103 | 74C462436C7348AA82BAE298 /* Pods-LLACircularProgressView.xcconfig */, 104 | 06DDA7C7EA834A56885C1A19 /* Pods-Tests.xcconfig */, 105 | ); 106 | sourceTree = ""; 107 | }; 108 | 33C870EA181BCA9B00523CAE /* Products */ = { 109 | isa = PBXGroup; 110 | children = ( 111 | 33C870E9181BCA9B00523CAE /* LLACircularProgressView.app */, 112 | 33C87104181BCA9B00523CAE /* Tests.xctest */, 113 | ); 114 | name = Products; 115 | sourceTree = ""; 116 | }; 117 | 33C870EB181BCA9B00523CAE /* Frameworks */ = { 118 | isa = PBXGroup; 119 | children = ( 120 | 33C870EC181BCA9B00523CAE /* Foundation.framework */, 121 | 33C870EE181BCA9B00523CAE /* CoreGraphics.framework */, 122 | 33C870F0181BCA9B00523CAE /* UIKit.framework */, 123 | 33C87105181BCA9B00523CAE /* XCTest.framework */, 124 | EB4EAA7215C943708C46DF64 /* libPods-LLACircularProgressView.a */, 125 | 7CD1DE80642A45ADB4A04B8D /* libPods-Tests.a */, 126 | ); 127 | name = Frameworks; 128 | sourceTree = ""; 129 | }; 130 | 33C8711C181BCC6300523CAE /* Classes */ = { 131 | isa = PBXGroup; 132 | children = ( 133 | 33C8711D181BCC6300523CAE /* LLAAppDelegate.h */, 134 | 33C8711E181BCC6300523CAE /* LLAAppDelegate.m */, 135 | 33C8712B181BD1A000523CAE /* LLAExampleViewController.h */, 136 | 33C8712C181BD1A000523CAE /* LLAExampleViewController.m */, 137 | ); 138 | name = Classes; 139 | path = Example/Classes; 140 | sourceTree = ""; 141 | }; 142 | 33C8711F181BCC6300523CAE /* Other Sources */ = { 143 | isa = PBXGroup; 144 | children = ( 145 | 33C87120181BCC6300523CAE /* LLACircularProgressView-Prefix.pch */, 146 | 33C87121181BCC6300523CAE /* main.m */, 147 | ); 148 | name = "Other Sources"; 149 | path = "Example/Other Sources"; 150 | sourceTree = ""; 151 | }; 152 | 33C87122181BCC6300523CAE /* Resources */ = { 153 | isa = PBXGroup; 154 | children = ( 155 | 33C87123181BCC6300523CAE /* LLACircularProgressView-Info.plist */, 156 | ); 157 | name = Resources; 158 | path = Example/Resources; 159 | sourceTree = ""; 160 | }; 161 | /* End PBXGroup section */ 162 | 163 | /* Begin PBXNativeTarget section */ 164 | 33C870E8181BCA9B00523CAE /* LLACircularProgressView */ = { 165 | isa = PBXNativeTarget; 166 | buildConfigurationList = 33C87115181BCA9B00523CAE /* Build configuration list for PBXNativeTarget "LLACircularProgressView" */; 167 | buildPhases = ( 168 | AC34018F854C4821904EA188 /* Check Pods Manifest.lock */, 169 | 33C870E5181BCA9B00523CAE /* Sources */, 170 | 33C870E6181BCA9B00523CAE /* Frameworks */, 171 | 33C870E7181BCA9B00523CAE /* Resources */, 172 | A2D804BBEE2C4A7D97105503 /* Copy Pods Resources */, 173 | ); 174 | buildRules = ( 175 | ); 176 | dependencies = ( 177 | ); 178 | name = LLACircularProgressView; 179 | productName = LLACircularProgressView; 180 | productReference = 33C870E9181BCA9B00523CAE /* LLACircularProgressView.app */; 181 | productType = "com.apple.product-type.application"; 182 | }; 183 | 33C87103181BCA9B00523CAE /* Tests */ = { 184 | isa = PBXNativeTarget; 185 | buildConfigurationList = 33C87118181BCA9B00523CAE /* Build configuration list for PBXNativeTarget "Tests" */; 186 | buildPhases = ( 187 | 85DADFC1EF1347D9B0833F5F /* Check Pods Manifest.lock */, 188 | 33C87100181BCA9B00523CAE /* Sources */, 189 | 33C87101181BCA9B00523CAE /* Frameworks */, 190 | 33C87102181BCA9B00523CAE /* Resources */, 191 | 4E2CC9F2F4214814A92EBE09 /* Copy Pods Resources */, 192 | ); 193 | buildRules = ( 194 | ); 195 | dependencies = ( 196 | 33C8710A181BCA9B00523CAE /* PBXTargetDependency */, 197 | ); 198 | name = Tests; 199 | productName = LLACircularProgressViewTests; 200 | productReference = 33C87104181BCA9B00523CAE /* Tests.xctest */; 201 | productType = "com.apple.product-type.bundle.unit-test"; 202 | }; 203 | /* End PBXNativeTarget section */ 204 | 205 | /* Begin PBXProject section */ 206 | 33C870E1181BCA9B00523CAE /* Project object */ = { 207 | isa = PBXProject; 208 | attributes = { 209 | CLASSPREFIX = LLA; 210 | LastUpgradeCheck = 0510; 211 | ORGANIZATIONNAME = "Lukas Lipka"; 212 | TargetAttributes = { 213 | 33C87103181BCA9B00523CAE = { 214 | TestTargetID = 33C870E8181BCA9B00523CAE; 215 | }; 216 | }; 217 | }; 218 | buildConfigurationList = 33C870E4181BCA9B00523CAE /* Build configuration list for PBXProject "LLACircularProgressView" */; 219 | compatibilityVersion = "Xcode 3.2"; 220 | developmentRegion = English; 221 | hasScannedForEncodings = 0; 222 | knownRegions = ( 223 | en, 224 | ); 225 | mainGroup = 33C870E0181BCA9B00523CAE; 226 | productRefGroup = 33C870EA181BCA9B00523CAE /* Products */; 227 | projectDirPath = ""; 228 | projectRoot = ""; 229 | targets = ( 230 | 33C870E8181BCA9B00523CAE /* LLACircularProgressView */, 231 | 33C87103181BCA9B00523CAE /* Tests */, 232 | ); 233 | }; 234 | /* End PBXProject section */ 235 | 236 | /* Begin PBXResourcesBuildPhase section */ 237 | 33C870E7181BCA9B00523CAE /* Resources */ = { 238 | isa = PBXResourcesBuildPhase; 239 | buildActionMask = 2147483647; 240 | files = ( 241 | 3309952F1994B9F100051263 /* Tests-Info.plist in Resources */, 242 | ); 243 | runOnlyForDeploymentPostprocessing = 0; 244 | }; 245 | 33C87102181BCA9B00523CAE /* Resources */ = { 246 | isa = PBXResourcesBuildPhase; 247 | buildActionMask = 2147483647; 248 | files = ( 249 | ); 250 | runOnlyForDeploymentPostprocessing = 0; 251 | }; 252 | /* End PBXResourcesBuildPhase section */ 253 | 254 | /* Begin PBXShellScriptBuildPhase section */ 255 | 4E2CC9F2F4214814A92EBE09 /* Copy Pods Resources */ = { 256 | isa = PBXShellScriptBuildPhase; 257 | buildActionMask = 2147483647; 258 | files = ( 259 | ); 260 | inputPaths = ( 261 | ); 262 | name = "Copy Pods Resources"; 263 | outputPaths = ( 264 | ); 265 | runOnlyForDeploymentPostprocessing = 0; 266 | shellPath = /bin/sh; 267 | shellScript = "\"${SRCROOT}/Pods/Pods-Tests-resources.sh\"\n"; 268 | showEnvVarsInLog = 0; 269 | }; 270 | 85DADFC1EF1347D9B0833F5F /* Check Pods Manifest.lock */ = { 271 | isa = PBXShellScriptBuildPhase; 272 | buildActionMask = 2147483647; 273 | files = ( 274 | ); 275 | inputPaths = ( 276 | ); 277 | name = "Check Pods Manifest.lock"; 278 | outputPaths = ( 279 | ); 280 | runOnlyForDeploymentPostprocessing = 0; 281 | shellPath = /bin/sh; 282 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; 283 | showEnvVarsInLog = 0; 284 | }; 285 | A2D804BBEE2C4A7D97105503 /* Copy Pods Resources */ = { 286 | isa = PBXShellScriptBuildPhase; 287 | buildActionMask = 2147483647; 288 | files = ( 289 | ); 290 | inputPaths = ( 291 | ); 292 | name = "Copy Pods Resources"; 293 | outputPaths = ( 294 | ); 295 | runOnlyForDeploymentPostprocessing = 0; 296 | shellPath = /bin/sh; 297 | shellScript = "\"${SRCROOT}/Pods/Pods-LLACircularProgressView-resources.sh\"\n"; 298 | showEnvVarsInLog = 0; 299 | }; 300 | AC34018F854C4821904EA188 /* Check Pods Manifest.lock */ = { 301 | isa = PBXShellScriptBuildPhase; 302 | buildActionMask = 2147483647; 303 | files = ( 304 | ); 305 | inputPaths = ( 306 | ); 307 | name = "Check Pods Manifest.lock"; 308 | outputPaths = ( 309 | ); 310 | runOnlyForDeploymentPostprocessing = 0; 311 | shellPath = /bin/sh; 312 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; 313 | showEnvVarsInLog = 0; 314 | }; 315 | /* End PBXShellScriptBuildPhase section */ 316 | 317 | /* Begin PBXSourcesBuildPhase section */ 318 | 33C870E5181BCA9B00523CAE /* Sources */ = { 319 | isa = PBXSourcesBuildPhase; 320 | buildActionMask = 2147483647; 321 | files = ( 322 | 33C8712D181BD1A000523CAE /* LLAExampleViewController.m in Sources */, 323 | 33C87125181BCC6300523CAE /* main.m in Sources */, 324 | 33C87124181BCC6300523CAE /* LLAAppDelegate.m in Sources */, 325 | ); 326 | runOnlyForDeploymentPostprocessing = 0; 327 | }; 328 | 33C87100181BCA9B00523CAE /* Sources */ = { 329 | isa = PBXSourcesBuildPhase; 330 | buildActionMask = 2147483647; 331 | files = ( 332 | 330995321994BA1400051263 /* LLACircularProgressViewTests.m in Sources */, 333 | ); 334 | runOnlyForDeploymentPostprocessing = 0; 335 | }; 336 | /* End PBXSourcesBuildPhase section */ 337 | 338 | /* Begin PBXTargetDependency section */ 339 | 33C8710A181BCA9B00523CAE /* PBXTargetDependency */ = { 340 | isa = PBXTargetDependency; 341 | target = 33C870E8181BCA9B00523CAE /* LLACircularProgressView */; 342 | targetProxy = 33C87109181BCA9B00523CAE /* PBXContainerItemProxy */; 343 | }; 344 | /* End PBXTargetDependency section */ 345 | 346 | /* Begin XCBuildConfiguration section */ 347 | 33C87113181BCA9B00523CAE /* Debug */ = { 348 | isa = XCBuildConfiguration; 349 | buildSettings = { 350 | ALWAYS_SEARCH_USER_PATHS = NO; 351 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 352 | CLANG_CXX_LIBRARY = "libc++"; 353 | CLANG_ENABLE_MODULES = YES; 354 | CLANG_ENABLE_OBJC_ARC = YES; 355 | CLANG_WARN_BOOL_CONVERSION = YES; 356 | CLANG_WARN_CONSTANT_CONVERSION = YES; 357 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 358 | CLANG_WARN_EMPTY_BODY = YES; 359 | CLANG_WARN_ENUM_CONVERSION = YES; 360 | CLANG_WARN_INT_CONVERSION = YES; 361 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 362 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 363 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 364 | COPY_PHASE_STRIP = NO; 365 | GCC_C_LANGUAGE_STANDARD = gnu99; 366 | GCC_DYNAMIC_NO_PIC = NO; 367 | GCC_OPTIMIZATION_LEVEL = 0; 368 | GCC_PREPROCESSOR_DEFINITIONS = ( 369 | "DEBUG=1", 370 | "$(inherited)", 371 | ); 372 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 373 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 374 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 375 | GCC_WARN_UNDECLARED_SELECTOR = YES; 376 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 377 | GCC_WARN_UNUSED_FUNCTION = YES; 378 | GCC_WARN_UNUSED_VARIABLE = YES; 379 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 380 | ONLY_ACTIVE_ARCH = YES; 381 | SDKROOT = iphoneos; 382 | TARGETED_DEVICE_FAMILY = "1,2"; 383 | }; 384 | name = Debug; 385 | }; 386 | 33C87114181BCA9B00523CAE /* Release */ = { 387 | isa = XCBuildConfiguration; 388 | buildSettings = { 389 | ALWAYS_SEARCH_USER_PATHS = NO; 390 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 391 | CLANG_CXX_LIBRARY = "libc++"; 392 | CLANG_ENABLE_MODULES = YES; 393 | CLANG_ENABLE_OBJC_ARC = YES; 394 | CLANG_WARN_BOOL_CONVERSION = YES; 395 | CLANG_WARN_CONSTANT_CONVERSION = YES; 396 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 397 | CLANG_WARN_EMPTY_BODY = YES; 398 | CLANG_WARN_ENUM_CONVERSION = YES; 399 | CLANG_WARN_INT_CONVERSION = YES; 400 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 401 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 402 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 403 | COPY_PHASE_STRIP = YES; 404 | ENABLE_NS_ASSERTIONS = NO; 405 | GCC_C_LANGUAGE_STANDARD = gnu99; 406 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 407 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 408 | GCC_WARN_UNDECLARED_SELECTOR = YES; 409 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 410 | GCC_WARN_UNUSED_FUNCTION = YES; 411 | GCC_WARN_UNUSED_VARIABLE = YES; 412 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 413 | SDKROOT = iphoneos; 414 | TARGETED_DEVICE_FAMILY = "1,2"; 415 | VALIDATE_PRODUCT = YES; 416 | }; 417 | name = Release; 418 | }; 419 | 33C87116181BCA9B00523CAE /* Debug */ = { 420 | isa = XCBuildConfiguration; 421 | baseConfigurationReference = 74C462436C7348AA82BAE298 /* Pods-LLACircularProgressView.xcconfig */; 422 | buildSettings = { 423 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 424 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 425 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 426 | GCC_PREFIX_HEADER = "Example/Other Sources/LLACircularProgressView-Prefix.pch"; 427 | INFOPLIST_FILE = "Example/Resources/LLACircularProgressView-Info.plist"; 428 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 429 | PRODUCT_NAME = "$(TARGET_NAME)"; 430 | WRAPPER_EXTENSION = app; 431 | }; 432 | name = Debug; 433 | }; 434 | 33C87117181BCA9B00523CAE /* Release */ = { 435 | isa = XCBuildConfiguration; 436 | baseConfigurationReference = 74C462436C7348AA82BAE298 /* Pods-LLACircularProgressView.xcconfig */; 437 | buildSettings = { 438 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 439 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 440 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 441 | GCC_PREFIX_HEADER = "Example/Other Sources/LLACircularProgressView-Prefix.pch"; 442 | INFOPLIST_FILE = "Example/Resources/LLACircularProgressView-Info.plist"; 443 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 444 | PRODUCT_NAME = "$(TARGET_NAME)"; 445 | WRAPPER_EXTENSION = app; 446 | }; 447 | name = Release; 448 | }; 449 | 33C87119181BCA9B00523CAE /* Debug */ = { 450 | isa = XCBuildConfiguration; 451 | baseConfigurationReference = 06DDA7C7EA834A56885C1A19 /* Pods-Tests.xcconfig */; 452 | buildSettings = { 453 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/LLACircularProgressView.app/LLACircularProgressView"; 454 | FRAMEWORK_SEARCH_PATHS = ( 455 | "$(SDKROOT)/Developer/Library/Frameworks", 456 | "$(inherited)", 457 | "$(DEVELOPER_FRAMEWORKS_DIR)", 458 | ); 459 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 460 | GCC_PREFIX_HEADER = "Tests/Tests-Prefix.pch"; 461 | GCC_PREPROCESSOR_DEFINITIONS = ( 462 | "DEBUG=1", 463 | "$(inherited)", 464 | ); 465 | INFOPLIST_FILE = "Tests/Tests-Info.plist"; 466 | PRODUCT_NAME = "$(TARGET_NAME)"; 467 | TEST_HOST = "$(BUNDLE_LOADER)"; 468 | WRAPPER_EXTENSION = xctest; 469 | }; 470 | name = Debug; 471 | }; 472 | 33C8711A181BCA9B00523CAE /* Release */ = { 473 | isa = XCBuildConfiguration; 474 | baseConfigurationReference = 06DDA7C7EA834A56885C1A19 /* Pods-Tests.xcconfig */; 475 | buildSettings = { 476 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/LLACircularProgressView.app/LLACircularProgressView"; 477 | FRAMEWORK_SEARCH_PATHS = ( 478 | "$(SDKROOT)/Developer/Library/Frameworks", 479 | "$(inherited)", 480 | "$(DEVELOPER_FRAMEWORKS_DIR)", 481 | ); 482 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 483 | GCC_PREFIX_HEADER = "Tests/Tests-Prefix.pch"; 484 | INFOPLIST_FILE = "Tests/Tests-Info.plist"; 485 | PRODUCT_NAME = "$(TARGET_NAME)"; 486 | TEST_HOST = "$(BUNDLE_LOADER)"; 487 | WRAPPER_EXTENSION = xctest; 488 | }; 489 | name = Release; 490 | }; 491 | /* End XCBuildConfiguration section */ 492 | 493 | /* Begin XCConfigurationList section */ 494 | 33C870E4181BCA9B00523CAE /* Build configuration list for PBXProject "LLACircularProgressView" */ = { 495 | isa = XCConfigurationList; 496 | buildConfigurations = ( 497 | 33C87113181BCA9B00523CAE /* Debug */, 498 | 33C87114181BCA9B00523CAE /* Release */, 499 | ); 500 | defaultConfigurationIsVisible = 0; 501 | defaultConfigurationName = Release; 502 | }; 503 | 33C87115181BCA9B00523CAE /* Build configuration list for PBXNativeTarget "LLACircularProgressView" */ = { 504 | isa = XCConfigurationList; 505 | buildConfigurations = ( 506 | 33C87116181BCA9B00523CAE /* Debug */, 507 | 33C87117181BCA9B00523CAE /* Release */, 508 | ); 509 | defaultConfigurationIsVisible = 0; 510 | defaultConfigurationName = Release; 511 | }; 512 | 33C87118181BCA9B00523CAE /* Build configuration list for PBXNativeTarget "Tests" */ = { 513 | isa = XCConfigurationList; 514 | buildConfigurations = ( 515 | 33C87119181BCA9B00523CAE /* Debug */, 516 | 33C8711A181BCA9B00523CAE /* Release */, 517 | ); 518 | defaultConfigurationIsVisible = 0; 519 | defaultConfigurationName = Release; 520 | }; 521 | /* End XCConfigurationList section */ 522 | }; 523 | rootObject = 33C870E1181BCA9B00523CAE /* Project object */; 524 | } 525 | -------------------------------------------------------------------------------- /LLACircularProgressView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /LLACircularProgressView.xcodeproj/xcshareddata/xcschemes/LLACircularProgressView.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 61 | 62 | 68 | 69 | 70 | 71 | 72 | 73 | 79 | 80 | 86 | 87 | 88 | 89 | 91 | 92 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /LLACircularProgressView.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /LLACircularProgressView/LLACircularProgressView.h: -------------------------------------------------------------------------------- 1 | // 2 | // LLACircularProgressView.h 3 | // LLACircularProgressView 4 | // 5 | // Created by Lukas Lipka on 26/10/13. 6 | // Copyright (c) 2013 Lukas Lipka. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | /** 12 | Simple `UIControl` for displaying a circular progress view with a stop button. 13 | */ 14 | @interface LLACircularProgressView : UIControl 15 | 16 | /** 17 | The progress of the circular view. Only valid for values between `0` and `1`. 18 | 19 | The default is `0`. 20 | */ 21 | @property (nonatomic) float progress; 22 | 23 | /** 24 | A tintColor replacement for pre-iOS7 SDK versions. On iOS7 and higher use `tintColor` for setting this. 25 | 26 | The default is the parent view's `tintColor` or a black color on versions lower than iOS7. 27 | */ 28 | @property (nonatomic, strong) UIColor *progressTintColor; 29 | 30 | /** 31 | Set the progress of the circular view in an animated manner. Only valid for values between `0` and `1`. 32 | */ 33 | - (void)setProgress:(float)progress animated:(BOOL)animated; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /LLACircularProgressView/LLACircularProgressView.m: -------------------------------------------------------------------------------- 1 | // 2 | // LLACircularProgressView.m 3 | // LLACircularProgressView 4 | // 5 | // Created by Lukas Lipka on 26/10/13. 6 | // Copyright (c) 2013 Lukas Lipka. All rights reserved. 7 | // 8 | 9 | #import "LLACircularProgressView.h" 10 | #import 11 | #import 12 | 13 | @interface LLACircularProgressView () 14 | 15 | @property (nonatomic, strong) CAShapeLayer *progressLayer; 16 | 17 | @end 18 | 19 | @implementation LLACircularProgressView 20 | 21 | @synthesize progressTintColor = _progressTintColor; 22 | 23 | - (id)initWithFrame:(CGRect)frame { 24 | if (self = [super initWithFrame:frame]) { 25 | [self initialize]; 26 | } 27 | return self; 28 | } 29 | 30 | - (id)initWithCoder:(NSCoder *)coder { 31 | if (self = [super initWithCoder:coder]) { 32 | [self initialize]; 33 | } 34 | return self; 35 | } 36 | 37 | - (void)initialize { 38 | self.contentMode = UIViewContentModeRedraw; 39 | self.backgroundColor = [UIColor whiteColor]; 40 | 41 | _progressTintColor = [UIColor blackColor]; 42 | 43 | _progressLayer = [[CAShapeLayer alloc] init]; 44 | _progressLayer.strokeColor = self.progressTintColor.CGColor; 45 | _progressLayer.strokeEnd = 0; 46 | _progressLayer.fillColor = nil; 47 | _progressLayer.lineWidth = 3; 48 | [self.layer addSublayer:_progressLayer]; 49 | } 50 | 51 | - (void)layoutSubviews { 52 | [super layoutSubviews]; 53 | 54 | self.progressLayer.frame = self.bounds; 55 | 56 | [self updatePath]; 57 | } 58 | 59 | - (void)drawRect:(CGRect)rect { 60 | CGContextRef ctx = UIGraphicsGetCurrentContext(); 61 | 62 | CGContextSetFillColorWithColor(ctx, self.progressTintColor.CGColor); 63 | CGContextSetStrokeColorWithColor(ctx, self.progressTintColor.CGColor); 64 | CGContextStrokeEllipseInRect(ctx, CGRectInset(self.bounds, 1, 1)); 65 | 66 | CGRect stopRect; 67 | stopRect.origin.x = CGRectGetMidX(self.bounds) - self.bounds.size.width / 8; 68 | stopRect.origin.y = CGRectGetMidY(self.bounds) - self.bounds.size.height / 8; 69 | stopRect.size.width = self.bounds.size.width / 4; 70 | stopRect.size.height = self.bounds.size.height / 4; 71 | CGContextFillRect(ctx, CGRectIntegral(stopRect)); 72 | } 73 | 74 | #pragma mark - Accessors 75 | 76 | - (void)setProgress:(float)progress { 77 | [self setProgress:progress animated:NO]; 78 | } 79 | 80 | - (void)setProgress:(float)progress animated:(BOOL)animated { 81 | if (progress > 0) { 82 | if (animated) { 83 | CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; 84 | animation.fromValue = self.progress == 0 ? @0 : nil; 85 | animation.toValue = [NSNumber numberWithFloat:progress]; 86 | animation.duration = 1; 87 | self.progressLayer.strokeEnd = progress; 88 | [self.progressLayer addAnimation:animation forKey:@"animation"]; 89 | } else { 90 | [CATransaction begin]; 91 | [CATransaction setDisableActions:YES]; 92 | self.progressLayer.strokeEnd = progress; 93 | [CATransaction commit]; 94 | } 95 | } else { 96 | self.progressLayer.strokeEnd = 0.0f; 97 | [self.progressLayer removeAnimationForKey:@"animation"]; 98 | } 99 | 100 | _progress = progress; 101 | } 102 | 103 | - (UIColor *)progressTintColor { 104 | #ifdef __IPHONE_7_0 105 | if ([self respondsToSelector:@selector(tintColor)]) { 106 | return self.tintColor; 107 | } 108 | #endif 109 | return _progressTintColor; 110 | } 111 | 112 | - (void)setProgressTintColor:(UIColor *)progressTintColor { 113 | #ifdef __IPHONE_7_0 114 | if ([self respondsToSelector:@selector(setTintColor:)]) { 115 | self.tintColor = progressTintColor; 116 | return; 117 | } 118 | #endif 119 | _progressTintColor = progressTintColor; 120 | self.progressLayer.strokeColor = progressTintColor.CGColor; 121 | [self setNeedsDisplay]; 122 | } 123 | 124 | #pragma mark - Other 125 | 126 | #ifdef __IPHONE_7_0 127 | - (void)tintColorDidChange { 128 | [super tintColorDidChange]; 129 | 130 | self.progressLayer.strokeColor = self.tintColor.CGColor; 131 | [self setNeedsDisplay]; 132 | } 133 | #endif 134 | 135 | #pragma mark - Private 136 | 137 | - (void)updatePath { 138 | CGPoint center = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds)); 139 | self.progressLayer.path = [UIBezierPath bezierPathWithArcCenter:center radius:self.bounds.size.width / 2 - 2 startAngle:-M_PI_2 endAngle:-M_PI_2 + 2 * M_PI clockwise:YES].CGPath; 140 | } 141 | 142 | @end 143 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | workspace 'LLACircularProgressView' 2 | 3 | target 'LLACircularProgressView' do 4 | pod "LLACircularProgressView", :path => "LLACircularProgressView.podspec" 5 | xcodeproj 'LLACircularProgressView.xcodeproj' 6 | end 7 | 8 | target 'Tests' do 9 | pod "LLACircularProgressView", :path => "LLACircularProgressView.podspec" 10 | pod 'Specta' 11 | pod 'Expecta' 12 | pod 'OCMock' 13 | pod 'FBSnapshotTestCase' 14 | pod 'Expecta+Snapshots' 15 | xcodeproj 'LLACircularProgressView.xcodeproj' 16 | end 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | LLACircularProgressView 3 |

4 | 5 | [![Build Status](https://travis-ci.org/lipka/LLACircularProgressView.svg)](https://travis-ci.org/lipka/LLACircularProgressView) 6 | [![Version](http://cocoapod-badges.herokuapp.com/v/LLACircularProgressView/badge.png)](http://cocoadocs.org/docsets/LLACircularProgressView) 7 | [![Platform](http://cocoapod-badges.herokuapp.com/p/LLACircularProgressView/badge.png)](http://cocoadocs.org/docsets/LLACircularProgressView) 8 | 9 | LLACircularProgressView is a deligthful iOS7 style circular progress view with a stop button. 10 | 11 | - Animated progress display 12 | - Stop button 13 | - Respects iOS7 interface tint color 14 | - Automatically dims the tint color when an alert view or an action sheet is presented 15 | - iOS7 compatible 16 | 17 | ## Example 18 | 19 | ![Screenshot](http://i.imgur.com/LboRSet.png) 20 | 21 | Open up the included Xcode project for an example app. 22 | 23 | ## Usage 24 | 25 | ``` objc 26 | // Initialize the progress view 27 | LLACircularProgressView *circularProgressView = [[LLACircularProgressView alloc] init]; 28 | 29 | // Optionally set the current progress 30 | circularProgressView.progress = 0.5f; 31 | 32 | // Optionally change the tint color 33 | circulerProgressView.tintColor = [UIColor redColor]; 34 | 35 | // Optionally hook up the stop action 36 | [circularProgressView addTarget:self action:@selector(stop:) forControlEvents:UIControlEventTouchUpInside]; 37 | 38 | // Add it as a subview 39 | [self.view addSubview:circularProgressView]; 40 | 41 | ... 42 | 43 | // Animate progress changes 44 | [circularProgressView setProgress:0.8f animated:YES]; 45 | ``` 46 | 47 | See the [header](LLACircularProgressView/LLACircularProgressView.h) for full documentation. 48 | 49 | ## Installation 50 | 51 | [CocoaPods](http://cocoapods.org) is the recommended method of installing LLACircularProgressView. Simply add the following line to your `Podfile`: 52 | 53 | #### Podfile 54 | 55 | ```ruby 56 | pod 'LLACircularProgressView' 57 | ``` 58 | 59 | Otherwise you can just add `LLACircularProgressView.h` and `LLACircularProgressView.m` to your project. 60 | 61 | ## Requirements 62 | 63 | LLACircularProgressView is tested on iOS6 and iOS7 and requires ARC. 64 | 65 | ## Contact 66 | 67 | Lukas Lipka 68 | 69 | - http://github.com/lipka 70 | - http://twitter.com/lipec 71 | - http://lukaslipka.com 72 | 73 | ## License 74 | 75 | LLACircularProgressView is available under the [MIT license](LICENSE). See the LICENSE file for more info. 76 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | desc "Runs the specs [EMPTY]" 2 | task :spec do 3 | # Provide your own implementation 4 | end 5 | 6 | task :version do 7 | git_remotes = `git remote`.strip.split("\n") 8 | 9 | if git_remotes.count > 0 10 | puts "-- fetching version number from github" 11 | sh 'git fetch' 12 | 13 | remote_version = remote_spec_version 14 | end 15 | 16 | if remote_version.nil? 17 | puts "There is no current released version. You're about to release a new Pod." 18 | version = "0.0.1" 19 | else 20 | puts "The current released version of your pod is " + remote_spec_version.to_s() 21 | version = suggested_version_number 22 | end 23 | 24 | puts "Enter the version you want to release (" + version + ") " 25 | new_version_number = $stdin.gets.strip 26 | if new_version_number == "" 27 | new_version_number = version 28 | end 29 | 30 | replace_version_number(new_version_number) 31 | end 32 | 33 | desc "Release a new version of the Pod" 34 | task :release do 35 | 36 | puts "* Running version" 37 | sh "rake version" 38 | 39 | unless ENV['SKIP_CHECKS'] 40 | if `git symbolic-ref HEAD 2>/dev/null`.strip.split('/').last != 'master' 41 | $stderr.puts "[!] You need to be on the `master' branch in order to be able to do a release." 42 | exit 1 43 | end 44 | 45 | if `git tag`.strip.split("\n").include?(spec_version) 46 | $stderr.puts "[!] A tag for version `#{spec_version}' already exists. Change the version in the podspec" 47 | exit 1 48 | end 49 | 50 | puts "You are about to release `#{spec_version}`, is that correct? [y/n]" 51 | exit if $stdin.gets.strip.downcase != 'y' 52 | end 53 | 54 | puts "* Running specs" 55 | sh "rake spec" 56 | 57 | puts "* Linting the podspec" 58 | sh "pod lib lint" 59 | 60 | # Then release 61 | sh "git commit #{podspec_path} -m 'Release #{spec_version}'" 62 | sh "git tag -a #{spec_version} -m 'Release #{spec_version}'" 63 | sh "git push origin master" 64 | sh "git push origin --tags" 65 | sh "pod trunk push #{podspec_path}" 66 | end 67 | 68 | # @return [Pod::Version] The version as reported by the Podspec. 69 | # 70 | def spec_version 71 | require 'cocoapods' 72 | spec = Pod::Specification.from_file(podspec_path) 73 | spec.version 74 | end 75 | 76 | # @return [Pod::Version] The version as reported by the Podspec from remote. 77 | # 78 | def remote_spec_version 79 | require 'cocoapods-core' 80 | 81 | if spec_file_exist_on_remote? 82 | remote_spec = eval(`git show origin/master:#{podspec_path}`) 83 | remote_spec.version 84 | else 85 | nil 86 | end 87 | end 88 | 89 | # @return [Bool] If the remote repository has a copy of the podpesc file or not. 90 | # 91 | def spec_file_exist_on_remote? 92 | test_condition = `if git rev-parse --verify --quiet origin/master:#{podspec_path} >/dev/null; 93 | then 94 | echo 'true' 95 | else 96 | echo 'false' 97 | fi` 98 | 99 | 'true' == test_condition.strip 100 | end 101 | 102 | # @return [String] The relative path of the Podspec. 103 | # 104 | def podspec_path 105 | podspecs = Dir.glob('*.podspec') 106 | if podspecs.count == 1 107 | podspecs.first 108 | else 109 | raise "Could not select a podspec" 110 | end 111 | end 112 | 113 | # @return [String] The suggested version number based on the local and remote version numbers. 114 | # 115 | def suggested_version_number 116 | if spec_version != remote_spec_version 117 | spec_version.to_s() 118 | else 119 | next_version(spec_version).to_s() 120 | end 121 | end 122 | 123 | # @param [Pod::Version] version 124 | # the version for which you need the next version 125 | # 126 | # @note It is computed by bumping the last component of the versino string by 1. 127 | # 128 | # @return [Pod::Version] The version that comes next after the version supplied. 129 | # 130 | def next_version(version) 131 | version_components = version.to_s().split("."); 132 | last = (version_components.last.to_i() + 1).to_s 133 | version_components[-1] = last 134 | Pod::Version.new(version_components.join(".")) 135 | end 136 | 137 | # @param [String] new_version_number 138 | # the new version number 139 | # 140 | # @note This methods replaces the version number in the podspec file with a new version number. 141 | # 142 | # @return void 143 | # 144 | def replace_version_number(new_version_number) 145 | text = File.read(podspec_path) 146 | text.gsub!(/(s.version( )*= ")#{spec_version}(")/, "\\1#{new_version_number}\\3") 147 | File.open(podspec_path, "w") { |file| file.puts text } 148 | end 149 | -------------------------------------------------------------------------------- /Tests/LLACircularProgressViewTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // LLACircularProgressViewTests.m 3 | // LLACircularProgressViewTests 4 | // 5 | // Created by Lukas Lipka on 26/10/13. 6 | // Copyright (c) 2013 Lukas Lipka. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | SpecBegin(LLACircularProgressView) 12 | 13 | it(@"should fit in bounds", ^{ 14 | LLACircularProgressView *progressView = [[LLACircularProgressView alloc] initWithFrame:CGRectZero]; 15 | progressView.frame = CGRectMake(0, 0, 40, 40); 16 | progressView.backgroundColor = [UIColor whiteColor]; 17 | 18 | expect(progressView).to.haveValidSnapshot(); 19 | }); 20 | 21 | SpecEnd -------------------------------------------------------------------------------- /Tests/ReferenceImages/LLACircularProgressViewSpec/should_fit_in_bounds@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lipka/LLACircularProgressView/e1a0b9209047bab2683916665de41c79900063a6/Tests/ReferenceImages/LLACircularProgressViewSpec/should_fit_in_bounds@2x.png -------------------------------------------------------------------------------- /Tests/Tests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | com.lukaslipka.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Tests/Tests-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Tests-Prefix.pch 3 | // LLACircularProgressView 4 | // 5 | // Created by Lukas Lipka on 08/08/14. 6 | // Copyright (c) 2014 Lukas Lipka. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #ifndef __IPHONE_4_0 12 | #warning "This project uses features only available in iOS SDK 4.0 and later." 13 | #endif 14 | 15 | #ifdef __OBJC__ 16 | 17 | #import 18 | #import 19 | 20 | #define EXP_SHORTHAND 21 | #import 22 | #import 23 | #import 24 | #import 25 | 26 | #endif 27 | --------------------------------------------------------------------------------