├── Podfile ├── ExampleProject ├── EFCircularSlider │ ├── en.lproj │ │ └── InfoPlist.strings │ ├── label_position.png │ ├── EFBigLineViewController.h │ ├── EFWithLabelsViewController.h │ ├── EFDoubleCircleViewController.h │ ├── EFSnapToLabelsViewController.h │ ├── EFBigCircleHandleViewController.h │ ├── EFAppDelegate.h │ ├── EFBasicViewController.h │ ├── EFDemoListViewController.h │ ├── EFTimePickerViewController.h │ ├── main.m │ ├── EFCircularSlider-Prefix.pch │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── LaunchImage.launchimage │ │ │ └── Contents.json │ ├── EFBigLineViewController.m │ ├── EFBasicViewController.m │ ├── EFDoubleCircleViewController.m │ ├── EFBigCircleHandleViewController.m │ ├── EFWithLabelsViewController.m │ ├── EFSnapToLabelsViewController.m │ ├── EFCircularSlider-Info.plist │ ├── EFDemoListViewController.m │ ├── EFAppDelegate.m │ ├── EFTimePickerViewController.m │ └── Base.lproj │ │ └── Main.storyboard ├── EFCircularSliderTests │ ├── en.lproj │ │ └── InfoPlist.strings │ ├── EFCircularSliderTests-Info.plist │ └── EFCircularSliderTests.m └── EFCircularSlider.xcodeproj │ └── project.pbxproj ├── .gitignore ├── EFCircularSlider.podspec ├── LICENSE ├── EFCircularSlider ├── EFCircularSlider.h └── EFCircularSlider.m └── README.md /Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, "7.0" -------------------------------------------------------------------------------- /ExampleProject/EFCircularSlider/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /ExampleProject/EFCircularSliderTests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /ExampleProject/EFCircularSlider/label_position.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eliotfowler/EFCircularSlider/HEAD/ExampleProject/EFCircularSlider/label_position.png -------------------------------------------------------------------------------- /.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 | *.xcworkspace 13 | !default.xcworkspace 14 | xcuserdata 15 | profile 16 | *.moved-aside 17 | DerivedData 18 | .idea/ 19 | -------------------------------------------------------------------------------- /ExampleProject/EFCircularSlider/EFBigLineViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // EFBigLineViewController.h 3 | // EFCircularSlider 4 | // 5 | // Created by Christian Bianciotto on 21/03/14. 6 | // Copyright (c) 2014 Eliot Fowler. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface EFBigLineViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /ExampleProject/EFCircularSlider/EFWithLabelsViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // EFWithLabelsViewController.h 3 | // EFCircularSlider 4 | // 5 | // Created by Eliot Fowler on 12/5/13. 6 | // Copyright (c) 2013 Eliot Fowler. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface EFWithLabelsViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /ExampleProject/EFCircularSlider/EFDoubleCircleViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // EFDoubleCircleViewController.h 3 | // EFCircularSlider 4 | // 5 | // Created by Eliot Fowler on 12/5/13. 6 | // Copyright (c) 2013 Eliot Fowler. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface EFDoubleCircleViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /ExampleProject/EFCircularSlider/EFSnapToLabelsViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // EFSnapToLabelsViewController.h 3 | // EFCircularSlider 4 | // 5 | // Created by Eliot Fowler on 12/5/13. 6 | // Copyright (c) 2013 Eliot Fowler. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface EFSnapToLabelsViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /ExampleProject/EFCircularSlider/EFBigCircleHandleViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // EFBigCircleHandleViewController.h 3 | // EFCircularSlider 4 | // 5 | // Created by Eliot Fowler on 12/5/13. 6 | // Copyright (c) 2013 Eliot Fowler. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface EFBigCircleHandleViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /ExampleProject/EFCircularSlider/EFAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // EFAppDelegate.h 3 | // EFCircularSlider 4 | // 5 | // Created by Eliot Fowler on 12/4/13. 6 | // Copyright (c) 2013 Eliot Fowler. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface EFAppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /ExampleProject/EFCircularSlider/EFBasicViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // EFViewController.h 3 | // EFCircularSlider 4 | // 5 | // Created by Eliot Fowler on 12/4/13. 6 | // Copyright (c) 2013 Eliot Fowler. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface EFBasicViewController : UIViewController 12 | @property (weak, nonatomic) IBOutlet UILabel *valueLabel; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /ExampleProject/EFCircularSlider/EFDemoListViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // EFDemoListViewController.h 3 | // EFCircularSlider 4 | // 5 | // Created by Eliot Fowler on 12/5/13. 6 | // Copyright (c) 2013 Eliot Fowler. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface EFDemoListViewController : UIViewController 12 | 13 | 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /ExampleProject/EFCircularSlider/EFTimePickerViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // EFTimePickerViewController.h 3 | // EFCircularSlider 4 | // 5 | // Created by Eliot Fowler on 12/5/13. 6 | // Copyright (c) 2013 Eliot Fowler. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface EFTimePickerViewController : UIViewController 12 | 13 | @property (weak, nonatomic) IBOutlet UILabel *timeLabel; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /ExampleProject/EFCircularSlider/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // EFCircularSlider 4 | // 5 | // Created by Eliot Fowler on 12/4/13. 6 | // Copyright (c) 2013 Eliot Fowler. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "EFAppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([EFAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ExampleProject/EFCircularSlider/EFCircularSlider-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_5_0 10 | #warning "This project uses features only available in iOS SDK 5.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | #import 16 | #endif 17 | -------------------------------------------------------------------------------- /ExampleProject/EFCircularSlider/Images.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" : "40x40", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "60x60", 16 | "scale" : "2x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /ExampleProject/EFCircularSlider/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "portrait", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "7.0", 16 | "scale" : "2x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /EFCircularSlider.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'EFCircularSlider' 3 | s.version = '0.2.0' 4 | s.license = { :type => 'MIT', :file => 'LICENSE' } 5 | s.authors = { 'Eliot Fowler' => 'eliot.fowler@gmail.com' } 6 | s.summary = 'An extensible circular slider for iOS applications' 7 | s.homepage = 'https://github.com/eliotfowler/EFCircularSlider' 8 | 9 | # Source Info 10 | s.platform = :ios, '7.0' 11 | s.source = { :git => 'https://github.com/eliotfowler/EFCircularSlider.git', :tag => "0.2.0" } 12 | s.source_files = 'EFCircularSlider/EFCircularSlider.{h,m}' 13 | 14 | s.requires_arc = true 15 | end -------------------------------------------------------------------------------- /ExampleProject/EFCircularSliderTests/EFCircularSliderTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | com.eliotfowler.${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 | -------------------------------------------------------------------------------- /ExampleProject/EFCircularSliderTests/EFCircularSliderTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // EFCircularSliderTests.m 3 | // EFCircularSliderTests 4 | // 5 | // Created by Eliot Fowler on 12/4/13. 6 | // Copyright (c) 2013 Eliot Fowler. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface EFCircularSliderTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation EFCircularSliderTests 16 | 17 | - (void)setUp 18 | { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown 24 | { 25 | // Put teardown code here. This method is called after the invocation of each test method in the class. 26 | [super tearDown]; 27 | } 28 | 29 | - (void)testExample 30 | { 31 | XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Eliot Fowler 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, 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, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /ExampleProject/EFCircularSlider/EFBigLineViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // EFBigLineViewController.m 3 | // EFCircularSlider 4 | // 5 | // Created by Christian Bianciotto on 21/03/14. 6 | // Copyright (c) 2014 Eliot Fowler. All rights reserved. 7 | // 8 | 9 | #import "EFBigLineViewController.h" 10 | #import "EFCircularSlider.h" 11 | 12 | @interface EFBigLineViewController () 13 | 14 | @end 15 | 16 | @implementation EFBigLineViewController 17 | 18 | - (void)viewDidLoad 19 | { 20 | [super viewDidLoad]; 21 | 22 | CGRect sliderFrame = CGRectMake(0, 120, 320, 320); 23 | EFCircularSlider* circularSlider = [[EFCircularSlider alloc] initWithFrame:sliderFrame]; 24 | 25 | circularSlider.lineWidth = 50; 26 | circularSlider.labelFont = [UIFont fontWithName:@"GillSans-Light" size:16]; 27 | 28 | NSArray* labels = @[@"B", @"C", @"D", @"E"]; 29 | [circularSlider setInnerMarkingLabels:labels]; 30 | 31 | [self.view addSubview:circularSlider]; 32 | } 33 | 34 | - (void)didReceiveMemoryWarning 35 | { 36 | [super didReceiveMemoryWarning]; 37 | // Dispose of any resources that can be recreated. 38 | } 39 | 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /ExampleProject/EFCircularSlider/EFBasicViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // EFBasicViewController.m 3 | // EFCircularSlider 4 | // 5 | // Created by Eliot Fowler on 12/4/13. 6 | // Copyright (c) 2013 Eliot Fowler. All rights reserved. 7 | // 8 | 9 | #import "EFBasicViewController.h" 10 | #import "EFCircularSlider.h" 11 | 12 | @interface EFBasicViewController () 13 | 14 | @end 15 | 16 | @implementation EFBasicViewController 17 | 18 | - (void)viewDidLoad 19 | { 20 | [super viewDidLoad]; 21 | 22 | CGRect sliderFrame = CGRectMake(60, 150, 200, 200); 23 | EFCircularSlider* circularSlider = [[EFCircularSlider alloc] initWithFrame:sliderFrame]; 24 | [circularSlider addTarget:self action:@selector(valueChanged:) forControlEvents:UIControlEventValueChanged]; 25 | [self.view addSubview:circularSlider]; 26 | [circularSlider setCurrentValue:10.0f]; 27 | } 28 | 29 | -(void)valueChanged:(EFCircularSlider*)slider { 30 | _valueLabel.text = [NSString stringWithFormat:@"%.02f", slider.currentValue ]; 31 | } 32 | 33 | - (void)didReceiveMemoryWarning 34 | { 35 | [super didReceiveMemoryWarning]; 36 | // Dispose of any resources that can be recreated. 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /ExampleProject/EFCircularSlider/EFDoubleCircleViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // EFDoubleCircleViewController.m 3 | // EFCircularSlider 4 | // 5 | // Created by Eliot Fowler on 12/5/13. 6 | // Copyright (c) 2013 Eliot Fowler. All rights reserved. 7 | // 8 | 9 | #import "EFDoubleCircleViewController.h" 10 | #import "EFCircularSlider.h" 11 | 12 | @interface EFDoubleCircleViewController () 13 | 14 | @end 15 | 16 | @implementation EFDoubleCircleViewController 17 | 18 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 19 | { 20 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 21 | if (self) { 22 | // Custom initialization 23 | } 24 | return self; 25 | } 26 | 27 | - (void)viewDidLoad 28 | { 29 | [super viewDidLoad]; 30 | 31 | CGRect sliderFrame = CGRectMake(60, 150, 200, 200); 32 | EFCircularSlider* circularSlider = [[EFCircularSlider alloc] initWithFrame:sliderFrame]; 33 | circularSlider.handleType = EFDoubleCircleWithOpenCenter; 34 | [self.view addSubview:circularSlider]; 35 | } 36 | 37 | - (void)didReceiveMemoryWarning 38 | { 39 | [super didReceiveMemoryWarning]; 40 | // Dispose of any resources that can be recreated. 41 | } 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /EFCircularSlider/EFCircularSlider.h: -------------------------------------------------------------------------------- 1 | // 2 | // EFCircularSlider.h 3 | // Awake 4 | // 5 | // Created by Eliot Fowler on 12/3/13. 6 | // Copyright (c) 2013 Eliot Fowler. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface EFCircularSlider : UIControl 12 | 13 | typedef NS_ENUM(NSInteger, EFHandleType) { 14 | EFSemiTransparentWhiteCircle, 15 | EFSemiTransparentBlackCircle, 16 | EFDoubleCircleWithOpenCenter, 17 | EFDoubleCircleWithClosedCenter, 18 | EFBigCircle 19 | }; 20 | 21 | @property (nonatomic) float minimumValue; 22 | @property (nonatomic) float maximumValue; 23 | @property (nonatomic) float currentValue; 24 | 25 | @property (nonatomic) int lineWidth; 26 | @property (nonatomic) int lineRadiusDisplacement; 27 | @property (nonatomic, strong) UIColor* filledColor; 28 | @property (nonatomic, strong) UIColor* unfilledColor; 29 | 30 | @property (nonatomic, strong) UIColor* handleColor; 31 | @property (nonatomic) EFHandleType handleType; 32 | 33 | @property (nonatomic, strong) UIFont* labelFont; 34 | @property (nonatomic, strong) UIColor* labelColor; 35 | @property (nonatomic, assign) NSInteger labelDisplacement; 36 | @property (nonatomic) BOOL snapToLabels; 37 | 38 | 39 | 40 | -(void)setInnerMarkingLabels:(NSArray*)labels; 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /ExampleProject/EFCircularSlider/EFBigCircleHandleViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // EFBigCircleHandleViewController.m 3 | // EFCircularSlider 4 | // 5 | // Created by Eliot Fowler on 12/5/13. 6 | // Copyright (c) 2013 Eliot Fowler. All rights reserved. 7 | // 8 | 9 | #import "EFBigCircleHandleViewController.h" 10 | #import "EFCircularSlider.h" 11 | 12 | @interface EFBigCircleHandleViewController () 13 | 14 | @end 15 | 16 | @implementation EFBigCircleHandleViewController 17 | 18 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 19 | { 20 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 21 | if (self) { 22 | // Custom initialization 23 | } 24 | return self; 25 | } 26 | 27 | - (void)viewDidLoad 28 | { 29 | [super viewDidLoad]; 30 | 31 | CGRect sliderFrame = CGRectMake(60, 150, 200, 200); 32 | EFCircularSlider* circularSlider = [[EFCircularSlider alloc] initWithFrame:sliderFrame]; 33 | circularSlider.handleType = EFBigCircle; 34 | circularSlider.handleColor = [UIColor blueColor]; 35 | [self.view addSubview:circularSlider]; 36 | } 37 | 38 | - (void)didReceiveMemoryWarning 39 | { 40 | [super didReceiveMemoryWarning]; 41 | // Dispose of any resources that can be recreated. 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /ExampleProject/EFCircularSlider/EFWithLabelsViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // EFWithLabelsViewController.m 3 | // EFCircularSlider 4 | // 5 | // Created by Eliot Fowler on 12/5/13. 6 | // Copyright (c) 2013 Eliot Fowler. All rights reserved. 7 | // 8 | 9 | #import "EFWithLabelsViewController.h" 10 | #import "EFCircularSlider.h" 11 | 12 | @interface EFWithLabelsViewController () 13 | 14 | @end 15 | 16 | @implementation EFWithLabelsViewController 17 | 18 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 19 | { 20 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 21 | if (self) { 22 | // Custom initialization 23 | } 24 | return self; 25 | } 26 | 27 | - (void)viewDidLoad 28 | { 29 | [super viewDidLoad]; 30 | 31 | CGRect sliderFrame = CGRectMake(60, 150, 200, 200); 32 | EFCircularSlider* circularSlider = [[EFCircularSlider alloc] initWithFrame:sliderFrame]; 33 | 34 | NSArray* labels = @[@"B", @"C", @"D", @"E", @"A"]; 35 | [circularSlider setInnerMarkingLabels:labels]; 36 | 37 | [self.view addSubview:circularSlider]; 38 | } 39 | 40 | - (void)didReceiveMemoryWarning 41 | { 42 | [super didReceiveMemoryWarning]; 43 | // Dispose of any resources that can be recreated. 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /ExampleProject/EFCircularSlider/EFSnapToLabelsViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // EFSnapToLabelsViewController.m 3 | // EFCircularSlider 4 | // 5 | // Created by Eliot Fowler on 12/5/13. 6 | // Copyright (c) 2013 Eliot Fowler. All rights reserved. 7 | // 8 | 9 | #import "EFSnapToLabelsViewController.h" 10 | #import "EFCircularSlider.h" 11 | 12 | @interface EFSnapToLabelsViewController () 13 | 14 | @end 15 | 16 | @implementation EFSnapToLabelsViewController 17 | 18 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 19 | { 20 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 21 | if (self) { 22 | // Custom initialization 23 | } 24 | return self; 25 | } 26 | 27 | - (void)viewDidLoad 28 | { 29 | [super viewDidLoad]; 30 | 31 | CGRect sliderFrame = CGRectMake(60, 150, 200, 200); 32 | EFCircularSlider* circularSlider = [[EFCircularSlider alloc] initWithFrame:sliderFrame]; 33 | 34 | NSArray* labels = @[@"B", @"C", @"D", @"E", @"A"]; 35 | [circularSlider setInnerMarkingLabels:labels]; 36 | circularSlider.snapToLabels = YES; 37 | 38 | [self.view addSubview:circularSlider]; 39 | } 40 | 41 | - (void)didReceiveMemoryWarning 42 | { 43 | [super didReceiveMemoryWarning]; 44 | // Dispose of any resources that can be recreated. 45 | } 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /ExampleProject/EFCircularSlider/EFCircularSlider-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | com.eliotfowler.${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 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /ExampleProject/EFCircularSlider/EFDemoListViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // EFDemoListViewController.m 3 | // EFCircularSlider 4 | // 5 | // Created by Eliot Fowler on 12/5/13. 6 | // Copyright (c) 2013 Eliot Fowler. All rights reserved. 7 | // 8 | 9 | #import "EFDemoListViewController.h" 10 | 11 | @interface EFDemoListViewController () 12 | 13 | @end 14 | 15 | @implementation EFDemoListViewController 16 | 17 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 18 | { 19 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 20 | if (self) { 21 | // Custom initialization 22 | } 23 | return self; 24 | } 25 | 26 | - (id)initWithCoder:(NSCoder *)aDecoder 27 | { 28 | if (self = [super initWithCoder:aDecoder]) 29 | { 30 | // Custom initialization 31 | } 32 | return self; 33 | } 34 | 35 | - (void)viewDidLoad 36 | { 37 | [super viewDidLoad]; 38 | // Do any additional setup after loading the view. 39 | } 40 | 41 | #pragma mark - UITableView Delegate Methods 42 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 43 | UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"]; 44 | cell.textLabel.text = @"Test"; 45 | return cell; 46 | } 47 | 48 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 49 | return 6; 50 | } 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /ExampleProject/EFCircularSlider/EFAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // EFAppDelegate.m 3 | // EFCircularSlider 4 | // 5 | // Created by Eliot Fowler on 12/4/13. 6 | // Copyright (c) 2013 Eliot Fowler. All rights reserved. 7 | // 8 | 9 | #import "EFAppDelegate.h" 10 | 11 | @implementation EFAppDelegate 12 | 13 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 14 | { 15 | // Override point for customization after application launch. 16 | return YES; 17 | } 18 | 19 | - (void)applicationWillResignActive:(UIApplication *)application 20 | { 21 | // 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. 22 | // 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. 23 | } 24 | 25 | - (void)applicationDidEnterBackground:(UIApplication *)application 26 | { 27 | // 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. 28 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 29 | } 30 | 31 | - (void)applicationWillEnterForeground:(UIApplication *)application 32 | { 33 | // 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. 34 | } 35 | 36 | - (void)applicationDidBecomeActive:(UIApplication *)application 37 | { 38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application 42 | { 43 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /ExampleProject/EFCircularSlider/EFTimePickerViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // EFTimePickerViewController.m 3 | // EFCircularSlider 4 | // 5 | // Created by Eliot Fowler on 12/5/13. 6 | // Copyright (c) 2013 Eliot Fowler. All rights reserved. 7 | // 8 | 9 | #import "EFTimePickerViewController.h" 10 | #import "EFCircularSlider.h" 11 | 12 | @interface EFTimePickerViewController () 13 | 14 | @end 15 | 16 | @implementation EFTimePickerViewController { 17 | EFCircularSlider* minuteSlider; 18 | EFCircularSlider* hourSlider; 19 | } 20 | 21 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 22 | { 23 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 24 | if (self) { 25 | // Custom initialization 26 | } 27 | return self; 28 | } 29 | 30 | - (void)viewDidLoad 31 | { 32 | [super viewDidLoad]; 33 | self.view.backgroundColor = [UIColor colorWithRed:31/255.0f green:61/255.0f blue:91/255.0f alpha:1.0f]; 34 | CGRect minuteSliderFrame = CGRectMake(5, 170, 310, 310); 35 | minuteSlider = [[EFCircularSlider alloc] initWithFrame:minuteSliderFrame]; 36 | minuteSlider.unfilledColor = [UIColor colorWithRed:23/255.0f green:47/255.0f blue:70/255.0f alpha:1.0f]; 37 | minuteSlider.filledColor = [UIColor colorWithRed:155/255.0f green:211/255.0f blue:156/255.0f alpha:1.0f]; 38 | [minuteSlider setInnerMarkingLabels:@[@"5", @"10", @"15", @"20", @"25", @"30", @"35", @"40", @"45", @"50", @"55", @"60"]]; 39 | minuteSlider.labelFont = [UIFont systemFontOfSize:14.0f]; 40 | minuteSlider.lineWidth = 8; 41 | minuteSlider.minimumValue = 0; 42 | minuteSlider.maximumValue = 60; 43 | minuteSlider.labelColor = [UIColor colorWithRed:76/255.0f green:111/255.0f blue:137/255.0f alpha:1.0f]; 44 | minuteSlider.handleType = EFDoubleCircleWithOpenCenter; 45 | minuteSlider.handleColor = minuteSlider.filledColor; 46 | [self.view addSubview:minuteSlider]; 47 | [minuteSlider addTarget:self action:@selector(minuteDidChange:) forControlEvents:UIControlEventValueChanged]; 48 | 49 | CGRect hourSliderFrame = CGRectMake(55, 220, 210, 210); 50 | hourSlider = [[EFCircularSlider alloc] initWithFrame:hourSliderFrame]; 51 | hourSlider.unfilledColor = [UIColor colorWithRed:23/255.0f green:47/255.0f blue:70/255.0f alpha:1.0f]; 52 | hourSlider.filledColor = [UIColor colorWithRed:98/255.0f green:243/255.0f blue:252/255.0f alpha:1.0f]; 53 | [hourSlider setInnerMarkingLabels:@[@"1", @"2", @"3", @"4", @"5", @"6", @"7", @"8", @"9", @"10", @"11", @"12"]]; 54 | hourSlider.labelFont = [UIFont systemFontOfSize:14.0f]; 55 | hourSlider.lineWidth = 12; 56 | hourSlider.snapToLabels = NO; 57 | hourSlider.minimumValue = 0; 58 | hourSlider.maximumValue = 12; 59 | hourSlider.labelColor = [UIColor colorWithRed:127/255.0f green:229/255.0f blue:255/255.0f alpha:1.0f]; 60 | hourSlider.handleType = EFBigCircle; 61 | hourSlider.handleColor = hourSlider.filledColor; 62 | [self.view addSubview:hourSlider]; 63 | [hourSlider addTarget:self action:@selector(hourDidChange:) forControlEvents:UIControlEventValueChanged]; 64 | } 65 | 66 | -(void)hourDidChange:(EFCircularSlider*)slider { 67 | int newVal = (int)slider.currentValue ? (int)slider.currentValue : 12; 68 | NSString* oldTime = _timeLabel.text; 69 | NSRange colonRange = [oldTime rangeOfString:@":"]; 70 | _timeLabel.text = [NSString stringWithFormat:@"%d:%@", newVal, [oldTime substringFromIndex:colonRange.location + 1]]; 71 | } 72 | 73 | -(void)minuteDidChange:(EFCircularSlider*)slider { 74 | int newVal = (int)slider.currentValue < 60 ? (int)slider.currentValue : 0; 75 | NSString* oldTime = _timeLabel.text; 76 | NSRange colonRange = [oldTime rangeOfString:@":"]; 77 | _timeLabel.text = [NSString stringWithFormat:@"%@:%02d", [oldTime substringToIndex:colonRange.location], newVal]; 78 | } 79 | 80 | - (void)didReceiveMemoryWarning 81 | { 82 | [super didReceiveMemoryWarning]; 83 | // Dispose of any resources that can be recreated. 84 | } 85 | 86 | @end 87 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | EFCircularSlider 2 | ================ 3 | 4 | An extensible circular slider for iOS applications. 5 | 6 | Demo 7 | ---- 8 | 9 | The code to make this GIF is in the `ExampleProject/` directory: 10 | 11 |

12 | 13 |

14 | 15 | Installation 16 | ------------ 17 | 18 | The simplest way to use EFCircularSlider in your application is with [CocoaPods](http://cocoapods.org). See the ["Getting Started" guide for more information](http://guides.cocoapods.org/using/using-cocoapods.html). 19 | 20 | #### Podfile 21 | 22 | ```ruby 23 | platform :ios, '7.0' 24 | pod "EFCircularSlider", "~> 0.1.0" 25 | ``` 26 | 27 | You could instead clone the project and copy the EFCircularSlider/EFCircularSlider.{h,m} files into your project. 28 | 29 | 30 | Initialization 31 | -------------- 32 | 33 | Adding EFCircularSlider to your project is as simple as getting the source files, and waving a magic wand: 34 | 35 | ``` objc 36 | - (void)viewDidLoad { 37 | ... 38 | CGRect sliderFrame = CGRectMake(110, 150, 100, 100); 39 | EFCircularSlider* circularSlider = [[EFCircularSlider alloc] initWithFrame:sliderFrame]; 40 | [self.view addSubview:circularSlider]; 41 | ... 42 | } 43 | ``` 44 | 45 | And then, just like you would for any other control, you need to subscribe to the event chagning using target-action behavior: 46 | 47 | ```objc 48 | [slider addTarget:self action:@selector(newValue:) forControlEvents:UIControlEventValueChanged]; 49 | ``` 50 | 51 | Options 52 | ------- 53 | 54 | EFCircularSlider is made to be very easy to style and customize. 55 | 56 | ###Properties 57 | 58 | ####minimumValue:(float) - Default: 0.0f 59 | 60 | When the slider is at the very top position, it will set the currentValue to this. 61 | 62 | You can set the minimum value with: 63 | 64 | ```objc 65 | circularSlider.minimumValue = 1.0f; 66 | ``` 67 | 68 | ####maximumValue:(float) - Default 100.0f 69 | 70 | With EFCircularSlider, the currentValue increases as you drag the slider clockwise. Therefore, when 71 | the slider is just to the left of the very top position, it will approach (but never reach) this. 72 | 73 | You can set the maximum value with: 74 | 75 | ```objc 76 | circularSlider.minimumValue = 100.0f; 77 | ``` 78 | 79 | ####currentValue:(float) - Default 0.0f 80 | 81 | Whenever the slider changes position, this value will change. It will be a normalized value based on the minimuimValue and maximumValue properties. 82 | 83 | You can get the currentValue with: 84 | 85 | ```objc 86 | float val = circularSlider.currentValue; 87 | ``` 88 | 89 | ####lineWidth:(int) - Default 5 90 | 91 | This determines the width of the arc that makes up the slider. This will set the value both for the unfilled arc (the background) and the arc that shows how much of the slider has been slid across. **Currently, changing the lineWidth more than a few pixels causes adverse side effects, mainly with the handle.** 92 | 93 | You can modify the lineWidth with: 94 | 95 | ```objc 96 | circularSlider.lineWidth = 6; 97 | ``` 98 | 99 | ####handleColor:(UIColor*) - Default [UIColor redColor] 100 | 101 | The handle is the part of the slider that you drag with your finger. 102 | 103 | Modify the color of the handle with: 104 | 105 | ```objc 106 | CGFloat hue = ( arc4random() % 256 / 256.0 ); 107 | CGFloat saturation = ( arc4random() % 128 / 256.0 ) + 0.5; 108 | CGFloat brightness = ( arc4random() % 128 / 256.0 ) + 0.5; 109 | 110 | circularSlider.handleColor = [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:1]; 111 | ``` 112 | 113 | ####handleType:(EFHandleType) - Default EFSemiTransparentWhiteCircle 114 | 115 | EFCircularSlider comes with 4 types of handles: 116 | 117 | - EFSemiTransparentWhiteCircle 118 | - EFSemiTransparentBlackCircle 119 | - EFDoubleCircleWithOpenCenter 120 | - EFDoubleCircleWithClosedCenter 121 | - EFBigCircle 122 | 123 | You can change the handleType with: 124 | 125 | ```objc 126 | circularSlider.handleType = EFDoubleCircleWithClosedCenter; 127 | ``` 128 | 129 | ####unfilledColor:(UIColor*) - Default [UIColor blackColor] 130 | 131 | This is the color that will show if the slider is set to its minimum value. 132 | 133 | You can modify the unfilledColor with: 134 | 135 | ```objc 136 | circularSlider.unfilledColor = [UIColor purpleColor]; 137 | ``` 138 | 139 | ####filledColor:(UIColor*) - Default [UIColor redColor] 140 | 141 | This is the color that will show between the minimum value and the currentValue. 142 | 143 | You can modify the filledColor with: 144 | 145 | ```objc 146 | circularSlider.unfilledColor = [UIColor purpleColor]; 147 | ``` 148 | 149 | ####labelFont:(UIFont*) - Default [UIFont systemFontOfSize:10.0f] 150 | 151 | This is the font that the labels will have if you decide to set inner marking labels (more on this down the page). 152 | 153 | You can modify the labelFont with: 154 | 155 | ```objc 156 | circularSlider.labelFont = [UIFont systemFontOfSize:14.0f]; 157 | ``` 158 | 159 | **Note this will have no effect if you have not passed in the labels that you want to add** 160 | 161 | ####snapToLabels:(BOOL) - Default NO 162 | 163 | If this is set to YES, once finish dragging the slider, it will snap to the closest label and subsequently set the current value to what it would be at that label, not where you dragged it. 164 | 165 | You can set the slider to snap to labels with: 166 | 167 | ```objc 168 | circularSlider.snapToLabels = YES; 169 | ``` 170 | 171 | **Note this will have no effect if you have not passed in the labels that you want to add** 172 | 173 | ###Functions 174 | 175 | ####-(void)setInnerMarkingLabels:(NSArray*)labels 176 | 177 | You can send this method an array of labels and they will show up on the inside of the slider. There is currently no way to specify the spacing between the labels and therefore they will be evenly spaced out. If you choose to include labels on your slider, you will then have the option to set the font of the label as well as if the slider should snap to the closest label position after the value changes. 178 | 179 | The first label will appear at the 1 o'clock position (if it were a clock). 180 | 181 | If you wanted to make your slider look like a clock, you would do the following: 182 | 183 | ```objc 184 | NSArray* hoursArray = @[@"1", @"2", @"3", @"4", @"5", @"6", @"7", @"8", @"9", @"10", @"11", @"12"]; 185 | [circularSlider setInnerMarkingLabels:hoursArray]; 186 | ``` 187 | 188 | Alarm Clock Demo Design 189 | ----------------------- 190 | 191 | The alarm clock demo design is an implemented version of a design from Micael Sambora on Dribbble and can be found [here](http://dribbble.com/shots/1293874-AlarmClock-final?list=searches&tag=alarm_clock&offset=102). 192 | 193 | More information about Michael Sambora can be found at his [personal website](http://samborek.pl/). 194 | 195 | About the developer 196 | ------------------- 197 | 198 | If you like this control, [follow @EliotFowler](http://www.twitter.com/eliotfowler) on Twitter and let me know! 199 | 200 | 201 | License (MIT) 202 | ------------- 203 | 204 | Copyright (c) 2013 Eliot Fowler 205 | 206 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 207 | 208 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 209 | 210 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /EFCircularSlider/EFCircularSlider.m: -------------------------------------------------------------------------------- 1 | // 2 | // EFCircularSlider.m 3 | // Awake 4 | // 5 | // Created by Eliot Fowler on 12/3/13. 6 | // Copyright (c) 2013 Eliot Fowler. All rights reserved. 7 | // 8 | 9 | #import "EFCircularSlider.h" 10 | #import 11 | #import 12 | 13 | #define kDefaultFontSize 14.0f; 14 | #define ToRad(deg) ( (M_PI * (deg)) / 180.0 ) 15 | #define ToDeg(rad) ( (180.0 * (rad)) / M_PI ) 16 | #define SQR(x) ( (x) * (x) ) 17 | 18 | @interface EFCircularSlider (private) 19 | 20 | @property (readonly, nonatomic) CGFloat radius; 21 | 22 | @end 23 | 24 | @implementation EFCircularSlider { 25 | int angle; 26 | int fixedAngle; 27 | NSMutableDictionary* labelsWithPercents; 28 | NSArray* labelsEvenSpacing; 29 | } 30 | 31 | - (void)defaults { 32 | // Defaults 33 | _maximumValue = 100.0f; 34 | _minimumValue = 0.0f; 35 | _currentValue = 0.0f; 36 | _lineWidth = 5; 37 | _lineRadiusDisplacement = 0; 38 | _unfilledColor = [UIColor blackColor]; 39 | _filledColor = [UIColor redColor]; 40 | _handleColor = _filledColor; 41 | _labelFont = [UIFont systemFontOfSize:10.0f]; 42 | _snapToLabels = NO; 43 | _handleType = EFSemiTransparentWhiteCircle; 44 | _labelColor = [UIColor redColor]; 45 | _labelDisplacement = 2; 46 | 47 | self.backgroundColor = [UIColor clearColor]; 48 | } 49 | 50 | - (id)initWithFrame:(CGRect)frame 51 | { 52 | self = [super initWithFrame:frame]; 53 | if (self) { 54 | [self defaults]; 55 | 56 | [self setFrame:frame]; 57 | } 58 | return self; 59 | } 60 | 61 | - (id)initWithCoder:(NSCoder *)aDecoder { 62 | if ((self=[super initWithCoder:aDecoder])){ 63 | [self defaults]; 64 | } 65 | 66 | return self; 67 | } 68 | 69 | 70 | #pragma mark - Setter/Getter 71 | 72 | - (void)setFrame:(CGRect)frame { 73 | [super setFrame:frame]; 74 | 75 | angle = [self angleFromValue]; 76 | } 77 | 78 | - (CGFloat)radius { 79 | //radius = self.frame.size.height/2 - [self circleDiameter]/2; 80 | return self.frame.size.height/2 - _lineWidth/2 - ([self circleDiameter]-_lineWidth) - _lineRadiusDisplacement; 81 | } 82 | 83 | - (void)setCurrentValue:(float)currentValue { 84 | _currentValue=currentValue; 85 | 86 | if(_currentValue>_maximumValue) _currentValue=_maximumValue; 87 | else if(_currentValue<_minimumValue) _currentValue=_minimumValue; 88 | 89 | angle = [self angleFromValue]; 90 | [self setNeedsLayout]; 91 | [self setNeedsDisplay]; 92 | [self sendActionsForControlEvents:UIControlEventValueChanged]; 93 | } 94 | 95 | #pragma mark - drawing methods 96 | 97 | - (void)drawRect:(CGRect)rect 98 | { 99 | [super drawRect:rect]; 100 | 101 | CGContextRef ctx = UIGraphicsGetCurrentContext(); 102 | 103 | //Draw the unfilled circle 104 | CGContextAddArc(ctx, self.frame.size.width/2, self.frame.size.height/2, self.radius, 0, M_PI *2, 0); 105 | [_unfilledColor setStroke]; 106 | CGContextSetLineWidth(ctx, _lineWidth); 107 | CGContextSetLineCap(ctx, kCGLineCapButt); 108 | CGContextDrawPath(ctx, kCGPathStroke); 109 | 110 | 111 | //Draw the filled circle 112 | if((_handleType == EFDoubleCircleWithClosedCenter || _handleType == EFDoubleCircleWithOpenCenter) && fixedAngle > 5) { 113 | CGContextAddArc(ctx, self.frame.size.width/2 , self.frame.size.height/2, self.radius, 3*M_PI/2, 3*M_PI/2-ToRad(angle+3), 0); 114 | } else { 115 | CGContextAddArc(ctx, self.frame.size.width/2 , self.frame.size.height/2, self.radius, 3*M_PI/2, 3*M_PI/2-ToRad(angle), 0); 116 | } 117 | [_filledColor setStroke]; 118 | CGContextSetLineWidth(ctx, _lineWidth); 119 | CGContextSetLineCap(ctx, kCGLineCapButt); 120 | CGContextDrawPath(ctx, kCGPathStroke); 121 | 122 | //Add the labels (if necessary) 123 | if(labelsEvenSpacing != nil) { 124 | [self drawLabels:ctx]; 125 | } 126 | 127 | //The draggable part 128 | [self drawHandle:ctx]; 129 | } 130 | 131 | -(void) drawHandle:(CGContextRef)ctx{ 132 | CGContextSaveGState(ctx); 133 | CGPoint handleCenter = [self pointFromAngle: angle]; 134 | if(_handleType == EFSemiTransparentWhiteCircle) { 135 | [[UIColor colorWithWhite:1.0 alpha:0.7] set]; 136 | CGContextFillEllipseInRect(ctx, CGRectMake(handleCenter.x, handleCenter.y, _lineWidth, _lineWidth)); 137 | } else if(_handleType == EFSemiTransparentBlackCircle) { 138 | [[UIColor colorWithWhite:0.0 alpha:0.7] set]; 139 | CGContextFillEllipseInRect(ctx, CGRectMake(handleCenter.x, handleCenter.y, _lineWidth, _lineWidth)); 140 | } else if(_handleType == EFDoubleCircleWithClosedCenter) { 141 | [_handleColor set]; 142 | CGContextAddArc(ctx, handleCenter.x + (_lineWidth)/2, handleCenter.y + (_lineWidth)/2, _lineWidth, 0, M_PI *2, 0); 143 | CGContextSetLineWidth(ctx, 7); 144 | CGContextSetLineCap(ctx, kCGLineCapButt); 145 | CGContextDrawPath(ctx, kCGPathStroke); 146 | 147 | CGContextFillEllipseInRect(ctx, CGRectMake(handleCenter.x, handleCenter.y, _lineWidth-1, _lineWidth-1)); 148 | } else if(_handleType == EFDoubleCircleWithOpenCenter) { 149 | [_handleColor set]; 150 | CGContextAddArc(ctx, handleCenter.x + (_lineWidth)/2, handleCenter.y + (_lineWidth)/2, _lineWidth/2 + 5, 0, M_PI *2, 0); 151 | CGContextSetLineWidth(ctx, 4); 152 | CGContextSetLineCap(ctx, kCGLineCapButt); 153 | CGContextDrawPath(ctx, kCGPathStroke); 154 | 155 | CGContextAddArc(ctx, handleCenter.x + _lineWidth/2, handleCenter.y + _lineWidth/2, _lineWidth/2, 0, M_PI *2, 0); 156 | CGContextSetLineWidth(ctx, 2); 157 | CGContextSetLineCap(ctx, kCGLineCapButt); 158 | CGContextDrawPath(ctx, kCGPathStroke); 159 | } else if(_handleType == EFBigCircle) { 160 | [_handleColor set]; 161 | CGContextFillEllipseInRect(ctx, CGRectMake(handleCenter.x-2.5, handleCenter.y-2.5, _lineWidth+5, _lineWidth+5)); 162 | } 163 | 164 | CGContextRestoreGState(ctx); 165 | } 166 | 167 | - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { 168 | CGPoint p1 = [self centerPoint]; 169 | CGPoint p2 = point; 170 | CGFloat xDist = (p2.x - p1.x); 171 | CGFloat yDist = (p2.y - p1.y); 172 | double distance = sqrt((xDist * xDist) + (yDist * yDist)); 173 | return distance < self.radius + 11; 174 | } 175 | 176 | -(void) drawLabels:(CGContextRef)ctx { 177 | if(labelsEvenSpacing == nil || [labelsEvenSpacing count] == 0) { 178 | return; 179 | } else { 180 | #if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_7_0 181 | NSDictionary *attributes = @{ NSFontAttributeName: _labelFont, 182 | NSForegroundColorAttributeName: _labelColor 183 | }; 184 | #endif 185 | 186 | CGFloat fontSize = ceilf(_labelFont.pointSize); 187 | 188 | NSInteger distanceToMove = -[self circleDiameter]/2 - fontSize/2 - _labelDisplacement; 189 | 190 | for (int i=0; i<[labelsEvenSpacing count]; i++) 191 | { 192 | NSString *label = [labelsEvenSpacing objectAtIndex:[labelsEvenSpacing count] - i - 1]; 193 | CGFloat percentageAlongCircle = i/(float)[labelsEvenSpacing count]; 194 | CGFloat degreesForLabel = percentageAlongCircle * 360; 195 | 196 | CGSize labelSize=CGSizeMake([self widthOfString:label withFont:_labelFont], [self heightOfString:label withFont:_labelFont]); 197 | CGPoint closestPointOnCircleToLabel = [self pointFromAngle:degreesForLabel withObjectSize:labelSize]; 198 | 199 | CGRect labelLocation = CGRectMake(closestPointOnCircleToLabel.x, closestPointOnCircleToLabel.y, labelSize.width, labelSize.height); 200 | 201 | CGPoint centerPoint = CGPointMake(self.frame.size.width/2, self.frame.size.height/2); 202 | float radiansTowardsCenter = ToRad(AngleFromNorth(centerPoint, closestPointOnCircleToLabel, NO)); 203 | 204 | labelLocation.origin.x = (labelLocation.origin.x + distanceToMove * cos(radiansTowardsCenter)); 205 | labelLocation.origin.y = (labelLocation.origin.y + distanceToMove * sin(radiansTowardsCenter)); 206 | 207 | #if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_7_0 208 | [label drawInRect:labelLocation withAttributes:attributes]; 209 | #else 210 | [_labelColor setFill]; 211 | [label drawInRect:labelLocation withFont:_labelFont]; 212 | #endif 213 | } 214 | } 215 | } 216 | 217 | #pragma mark - UIControl functions 218 | 219 | -(BOOL) beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event { 220 | [super beginTrackingWithTouch:touch withEvent:event]; 221 | 222 | return YES; 223 | } 224 | 225 | -(BOOL) continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event { 226 | [super continueTrackingWithTouch:touch withEvent:event]; 227 | 228 | CGPoint lastPoint = [touch locationInView:self]; 229 | [self moveHandle:lastPoint]; 230 | [self sendActionsForControlEvents:UIControlEventValueChanged]; 231 | 232 | return YES; 233 | } 234 | 235 | -(void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event{ 236 | [super endTrackingWithTouch:touch withEvent:event]; 237 | if(_snapToLabels && labelsEvenSpacing != nil) { 238 | CGFloat newAngle=0; 239 | float minDist = 360; 240 | for (int i=0; i<[labelsEvenSpacing count]; i++) { 241 | CGFloat percentageAlongCircle = i/(float)[labelsEvenSpacing count]; 242 | CGFloat degreesForLabel = percentageAlongCircle * 360; 243 | if(abs(fixedAngle - degreesForLabel) < minDist) { 244 | newAngle=degreesForLabel ? 360 - degreesForLabel : 0; 245 | minDist = abs(fixedAngle - degreesForLabel); 246 | } 247 | } 248 | angle = newAngle; 249 | _currentValue = [self valueFromAngle]; 250 | [self setNeedsDisplay]; 251 | } 252 | } 253 | 254 | -(void)moveHandle:(CGPoint)point { 255 | CGPoint centerPoint; 256 | centerPoint = [self centerPoint]; 257 | int currentAngle = floor(AngleFromNorth(centerPoint, point, NO)); 258 | angle = 360 - 90 - currentAngle; 259 | _currentValue = [self valueFromAngle]; 260 | [self setNeedsDisplay]; 261 | } 262 | 263 | - (CGPoint)centerPoint { 264 | return CGPointMake(self.frame.size.width/2, self.frame.size.height/2); 265 | } 266 | 267 | #pragma mark - helper functions 268 | 269 | -(CGPoint)pointFromAngle:(int)angleInt{ 270 | 271 | //Define the Circle center 272 | CGPoint centerPoint = CGPointMake(self.frame.size.width/2 - _lineWidth/2, self.frame.size.height/2 - _lineWidth/2); 273 | 274 | //Define The point position on the circumference 275 | CGPoint result; 276 | result.y = round(centerPoint.y + self.radius * sin(ToRad(-angleInt-90))) ; 277 | result.x = round(centerPoint.x + self.radius * cos(ToRad(-angleInt-90))); 278 | 279 | return result; 280 | } 281 | 282 | -(CGPoint)pointFromAngle:(int)angleInt withObjectSize:(CGSize)size{ 283 | 284 | //Define the Circle center 285 | CGPoint centerPoint = CGPointMake(self.frame.size.width/2 - size.width/2, self.frame.size.height/2 - size.height/2); 286 | 287 | //Define The point position on the circumference 288 | CGPoint result; 289 | result.y = round(centerPoint.y + self.radius * sin(ToRad(-angleInt-90))) ; 290 | result.x = round(centerPoint.x + self.radius * cos(ToRad(-angleInt-90))); 291 | 292 | return result; 293 | } 294 | 295 | - (CGFloat)circleDiameter { 296 | if(_handleType == EFSemiTransparentWhiteCircle) { 297 | return _lineWidth; 298 | } else if(_handleType == EFSemiTransparentBlackCircle) { 299 | return _lineWidth; 300 | } else if(_handleType == EFDoubleCircleWithClosedCenter) { 301 | return _lineWidth * 2 + 3.5; 302 | } else if(_handleType == EFDoubleCircleWithOpenCenter) { 303 | return _lineWidth + 2.5 + 2; 304 | } else if(_handleType == EFBigCircle) { 305 | return _lineWidth + 2.5; 306 | } 307 | return 0; 308 | } 309 | 310 | static inline float AngleFromNorth(CGPoint p1, CGPoint p2, BOOL flipped) { 311 | CGPoint v = CGPointMake(p2.x-p1.x,p2.y-p1.y); 312 | float vmag = sqrt(SQR(v.x) + SQR(v.y)), result = 0; 313 | v.x /= vmag; 314 | v.y /= vmag; 315 | double radians = atan2(v.y,v.x); 316 | result = ToDeg(radians); 317 | return (result >=0 ? result : result + 360.0); 318 | } 319 | 320 | -(float) valueFromAngle { 321 | if(angle < 0) { 322 | _currentValue = -angle; 323 | } else { 324 | _currentValue = 270 - angle + 90; 325 | } 326 | fixedAngle = _currentValue; 327 | return (_currentValue*(_maximumValue - _minimumValue))/360.0f; 328 | } 329 | 330 | - (float)angleFromValue { 331 | angle = 360 - (360.0f*_currentValue/_maximumValue); 332 | 333 | if(angle==360) angle=0; 334 | 335 | return angle; 336 | } 337 | 338 | - (CGFloat) widthOfString:(NSString *)string withFont:(UIFont*)font { 339 | NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName, nil]; 340 | return [[[NSAttributedString alloc] initWithString:string attributes:attributes] size].width; 341 | } 342 | 343 | - (CGFloat) heightOfString:(NSString *)string withFont:(UIFont*)font { 344 | NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName, nil]; 345 | return [[[NSAttributedString alloc] initWithString:string attributes:attributes] size].height; 346 | } 347 | 348 | #pragma mark - public methods 349 | -(void)setInnerMarkingLabels:(NSArray*)labels{ 350 | labelsEvenSpacing = labels; 351 | [self setNeedsDisplay]; 352 | } 353 | 354 | @end 355 | -------------------------------------------------------------------------------- /ExampleProject/EFCircularSlider.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 2638776D1857686D00069D17 /* EFCircularSlider.m in Sources */ = {isa = PBXBuildFile; fileRef = 2638776C1857686D00069D17 /* EFCircularSlider.m */; }; 11 | 73AA222A184F85BF0019641B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73AA2229184F85BF0019641B /* Foundation.framework */; }; 12 | 73AA222C184F85BF0019641B /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73AA222B184F85BF0019641B /* CoreGraphics.framework */; }; 13 | 73AA222E184F85BF0019641B /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73AA222D184F85BF0019641B /* UIKit.framework */; }; 14 | 73AA2234184F85BF0019641B /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 73AA2232184F85BF0019641B /* InfoPlist.strings */; }; 15 | 73AA2236184F85BF0019641B /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 73AA2235184F85BF0019641B /* main.m */; }; 16 | 73AA223A184F85BF0019641B /* EFAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 73AA2239184F85BF0019641B /* EFAppDelegate.m */; }; 17 | 73AA223D184F85BF0019641B /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 73AA223B184F85BF0019641B /* Main.storyboard */; }; 18 | 73AA2240184F85BF0019641B /* EFBasicViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 73AA223F184F85BF0019641B /* EFBasicViewController.m */; }; 19 | 73AA2242184F85BF0019641B /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 73AA2241184F85BF0019641B /* Images.xcassets */; }; 20 | 73AA2249184F85BF0019641B /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73AA2248184F85BF0019641B /* XCTest.framework */; }; 21 | 73AA224A184F85BF0019641B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73AA2229184F85BF0019641B /* Foundation.framework */; }; 22 | 73AA224B184F85BF0019641B /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73AA222D184F85BF0019641B /* UIKit.framework */; }; 23 | 73AA2253184F85BF0019641B /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 73AA2251184F85BF0019641B /* InfoPlist.strings */; }; 24 | 73AA2255184F85BF0019641B /* EFCircularSliderTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 73AA2254184F85BF0019641B /* EFCircularSliderTests.m */; }; 25 | 73AA22731850F3720019641B /* EFDemoListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 73AA22721850F3720019641B /* EFDemoListViewController.m */; }; 26 | 73AA2276185100B70019641B /* EFBigCircleHandleViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 73AA2275185100B70019641B /* EFBigCircleHandleViewController.m */; }; 27 | 73AA2279185101F60019641B /* EFDoubleCircleViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 73AA2278185101F60019641B /* EFDoubleCircleViewController.m */; }; 28 | 73AA227C185102560019641B /* EFWithLabelsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 73AA227B185102560019641B /* EFWithLabelsViewController.m */; }; 29 | 73AA227F1851030B0019641B /* EFSnapToLabelsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 73AA227E1851030B0019641B /* EFSnapToLabelsViewController.m */; }; 30 | 73AA2282185103BC0019641B /* EFTimePickerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 73AA2281185103BC0019641B /* EFTimePickerViewController.m */; }; 31 | 9F44EB0418DC32FD00CA0945 /* EFBigLineViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F44EB0318DC32FD00CA0945 /* EFBigLineViewController.m */; }; 32 | 9F44EB0618DC365400CA0945 /* label_position.png in Resources */ = {isa = PBXBuildFile; fileRef = 9F44EB0518DC365400CA0945 /* label_position.png */; }; 33 | /* End PBXBuildFile section */ 34 | 35 | /* Begin PBXContainerItemProxy section */ 36 | 73AA224C184F85BF0019641B /* PBXContainerItemProxy */ = { 37 | isa = PBXContainerItemProxy; 38 | containerPortal = 73AA221E184F85BF0019641B /* Project object */; 39 | proxyType = 1; 40 | remoteGlobalIDString = 73AA2225184F85BF0019641B; 41 | remoteInfo = EFCircularSlider; 42 | }; 43 | /* End PBXContainerItemProxy section */ 44 | 45 | /* Begin PBXFileReference section */ 46 | 2638776B1857686D00069D17 /* EFCircularSlider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EFCircularSlider.h; sourceTree = ""; }; 47 | 2638776C1857686D00069D17 /* EFCircularSlider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EFCircularSlider.m; sourceTree = ""; }; 48 | 73AA2226184F85BF0019641B /* EFCircularSlider.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = EFCircularSlider.app; sourceTree = BUILT_PRODUCTS_DIR; }; 49 | 73AA2229184F85BF0019641B /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 50 | 73AA222B184F85BF0019641B /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 51 | 73AA222D184F85BF0019641B /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 52 | 73AA2231184F85BF0019641B /* EFCircularSlider-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "EFCircularSlider-Info.plist"; sourceTree = ""; }; 53 | 73AA2233184F85BF0019641B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 54 | 73AA2235184F85BF0019641B /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 55 | 73AA2237184F85BF0019641B /* EFCircularSlider-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "EFCircularSlider-Prefix.pch"; sourceTree = ""; }; 56 | 73AA2238184F85BF0019641B /* EFAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EFAppDelegate.h; sourceTree = ""; }; 57 | 73AA2239184F85BF0019641B /* EFAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EFAppDelegate.m; sourceTree = ""; }; 58 | 73AA223C184F85BF0019641B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 59 | 73AA223E184F85BF0019641B /* EFBasicViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EFBasicViewController.h; sourceTree = ""; }; 60 | 73AA223F184F85BF0019641B /* EFBasicViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EFBasicViewController.m; sourceTree = ""; }; 61 | 73AA2241184F85BF0019641B /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 62 | 73AA2247184F85BF0019641B /* EFCircularSliderTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = EFCircularSliderTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 63 | 73AA2248184F85BF0019641B /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 64 | 73AA2250184F85BF0019641B /* EFCircularSliderTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "EFCircularSliderTests-Info.plist"; sourceTree = ""; }; 65 | 73AA2252184F85BF0019641B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 66 | 73AA2254184F85BF0019641B /* EFCircularSliderTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EFCircularSliderTests.m; sourceTree = ""; }; 67 | 73AA22711850F3720019641B /* EFDemoListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EFDemoListViewController.h; sourceTree = ""; }; 68 | 73AA22721850F3720019641B /* EFDemoListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EFDemoListViewController.m; sourceTree = ""; }; 69 | 73AA2274185100B70019641B /* EFBigCircleHandleViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EFBigCircleHandleViewController.h; sourceTree = ""; }; 70 | 73AA2275185100B70019641B /* EFBigCircleHandleViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EFBigCircleHandleViewController.m; sourceTree = ""; }; 71 | 73AA2277185101F60019641B /* EFDoubleCircleViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EFDoubleCircleViewController.h; sourceTree = ""; }; 72 | 73AA2278185101F60019641B /* EFDoubleCircleViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EFDoubleCircleViewController.m; sourceTree = ""; }; 73 | 73AA227A185102560019641B /* EFWithLabelsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EFWithLabelsViewController.h; sourceTree = ""; }; 74 | 73AA227B185102560019641B /* EFWithLabelsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EFWithLabelsViewController.m; sourceTree = ""; }; 75 | 73AA227D1851030B0019641B /* EFSnapToLabelsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EFSnapToLabelsViewController.h; sourceTree = ""; }; 76 | 73AA227E1851030B0019641B /* EFSnapToLabelsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EFSnapToLabelsViewController.m; sourceTree = ""; }; 77 | 73AA2280185103BC0019641B /* EFTimePickerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EFTimePickerViewController.h; sourceTree = ""; }; 78 | 73AA2281185103BC0019641B /* EFTimePickerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EFTimePickerViewController.m; sourceTree = ""; }; 79 | 9F44EB0218DC32FD00CA0945 /* EFBigLineViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EFBigLineViewController.h; sourceTree = ""; }; 80 | 9F44EB0318DC32FD00CA0945 /* EFBigLineViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EFBigLineViewController.m; sourceTree = ""; }; 81 | 9F44EB0518DC365400CA0945 /* label_position.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = label_position.png; sourceTree = ""; }; 82 | /* End PBXFileReference section */ 83 | 84 | /* Begin PBXFrameworksBuildPhase section */ 85 | 73AA2223184F85BF0019641B /* Frameworks */ = { 86 | isa = PBXFrameworksBuildPhase; 87 | buildActionMask = 2147483647; 88 | files = ( 89 | 73AA222C184F85BF0019641B /* CoreGraphics.framework in Frameworks */, 90 | 73AA222E184F85BF0019641B /* UIKit.framework in Frameworks */, 91 | 73AA222A184F85BF0019641B /* Foundation.framework in Frameworks */, 92 | ); 93 | runOnlyForDeploymentPostprocessing = 0; 94 | }; 95 | 73AA2244184F85BF0019641B /* Frameworks */ = { 96 | isa = PBXFrameworksBuildPhase; 97 | buildActionMask = 2147483647; 98 | files = ( 99 | 73AA2249184F85BF0019641B /* XCTest.framework in Frameworks */, 100 | 73AA224B184F85BF0019641B /* UIKit.framework in Frameworks */, 101 | 73AA224A184F85BF0019641B /* Foundation.framework in Frameworks */, 102 | ); 103 | runOnlyForDeploymentPostprocessing = 0; 104 | }; 105 | /* End PBXFrameworksBuildPhase section */ 106 | 107 | /* Begin PBXGroup section */ 108 | 2638776A1857686D00069D17 /* EFCircularSlider */ = { 109 | isa = PBXGroup; 110 | children = ( 111 | 2638776B1857686D00069D17 /* EFCircularSlider.h */, 112 | 2638776C1857686D00069D17 /* EFCircularSlider.m */, 113 | ); 114 | name = EFCircularSlider; 115 | path = ../../EFCircularSlider; 116 | sourceTree = ""; 117 | }; 118 | 73AA221D184F85BF0019641B = { 119 | isa = PBXGroup; 120 | children = ( 121 | 73AA222F184F85BF0019641B /* EFCircularSlider */, 122 | 73AA224E184F85BF0019641B /* EFCircularSliderTests */, 123 | 73AA2228184F85BF0019641B /* Frameworks */, 124 | 73AA2227184F85BF0019641B /* Products */, 125 | ); 126 | sourceTree = ""; 127 | }; 128 | 73AA2227184F85BF0019641B /* Products */ = { 129 | isa = PBXGroup; 130 | children = ( 131 | 73AA2226184F85BF0019641B /* EFCircularSlider.app */, 132 | 73AA2247184F85BF0019641B /* EFCircularSliderTests.xctest */, 133 | ); 134 | name = Products; 135 | sourceTree = ""; 136 | }; 137 | 73AA2228184F85BF0019641B /* Frameworks */ = { 138 | isa = PBXGroup; 139 | children = ( 140 | 73AA2229184F85BF0019641B /* Foundation.framework */, 141 | 73AA222B184F85BF0019641B /* CoreGraphics.framework */, 142 | 73AA222D184F85BF0019641B /* UIKit.framework */, 143 | 73AA2248184F85BF0019641B /* XCTest.framework */, 144 | ); 145 | name = Frameworks; 146 | sourceTree = ""; 147 | }; 148 | 73AA222F184F85BF0019641B /* EFCircularSlider */ = { 149 | isa = PBXGroup; 150 | children = ( 151 | 2638776A1857686D00069D17 /* EFCircularSlider */, 152 | 73AA223B184F85BF0019641B /* Main.storyboard */, 153 | 73AA2241184F85BF0019641B /* Images.xcassets */, 154 | 9F44EB0518DC365400CA0945 /* label_position.png */, 155 | 73AA22701850F3340019641B /* ViewControllers */, 156 | 73AA2230184F85BF0019641B /* Supporting Files */, 157 | ); 158 | path = EFCircularSlider; 159 | sourceTree = ""; 160 | }; 161 | 73AA2230184F85BF0019641B /* Supporting Files */ = { 162 | isa = PBXGroup; 163 | children = ( 164 | 73AA2238184F85BF0019641B /* EFAppDelegate.h */, 165 | 73AA2239184F85BF0019641B /* EFAppDelegate.m */, 166 | 73AA2231184F85BF0019641B /* EFCircularSlider-Info.plist */, 167 | 73AA2232184F85BF0019641B /* InfoPlist.strings */, 168 | 73AA2235184F85BF0019641B /* main.m */, 169 | 73AA2237184F85BF0019641B /* EFCircularSlider-Prefix.pch */, 170 | ); 171 | name = "Supporting Files"; 172 | sourceTree = ""; 173 | }; 174 | 73AA224E184F85BF0019641B /* EFCircularSliderTests */ = { 175 | isa = PBXGroup; 176 | children = ( 177 | 73AA2254184F85BF0019641B /* EFCircularSliderTests.m */, 178 | 73AA224F184F85BF0019641B /* Supporting Files */, 179 | ); 180 | path = EFCircularSliderTests; 181 | sourceTree = ""; 182 | }; 183 | 73AA224F184F85BF0019641B /* Supporting Files */ = { 184 | isa = PBXGroup; 185 | children = ( 186 | 73AA2250184F85BF0019641B /* EFCircularSliderTests-Info.plist */, 187 | 73AA2251184F85BF0019641B /* InfoPlist.strings */, 188 | ); 189 | name = "Supporting Files"; 190 | sourceTree = ""; 191 | }; 192 | 73AA22701850F3340019641B /* ViewControllers */ = { 193 | isa = PBXGroup; 194 | children = ( 195 | 73AA223E184F85BF0019641B /* EFBasicViewController.h */, 196 | 73AA223F184F85BF0019641B /* EFBasicViewController.m */, 197 | 73AA2274185100B70019641B /* EFBigCircleHandleViewController.h */, 198 | 73AA2275185100B70019641B /* EFBigCircleHandleViewController.m */, 199 | 73AA22711850F3720019641B /* EFDemoListViewController.h */, 200 | 73AA22721850F3720019641B /* EFDemoListViewController.m */, 201 | 73AA2277185101F60019641B /* EFDoubleCircleViewController.h */, 202 | 73AA2278185101F60019641B /* EFDoubleCircleViewController.m */, 203 | 73AA227A185102560019641B /* EFWithLabelsViewController.h */, 204 | 73AA227B185102560019641B /* EFWithLabelsViewController.m */, 205 | 9F44EB0218DC32FD00CA0945 /* EFBigLineViewController.h */, 206 | 9F44EB0318DC32FD00CA0945 /* EFBigLineViewController.m */, 207 | 73AA227D1851030B0019641B /* EFSnapToLabelsViewController.h */, 208 | 73AA227E1851030B0019641B /* EFSnapToLabelsViewController.m */, 209 | 73AA2280185103BC0019641B /* EFTimePickerViewController.h */, 210 | 73AA2281185103BC0019641B /* EFTimePickerViewController.m */, 211 | ); 212 | name = ViewControllers; 213 | sourceTree = ""; 214 | }; 215 | /* End PBXGroup section */ 216 | 217 | /* Begin PBXNativeTarget section */ 218 | 73AA2225184F85BF0019641B /* EFCircularSlider */ = { 219 | isa = PBXNativeTarget; 220 | buildConfigurationList = 73AA2258184F85BF0019641B /* Build configuration list for PBXNativeTarget "EFCircularSlider" */; 221 | buildPhases = ( 222 | 73AA2222184F85BF0019641B /* Sources */, 223 | 73AA2223184F85BF0019641B /* Frameworks */, 224 | 73AA2224184F85BF0019641B /* Resources */, 225 | ); 226 | buildRules = ( 227 | ); 228 | dependencies = ( 229 | ); 230 | name = EFCircularSlider; 231 | productName = EFCircularSlider; 232 | productReference = 73AA2226184F85BF0019641B /* EFCircularSlider.app */; 233 | productType = "com.apple.product-type.application"; 234 | }; 235 | 73AA2246184F85BF0019641B /* EFCircularSliderTests */ = { 236 | isa = PBXNativeTarget; 237 | buildConfigurationList = 73AA225B184F85BF0019641B /* Build configuration list for PBXNativeTarget "EFCircularSliderTests" */; 238 | buildPhases = ( 239 | 73AA2243184F85BF0019641B /* Sources */, 240 | 73AA2244184F85BF0019641B /* Frameworks */, 241 | 73AA2245184F85BF0019641B /* Resources */, 242 | ); 243 | buildRules = ( 244 | ); 245 | dependencies = ( 246 | 73AA224D184F85BF0019641B /* PBXTargetDependency */, 247 | ); 248 | name = EFCircularSliderTests; 249 | productName = EFCircularSliderTests; 250 | productReference = 73AA2247184F85BF0019641B /* EFCircularSliderTests.xctest */; 251 | productType = "com.apple.product-type.bundle.unit-test"; 252 | }; 253 | /* End PBXNativeTarget section */ 254 | 255 | /* Begin PBXProject section */ 256 | 73AA221E184F85BF0019641B /* Project object */ = { 257 | isa = PBXProject; 258 | attributes = { 259 | CLASSPREFIX = EF; 260 | LastUpgradeCheck = 0500; 261 | ORGANIZATIONNAME = "Eliot Fowler"; 262 | TargetAttributes = { 263 | 73AA2225184F85BF0019641B = { 264 | DevelopmentTeam = 99RZ6CD595; 265 | }; 266 | 73AA2246184F85BF0019641B = { 267 | TestTargetID = 73AA2225184F85BF0019641B; 268 | }; 269 | }; 270 | }; 271 | buildConfigurationList = 73AA2221184F85BF0019641B /* Build configuration list for PBXProject "EFCircularSlider" */; 272 | compatibilityVersion = "Xcode 3.2"; 273 | developmentRegion = English; 274 | hasScannedForEncodings = 0; 275 | knownRegions = ( 276 | en, 277 | Base, 278 | ); 279 | mainGroup = 73AA221D184F85BF0019641B; 280 | productRefGroup = 73AA2227184F85BF0019641B /* Products */; 281 | projectDirPath = ""; 282 | projectRoot = ""; 283 | targets = ( 284 | 73AA2225184F85BF0019641B /* EFCircularSlider */, 285 | 73AA2246184F85BF0019641B /* EFCircularSliderTests */, 286 | ); 287 | }; 288 | /* End PBXProject section */ 289 | 290 | /* Begin PBXResourcesBuildPhase section */ 291 | 73AA2224184F85BF0019641B /* Resources */ = { 292 | isa = PBXResourcesBuildPhase; 293 | buildActionMask = 2147483647; 294 | files = ( 295 | 73AA2242184F85BF0019641B /* Images.xcassets in Resources */, 296 | 9F44EB0618DC365400CA0945 /* label_position.png in Resources */, 297 | 73AA2234184F85BF0019641B /* InfoPlist.strings in Resources */, 298 | 73AA223D184F85BF0019641B /* Main.storyboard in Resources */, 299 | ); 300 | runOnlyForDeploymentPostprocessing = 0; 301 | }; 302 | 73AA2245184F85BF0019641B /* Resources */ = { 303 | isa = PBXResourcesBuildPhase; 304 | buildActionMask = 2147483647; 305 | files = ( 306 | 73AA2253184F85BF0019641B /* InfoPlist.strings in Resources */, 307 | ); 308 | runOnlyForDeploymentPostprocessing = 0; 309 | }; 310 | /* End PBXResourcesBuildPhase section */ 311 | 312 | /* Begin PBXSourcesBuildPhase section */ 313 | 73AA2222184F85BF0019641B /* Sources */ = { 314 | isa = PBXSourcesBuildPhase; 315 | buildActionMask = 2147483647; 316 | files = ( 317 | 73AA227C185102560019641B /* EFWithLabelsViewController.m in Sources */, 318 | 73AA2276185100B70019641B /* EFBigCircleHandleViewController.m in Sources */, 319 | 73AA2282185103BC0019641B /* EFTimePickerViewController.m in Sources */, 320 | 73AA227F1851030B0019641B /* EFSnapToLabelsViewController.m in Sources */, 321 | 9F44EB0418DC32FD00CA0945 /* EFBigLineViewController.m in Sources */, 322 | 73AA2279185101F60019641B /* EFDoubleCircleViewController.m in Sources */, 323 | 73AA2240184F85BF0019641B /* EFBasicViewController.m in Sources */, 324 | 73AA2236184F85BF0019641B /* main.m in Sources */, 325 | 73AA22731850F3720019641B /* EFDemoListViewController.m in Sources */, 326 | 2638776D1857686D00069D17 /* EFCircularSlider.m in Sources */, 327 | 73AA223A184F85BF0019641B /* EFAppDelegate.m in Sources */, 328 | ); 329 | runOnlyForDeploymentPostprocessing = 0; 330 | }; 331 | 73AA2243184F85BF0019641B /* Sources */ = { 332 | isa = PBXSourcesBuildPhase; 333 | buildActionMask = 2147483647; 334 | files = ( 335 | 73AA2255184F85BF0019641B /* EFCircularSliderTests.m in Sources */, 336 | ); 337 | runOnlyForDeploymentPostprocessing = 0; 338 | }; 339 | /* End PBXSourcesBuildPhase section */ 340 | 341 | /* Begin PBXTargetDependency section */ 342 | 73AA224D184F85BF0019641B /* PBXTargetDependency */ = { 343 | isa = PBXTargetDependency; 344 | target = 73AA2225184F85BF0019641B /* EFCircularSlider */; 345 | targetProxy = 73AA224C184F85BF0019641B /* PBXContainerItemProxy */; 346 | }; 347 | /* End PBXTargetDependency section */ 348 | 349 | /* Begin PBXVariantGroup section */ 350 | 73AA2232184F85BF0019641B /* InfoPlist.strings */ = { 351 | isa = PBXVariantGroup; 352 | children = ( 353 | 73AA2233184F85BF0019641B /* en */, 354 | ); 355 | name = InfoPlist.strings; 356 | sourceTree = ""; 357 | }; 358 | 73AA223B184F85BF0019641B /* Main.storyboard */ = { 359 | isa = PBXVariantGroup; 360 | children = ( 361 | 73AA223C184F85BF0019641B /* Base */, 362 | ); 363 | name = Main.storyboard; 364 | sourceTree = ""; 365 | }; 366 | 73AA2251184F85BF0019641B /* InfoPlist.strings */ = { 367 | isa = PBXVariantGroup; 368 | children = ( 369 | 73AA2252184F85BF0019641B /* en */, 370 | ); 371 | name = InfoPlist.strings; 372 | sourceTree = ""; 373 | }; 374 | /* End PBXVariantGroup section */ 375 | 376 | /* Begin XCBuildConfiguration section */ 377 | 73AA2256184F85BF0019641B /* Debug */ = { 378 | isa = XCBuildConfiguration; 379 | buildSettings = { 380 | ALWAYS_SEARCH_USER_PATHS = NO; 381 | ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; 382 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 383 | CLANG_CXX_LIBRARY = "libc++"; 384 | CLANG_ENABLE_MODULES = YES; 385 | CLANG_ENABLE_OBJC_ARC = YES; 386 | CLANG_WARN_BOOL_CONVERSION = YES; 387 | CLANG_WARN_CONSTANT_CONVERSION = YES; 388 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 389 | CLANG_WARN_EMPTY_BODY = YES; 390 | CLANG_WARN_ENUM_CONVERSION = YES; 391 | CLANG_WARN_INT_CONVERSION = YES; 392 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 393 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 394 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 395 | COPY_PHASE_STRIP = NO; 396 | GCC_C_LANGUAGE_STANDARD = gnu99; 397 | GCC_DYNAMIC_NO_PIC = NO; 398 | GCC_OPTIMIZATION_LEVEL = 0; 399 | GCC_PREPROCESSOR_DEFINITIONS = ( 400 | "DEBUG=1", 401 | "$(inherited)", 402 | ); 403 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 404 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 405 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 406 | GCC_WARN_UNDECLARED_SELECTOR = YES; 407 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 408 | GCC_WARN_UNUSED_FUNCTION = YES; 409 | GCC_WARN_UNUSED_VARIABLE = YES; 410 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 411 | ONLY_ACTIVE_ARCH = YES; 412 | SDKROOT = iphoneos; 413 | }; 414 | name = Debug; 415 | }; 416 | 73AA2257184F85BF0019641B /* Release */ = { 417 | isa = XCBuildConfiguration; 418 | buildSettings = { 419 | ALWAYS_SEARCH_USER_PATHS = NO; 420 | ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; 421 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 422 | CLANG_CXX_LIBRARY = "libc++"; 423 | CLANG_ENABLE_MODULES = YES; 424 | CLANG_ENABLE_OBJC_ARC = YES; 425 | CLANG_WARN_BOOL_CONVERSION = YES; 426 | CLANG_WARN_CONSTANT_CONVERSION = YES; 427 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 428 | CLANG_WARN_EMPTY_BODY = YES; 429 | CLANG_WARN_ENUM_CONVERSION = YES; 430 | CLANG_WARN_INT_CONVERSION = YES; 431 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 432 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 433 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 434 | COPY_PHASE_STRIP = YES; 435 | ENABLE_NS_ASSERTIONS = NO; 436 | GCC_C_LANGUAGE_STANDARD = gnu99; 437 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 438 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 439 | GCC_WARN_UNDECLARED_SELECTOR = YES; 440 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 441 | GCC_WARN_UNUSED_FUNCTION = YES; 442 | GCC_WARN_UNUSED_VARIABLE = YES; 443 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 444 | SDKROOT = iphoneos; 445 | VALIDATE_PRODUCT = YES; 446 | }; 447 | name = Release; 448 | }; 449 | 73AA2259184F85BF0019641B /* Debug */ = { 450 | isa = XCBuildConfiguration; 451 | buildSettings = { 452 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 453 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 454 | CODE_SIGN_IDENTITY = "iPhone Developer"; 455 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 456 | GCC_PREFIX_HEADER = "EFCircularSlider/EFCircularSlider-Prefix.pch"; 457 | INFOPLIST_FILE = "EFCircularSlider/EFCircularSlider-Info.plist"; 458 | PRODUCT_NAME = "$(TARGET_NAME)"; 459 | WRAPPER_EXTENSION = app; 460 | }; 461 | name = Debug; 462 | }; 463 | 73AA225A184F85BF0019641B /* Release */ = { 464 | isa = XCBuildConfiguration; 465 | buildSettings = { 466 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 467 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 468 | CODE_SIGN_IDENTITY = "iPhone Developer"; 469 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 470 | GCC_PREFIX_HEADER = "EFCircularSlider/EFCircularSlider-Prefix.pch"; 471 | INFOPLIST_FILE = "EFCircularSlider/EFCircularSlider-Info.plist"; 472 | PRODUCT_NAME = "$(TARGET_NAME)"; 473 | WRAPPER_EXTENSION = app; 474 | }; 475 | name = Release; 476 | }; 477 | 73AA225C184F85BF0019641B /* Debug */ = { 478 | isa = XCBuildConfiguration; 479 | buildSettings = { 480 | ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; 481 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/EFCircularSlider.app/EFCircularSlider"; 482 | FRAMEWORK_SEARCH_PATHS = ( 483 | "$(SDKROOT)/Developer/Library/Frameworks", 484 | "$(inherited)", 485 | "$(DEVELOPER_FRAMEWORKS_DIR)", 486 | ); 487 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 488 | GCC_PREFIX_HEADER = "EFCircularSlider/EFCircularSlider-Prefix.pch"; 489 | GCC_PREPROCESSOR_DEFINITIONS = ( 490 | "DEBUG=1", 491 | "$(inherited)", 492 | ); 493 | INFOPLIST_FILE = "EFCircularSliderTests/EFCircularSliderTests-Info.plist"; 494 | PRODUCT_NAME = "$(TARGET_NAME)"; 495 | TEST_HOST = "$(BUNDLE_LOADER)"; 496 | WRAPPER_EXTENSION = xctest; 497 | }; 498 | name = Debug; 499 | }; 500 | 73AA225D184F85BF0019641B /* Release */ = { 501 | isa = XCBuildConfiguration; 502 | buildSettings = { 503 | ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; 504 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/EFCircularSlider.app/EFCircularSlider"; 505 | FRAMEWORK_SEARCH_PATHS = ( 506 | "$(SDKROOT)/Developer/Library/Frameworks", 507 | "$(inherited)", 508 | "$(DEVELOPER_FRAMEWORKS_DIR)", 509 | ); 510 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 511 | GCC_PREFIX_HEADER = "EFCircularSlider/EFCircularSlider-Prefix.pch"; 512 | INFOPLIST_FILE = "EFCircularSliderTests/EFCircularSliderTests-Info.plist"; 513 | PRODUCT_NAME = "$(TARGET_NAME)"; 514 | TEST_HOST = "$(BUNDLE_LOADER)"; 515 | WRAPPER_EXTENSION = xctest; 516 | }; 517 | name = Release; 518 | }; 519 | /* End XCBuildConfiguration section */ 520 | 521 | /* Begin XCConfigurationList section */ 522 | 73AA2221184F85BF0019641B /* Build configuration list for PBXProject "EFCircularSlider" */ = { 523 | isa = XCConfigurationList; 524 | buildConfigurations = ( 525 | 73AA2256184F85BF0019641B /* Debug */, 526 | 73AA2257184F85BF0019641B /* Release */, 527 | ); 528 | defaultConfigurationIsVisible = 0; 529 | defaultConfigurationName = Release; 530 | }; 531 | 73AA2258184F85BF0019641B /* Build configuration list for PBXNativeTarget "EFCircularSlider" */ = { 532 | isa = XCConfigurationList; 533 | buildConfigurations = ( 534 | 73AA2259184F85BF0019641B /* Debug */, 535 | 73AA225A184F85BF0019641B /* Release */, 536 | ); 537 | defaultConfigurationIsVisible = 0; 538 | defaultConfigurationName = Release; 539 | }; 540 | 73AA225B184F85BF0019641B /* Build configuration list for PBXNativeTarget "EFCircularSliderTests" */ = { 541 | isa = XCConfigurationList; 542 | buildConfigurations = ( 543 | 73AA225C184F85BF0019641B /* Debug */, 544 | 73AA225D184F85BF0019641B /* Release */, 545 | ); 546 | defaultConfigurationIsVisible = 0; 547 | defaultConfigurationName = Release; 548 | }; 549 | /* End XCConfigurationList section */ 550 | }; 551 | rootObject = 73AA221E184F85BF0019641B /* Project object */; 552 | } 553 | -------------------------------------------------------------------------------- /ExampleProject/EFCircularSlider/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | --------------------------------------------------------------------------------