├── image.png
├── example-animated.gif
├── NYSegmentedControlDemo
├── NYSegmentedControlDemo
│ ├── en.lproj
│ │ └── InfoPlist.strings
│ ├── DemoViewController.h
│ ├── AppDelegate.h
│ ├── main.m
│ ├── NYSegmentedControlDemo-Prefix.pch
│ ├── Images.xcassets
│ │ ├── LaunchImage.launchimage
│ │ │ └── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── AppDelegate.m
│ ├── NYSegmentedControlDemo-Info.plist
│ ├── Launch Screen.xib
│ └── DemoViewController.m
├── NYSegmentedControlDemoTests
│ ├── en.lproj
│ │ └── InfoPlist.strings
│ ├── NYSegmentedControlDemoTests-Info.plist
│ └── NYSegmentedControlDemoTests.m
└── NYSegmentedControlDemo.xcodeproj
│ ├── project.xcworkspace
│ └── contents.xcworkspacedata
│ └── project.pbxproj
├── .gitignore
├── NYSegmentedControl
├── NYSegment.h
├── NYSegmentIndicator.h
├── NYSegmentTextRenderView.h
├── NYSegment.m
├── NYSegmentIndicator.m
├── NYSegmentTextRenderView.m
├── NYSegmentedControl.h
└── NYSegmentedControl.m
├── NYSegmentedControl.podspec
├── LICENSE.md
└── README.md
/image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nealyoung/NYSegmentedControl/HEAD/image.png
--------------------------------------------------------------------------------
/example-animated.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nealyoung/NYSegmentedControl/HEAD/example-animated.gif
--------------------------------------------------------------------------------
/NYSegmentedControlDemo/NYSegmentedControlDemo/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/NYSegmentedControlDemo/NYSegmentedControlDemoTests/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/NYSegmentedControlDemo/NYSegmentedControlDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | build/
2 | *.DS_Store
3 | *.pbxuser
4 | !default.pbxuser
5 | *.mode1v3
6 | !default.mode1v3
7 | *.mode2v3
8 | !default.mode2v3
9 | *.perspectivev3
10 | !default.perspectivev3
11 | xcuserdata
12 | *.xccheckout
13 | profile
14 | *.moved-aside
15 | DerivedData
16 | *.hmap
17 | *.ipa
18 | .idea/
19 |
--------------------------------------------------------------------------------
/NYSegmentedControl/NYSegment.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @class NYSegment;
4 | @class NYSegmentTextRenderView;
5 |
6 | @interface NYSegment : UIView
7 |
8 | @property (nonatomic) NYSegmentTextRenderView *titleLabel;
9 | @property (nonatomic) BOOL selected;
10 |
11 | - (instancetype)initWithTitle:(NSString *)title;
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/NYSegmentedControlDemo/NYSegmentedControlDemo/DemoViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // DemoViewController.h
3 | // NYSegmentedControlDemo
4 | //
5 | // Created by Nealon Young on 3/22/14.
6 | // Copyright (c) 2014 Neal Young. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface DemoViewController : UIViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/NYSegmentedControlDemo/NYSegmentedControlDemo/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // NYSegmentedControlDemo
4 | //
5 | // Created by Nealon Young on 3/22/14.
6 | // Copyright (c) 2014 Neal Young. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/NYSegmentedControl/NYSegmentIndicator.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @interface NYSegmentIndicator : UIView
4 |
5 | @property (nonatomic) CGFloat cornerRadius;
6 |
7 | @property (nonatomic) CGFloat borderWidth;
8 | @property (nonatomic) UIColor *borderColor;
9 |
10 | @property (nonatomic) BOOL drawsGradientBackground;
11 | @property (nonatomic) UIColor *gradientTopColor;
12 | @property (nonatomic) UIColor *gradientBottomColor;
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/NYSegmentedControlDemo/NYSegmentedControlDemo/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // NYSegmentedControlDemo
4 | //
5 | // Created by Nealon Young on 3/23/14.
6 | // Copyright (c) 2014 Neal Young. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "AppDelegate.h"
12 |
13 | int main(int argc, char * argv[])
14 | {
15 | @autoreleasepool {
16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/NYSegmentedControlDemo/NYSegmentedControlDemo/NYSegmentedControlDemo-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 |
--------------------------------------------------------------------------------
/NYSegmentedControlDemo/NYSegmentedControlDemo/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 | }
--------------------------------------------------------------------------------
/NYSegmentedControl/NYSegmentTextRenderView.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | NS_ASSUME_NONNULL_BEGIN
4 |
5 | @interface NYSegmentTextRenderView : UIView
6 |
7 | @property (nonatomic, strong, nullable) NSString *text;
8 |
9 | @property (nonatomic, strong) UIFont *font;
10 | @property (nonatomic, strong) UIColor *textColor;
11 |
12 | @property (nonatomic, strong) UIColor *selectedTextColor;
13 | @property (nonatomic, strong) UIFont *selectedFont;
14 |
15 | @property (nonatomic, assign) CGRect selectedTextDrawingRect;
16 | @property (nonatomic, assign) CGFloat maskCornerRadius;
17 |
18 | @end
19 |
20 | NS_ASSUME_NONNULL_END
21 |
--------------------------------------------------------------------------------
/NYSegmentedControlDemo/NYSegmentedControlDemo/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // NYSegmentedControlDemo
4 | //
5 | // Created by Nealon Young on 3/22/14.
6 | // Copyright (c) 2014 Neal Young. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 | #import "DemoViewController.h"
11 | #import "NYSegmentedControl.h"
12 |
13 | @implementation AppDelegate
14 |
15 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
16 | DemoViewController *viewController = [[DemoViewController alloc] initWithNibName:nil bundle:nil];
17 |
18 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
19 | self.window.rootViewController = viewController;
20 | [self.window makeKeyAndVisible];
21 |
22 | return YES;
23 | }
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/NYSegmentedControlDemo/NYSegmentedControlDemo/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" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/NYSegmentedControlDemo/NYSegmentedControlDemoTests/NYSegmentedControlDemoTests-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | com.nealonyoung.${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 |
--------------------------------------------------------------------------------
/NYSegmentedControlDemo/NYSegmentedControlDemoTests/NYSegmentedControlDemoTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // NYSegmentedControlDemoTests.m
3 | // NYSegmentedControlDemoTests
4 | //
5 | // Created by Nealon Young on 3/23/14.
6 | // Copyright (c) 2014 Neal Young. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NYSegmentedControlDemoTests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation NYSegmentedControlDemoTests
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 |
--------------------------------------------------------------------------------
/NYSegmentedControl.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = "NYSegmentedControl"
3 | s.version = "1.1.0"
4 | s.summary = "Animated, customizable replacement for UISegmentedControl"
5 | s.description = "NYSegmentedControl is a customizable, animated replacement for UISegmentedControl inspired by controls found in Instagram, Foursquare, and other apps."
6 | s.homepage = "https://github.com/nealyoung/NYSegmentedControl"
7 | s.screenshots = "https://github.com/nealyoung/NYSegmentedControl/raw/master/image.png"
8 | s.license = { :type => "MIT", :file => "LICENSE.md" }
9 | s.author = { "Neal Young" => "hi@nealyoung.me" }
10 | s.social_media_url = "http://nealyoung.me"
11 | s.platform = :ios, "7.0"
12 | s.source = { :git => "https://github.com/nealyoung/NYSegmentedControl.git", :tag => "#{s.version}" }
13 | s.source_files = "NYSegmentedControl/*.{h,m}"
14 | s.requires_arc = true
15 | end
16 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Nealon Young
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.
22 |
--------------------------------------------------------------------------------
/NYSegmentedControlDemo/NYSegmentedControlDemo/NYSegmentedControlDemo-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIdentifier
12 | com.nealonyoung.${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 | UILaunchStoryboardName
28 | Launch Screen
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UIStatusBarStyle
34 | UIStatusBarStyleBlackTranslucent
35 | UISupportedInterfaceOrientations
36 |
37 | UIInterfaceOrientationPortrait
38 |
39 | UIViewControllerBasedStatusBarAppearance
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/NYSegmentedControl/NYSegment.m:
--------------------------------------------------------------------------------
1 | #import "NYSegment.h"
2 | #import "NYSegmentTextRenderView.h"
3 |
4 | static CGFloat const kMinimumSegmentWidth = 64.0f;
5 |
6 | @implementation NYSegment
7 |
8 | - (instancetype)initWithTitle:(NSString *)title {
9 | self = [self initWithFrame:CGRectZero];
10 | if (self) {
11 | self.titleLabel.text = title;
12 | }
13 | return self;
14 | }
15 |
16 | - (id)initWithFrame:(CGRect)frame {
17 | self = [super initWithFrame:frame];
18 | if (self) {
19 | self.isAccessibilityElement = YES;
20 | self.accessibilityTraits = UIAccessibilityTraitButton;
21 |
22 | self.userInteractionEnabled = NO;
23 | self.titleLabel = [[NYSegmentTextRenderView alloc] initWithFrame:self.frame];
24 | self.titleLabel.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
25 | self.titleLabel.font = [UIFont systemFontOfSize:13.0f];
26 | self.titleLabel.backgroundColor = [UIColor clearColor];
27 | [self addSubview:self.titleLabel];
28 | }
29 | return self;
30 | }
31 |
32 | - (CGSize)sizeThatFits:(CGSize)size {
33 | CGSize sizeThatFits = [self.titleLabel sizeThatFits:size];
34 | return CGSizeMake(MAX(sizeThatFits.width * 1.4f, kMinimumSegmentWidth), sizeThatFits.height);
35 | }
36 |
37 | - (void)setSelected:(BOOL)selected {
38 | _selected = selected;
39 | if (selected) {
40 | self.accessibilityTraits = self.accessibilityTraits | UIAccessibilityTraitSelected;
41 | } else {
42 | self.accessibilityTraits = self.accessibilityTraits & ~UIAccessibilityTraitSelected;
43 | }
44 | }
45 |
46 | - (NSString *)accessibilityLabel {
47 | return self.titleLabel.text;
48 | }
49 |
50 | @end
51 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # NYSegmentedControl
2 |
3 | NYSegmentedControl is a customizable, animated replacement for UISegmentedControl inspired by controls found in Instagram, Foursquare, and other apps.
4 |
5 | 
6 |
7 | ### Features
8 | * Create segmented controls with animated selection indicator
9 | * Customize colors, gradients, fonts, etc. either directly or globally with UIAppearance
10 | * Configure distinct text styles for the selected segment
11 | * VoiceOver/accessibility support
12 |
13 | 
14 |
15 | ### Installation
16 | #### Manual
17 | Add the files to your project manually by dragging the NYSegmentedControl directory into your Xcode project.
18 |
19 | #### CocoaPods
20 | Add `pod 'NYSegmentedControl'` to your Podfile, and run `pod install`.
21 |
22 | ### Usage
23 | Use is largely identical to UISegmentedControl. An example project is included in the NYSegmentedControlDemo directory.
24 |
25 | ```objc
26 | // Import the class and create an NYSegmentedControl instance
27 | #import "NYSegmentedControl.h"
28 |
29 | // ...
30 |
31 | NYSegmentedControl *segmentedControl = [[NYSegmentedControl alloc] initWithItems:@[@"Segment 1", @"Segment 2"]];
32 |
33 | // Add desired targets/actions
34 | [segmentedControl addTarget:self action:@selector(segmentSelected) forControlEvents:UIControlEventValueChanged];
35 |
36 | // Customize and size the control
37 | segmentedControl.borderWidth = 1.0f;
38 | segmentedControl.borderColor = [UIColor colorWithWhite:0.15f alpha:1.0f];
39 | segmentedControl.drawsGradientBackground = YES;
40 | segmentedControl.segmentIndicatorInset = 2.0f;
41 | segmentedControl.drawsSegmentIndicatorGradientBackground = YES;
42 | segmentedControl.segmentIndicatorGradientTopColor = [UIColor colorWithRed:0.30 green:0.50 blue:0.88f alpha:1.0f];
43 | segmentedControl.segmentIndicatorGradientBottomColor = [UIColor colorWithRed:0.20 green:0.35 blue:0.75f alpha:1.0f];
44 | segmentedControl.segmentIndicatorAnimationDuration = 0.3f;
45 | segmentedControl.segmentIndicatorBorderWidth = 0.0f;
46 | [segmentedControl sizeToFit];
47 |
48 | // Add the control to your view
49 | self.navigationItem.titleView = self.segmentedControl;
50 | ```
51 |
52 | ### License
53 | This project is released under the MIT License.
54 |
--------------------------------------------------------------------------------
/NYSegmentedControl/NYSegmentIndicator.m:
--------------------------------------------------------------------------------
1 | #import "NYSegmentIndicator.h"
2 |
3 | @implementation NYSegmentIndicator
4 |
5 | + (Class)layerClass {
6 | return [CAGradientLayer class];
7 | }
8 |
9 | - (id)initWithFrame:(CGRect)frame {
10 | self = [super initWithFrame:frame];
11 | if (self) {
12 | self.layer.masksToBounds = YES;
13 | self.drawsGradientBackground = NO;
14 | self.opaque = NO;
15 | self.cornerRadius = 4.0f;
16 | self.gradientTopColor = [UIColor colorWithRed:0.27f green:0.54f blue:0.21f alpha:1.0f];
17 | self.gradientBottomColor = [UIColor colorWithRed:0.22f green:0.43f blue:0.16f alpha:1.0f];
18 | self.borderColor = [UIColor lightGrayColor];
19 | self.borderWidth = 1.0f;
20 | }
21 | return self;
22 | }
23 |
24 | - (void)drawRect:(CGRect)rect {
25 | if (self.drawsGradientBackground) {
26 | CAGradientLayer *gradientLayer = (CAGradientLayer *)self.layer;
27 | gradientLayer.colors = @[(__bridge id)[self.gradientTopColor CGColor],
28 | (__bridge id)[self.gradientBottomColor CGColor]];
29 | } else {
30 | self.layer.backgroundColor = [self.backgroundColor CGColor];
31 | }
32 | }
33 |
34 | #pragma mark - Getters and Setters
35 |
36 | - (void)setBorderColor:(UIColor *)borderColor {
37 | self.layer.borderColor = [borderColor CGColor];
38 | }
39 |
40 | - (UIColor *)borderColor {
41 | return [UIColor colorWithCGColor:self.layer.borderColor];
42 | }
43 |
44 | - (void)setBorderWidth:(CGFloat)borderWidth {
45 | self.layer.borderWidth = borderWidth;
46 | }
47 |
48 | - (CGFloat)borderWidth {
49 | return self.layer.borderWidth;
50 | }
51 |
52 | - (void)setCornerRadius:(CGFloat)cornerRadius {
53 | self.layer.cornerRadius = cornerRadius;
54 | [self setNeedsDisplay];
55 | }
56 |
57 | - (CGFloat)cornerRadius {
58 | return self.layer.cornerRadius;
59 | }
60 |
61 | - (void)setDrawsGradientBackground:(BOOL)drawsGradientBackground {
62 | _drawsGradientBackground = drawsGradientBackground;
63 | [self setNeedsDisplay];
64 | }
65 |
66 | - (void)setGradientTopColor:(UIColor *)gradientTopColor {
67 | _gradientTopColor = gradientTopColor;
68 | [self setNeedsDisplay];
69 | }
70 |
71 | - (void)setGradientBottomColor:(UIColor *)gradientBottomColor {
72 | _gradientBottomColor = gradientBottomColor;
73 | [self setNeedsDisplay];
74 | }
75 |
76 | @end
77 |
--------------------------------------------------------------------------------
/NYSegmentedControlDemo/NYSegmentedControlDemo/Launch Screen.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
23 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/NYSegmentedControl/NYSegmentTextRenderView.m:
--------------------------------------------------------------------------------
1 | #import "NYSegmentTextRenderView.h"
2 |
3 | @interface NYSegmentTextRenderView ()
4 |
5 | @property (nonatomic, strong, nonnull) NSDictionary *unselectedTextAttributes;
6 | @property (nonatomic, strong, nonnull) NSDictionary *selectedTextAttributes;
7 |
8 | @end
9 |
10 | @implementation NYSegmentTextRenderView
11 |
12 | - (instancetype)initWithFrame:(CGRect)frame {
13 | self = [super initWithFrame:frame];
14 |
15 | if (self) {
16 | _font = [UIFont systemFontOfSize:14.0f];
17 | _textColor = [UIColor darkGrayColor];
18 |
19 | _selectedTextColor = _textColor;
20 | _selectedFont = _font;
21 |
22 | [self setupSelectedAttributes];
23 | [self setupUnselectedAttributes];
24 | }
25 |
26 | return self;
27 | }
28 |
29 | - (void)drawRect:(CGRect)rect {
30 | CGContextRef context = UIGraphicsGetCurrentContext();
31 | CGContextSaveGState(context);
32 |
33 | if (!CGRectIsEmpty(self.selectedTextDrawingRect)) {
34 | CGRect beforeMaskFrame = CGRectMake(0, 0, CGRectGetMinX(self.selectedTextDrawingRect), CGRectGetHeight(self.frame));
35 | CGRect afterMaskFrame = CGRectMake(CGRectGetMaxX(self.selectedTextDrawingRect),
36 | 0,
37 | CGRectGetWidth(self.frame) - CGRectGetMaxX(self.selectedTextDrawingRect),
38 | CGRectGetHeight(self.frame));
39 | CGRect unselectedTextDrawingRects[2] = {beforeMaskFrame, afterMaskFrame};
40 | CGContextClipToRects(context, unselectedTextDrawingRects, 2);
41 | }
42 |
43 | CGFloat unselectedTextRectHeight = [self.text sizeWithAttributes:self.unselectedTextAttributes].height;
44 | CGRect unselectedTextDrawingRect = CGRectMake(rect.origin.x,
45 | rect.origin.y + (rect.size.height - unselectedTextRectHeight) / 2.0f,
46 | rect.size.width,
47 | unselectedTextRectHeight);
48 |
49 | [self.text drawInRect:unselectedTextDrawingRect withAttributes:self.unselectedTextAttributes];
50 |
51 | CGContextRestoreGState(context);
52 |
53 | if (!CGRectIsEmpty(self.selectedTextDrawingRect)) {
54 | CGFloat selectedTextRectHeight = [self.text sizeWithAttributes:self.selectedTextAttributes].height;
55 | CGRect selectedTextDrawingRect = CGRectMake(rect.origin.x,
56 | rect.origin.y + (rect.size.height - selectedTextRectHeight) / 2.0f,
57 | rect.size.width,
58 | selectedTextRectHeight);
59 | CGContextClipToRect(context, self.selectedTextDrawingRect);
60 |
61 | [self.text drawInRect:selectedTextDrawingRect withAttributes:self.selectedTextAttributes];
62 | }
63 | }
64 |
65 | - (CGSize)sizeThatFits:(CGSize)size {
66 | return [self.text sizeWithAttributes:self.unselectedTextAttributes];
67 | }
68 |
69 | #pragma mark - Private
70 |
71 | - (void)setupSelectedAttributes {
72 | NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
73 | paragraphStyle.alignment = NSTextAlignmentCenter;
74 |
75 | NSDictionary *selectedAttributes = @{ NSFontAttributeName: self.selectedFont,
76 | NSForegroundColorAttributeName: self.selectedTextColor,
77 | NSParagraphStyleAttributeName: paragraphStyle };
78 |
79 | self.selectedTextAttributes = selectedAttributes;
80 | }
81 |
82 | - (void)setupUnselectedAttributes {
83 | NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
84 | paragraphStyle.alignment = NSTextAlignmentCenter;
85 |
86 | NSDictionary *unselectedAttributes = @{ NSFontAttributeName: self.font,
87 | NSForegroundColorAttributeName: self.textColor,
88 | NSParagraphStyleAttributeName: paragraphStyle };
89 |
90 | self.unselectedTextAttributes = unselectedAttributes;
91 | }
92 |
93 | #pragma mark - Setters
94 |
95 | - (void)setSelectedTextDrawingRect:(CGRect)selectedTextDrawingRect {
96 | _selectedTextDrawingRect = selectedTextDrawingRect;
97 |
98 | [self setNeedsDisplay];
99 | }
100 |
101 | - (void)setMaskCornerRadius:(CGFloat)maskCornerRadius {
102 | _maskCornerRadius = maskCornerRadius;
103 |
104 | [self setNeedsDisplay];
105 | }
106 |
107 | - (void)setTextColor:(UIColor *)textColor {
108 | _textColor = textColor;
109 |
110 | [self setupUnselectedAttributes];
111 | }
112 |
113 | - (void)setSelectedTextColor:(UIColor *)selectedTextColor {
114 | _selectedTextColor = selectedTextColor;
115 |
116 | [self setupSelectedAttributes];
117 | }
118 |
119 | - (void)setSelectedFont:(UIFont *)selectedFont {
120 | _selectedFont = selectedFont;
121 |
122 | [self setupSelectedAttributes];
123 | }
124 |
125 | - (void)setFont:(UIFont *)font {
126 | _font = font;
127 |
128 | [self setupUnselectedAttributes];
129 | }
130 |
131 | @end
132 |
--------------------------------------------------------------------------------
/NYSegmentedControl/NYSegmentedControl.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | NS_ASSUME_NONNULL_BEGIN
4 |
5 | @class NYSegmentedControl;
6 |
7 | @protocol NYSegmentedControlDataSource
8 |
9 | - (NSUInteger)numberOfSegments:(NYSegmentedControl *)control;
10 | - (NSString *)segmentedControl:(NYSegmentedControl *)control titleForSegmentAtIndex:(NSUInteger)index;
11 |
12 | @end
13 |
14 | @interface NYSegmentedControl : UIControl
15 |
16 | /**
17 | The segmented control's data source object.
18 | */
19 | @property (nonatomic, weak, nullable) IBOutlet id dataSource;
20 |
21 | /**
22 | If YES, selectedTitleFont and selectedTitleTextColor are used for the selected segment's title label. The default value is YES.
23 | */
24 | @property (nonatomic) BOOL stylesTitleForSelectedSegment;
25 |
26 | /**
27 | The font used for the segment titles.
28 | */
29 | @property (nonatomic) UIFont *titleFont UI_APPEARANCE_SELECTOR;
30 |
31 | /**
32 | The color of the segment titles.
33 | */
34 | @property (nonatomic) UIColor *titleTextColor UI_APPEARANCE_SELECTOR;
35 |
36 | /**
37 | The font used for the selected segment's title.
38 | */
39 | @property (nonatomic) UIFont *selectedTitleFont UI_APPEARANCE_SELECTOR;
40 |
41 | /**
42 | The color of the selected segment's title.
43 | */
44 | @property (nonatomic) UIColor *selectedTitleTextColor UI_APPEARANCE_SELECTOR;
45 |
46 | /**
47 | The radius of the control's corners.
48 | */
49 | @property (nonatomic) CGFloat cornerRadius UI_APPEARANCE_SELECTOR;
50 |
51 | /**
52 | The color of the control's border.
53 | */
54 | @property (nonatomic) UIColor *borderColor UI_APPEARANCE_SELECTOR;
55 |
56 | /**
57 | The width of the control's border
58 | */
59 | @property (nonatomic) CGFloat borderWidth UI_APPEARANCE_SELECTOR;
60 |
61 | /**
62 | If YES, the control's background will be drawn with a background gradient specified by the gradientTopColor and gradientBottomColor properties. The default value is YES.
63 |
64 | @see gradientTopColor
65 | @see gradientBottomColor
66 | */
67 | @property (nonatomic) BOOL drawsGradientBackground;
68 |
69 | /**
70 | The start (top) color of the control's background gradient.
71 |
72 | @see drawsGradientBackground
73 | */
74 | @property (nonatomic) UIColor *gradientTopColor UI_APPEARANCE_SELECTOR;
75 |
76 | /**
77 | The end (bottom) color of the control's background gradient.
78 |
79 | @see drawsGradientBackground
80 | */
81 | @property (nonatomic) UIColor *gradientBottomColor UI_APPEARANCE_SELECTOR;
82 |
83 | /**
84 | The duration of the segment change animation.
85 | */
86 | @property (nonatomic) CGFloat segmentIndicatorAnimationDuration UI_APPEARANCE_SELECTOR;
87 |
88 | /**
89 | The amount the selected segment indicator should be inset from the outer edge of the control.
90 | */
91 | @property (nonatomic) CGFloat segmentIndicatorInset UI_APPEARANCE_SELECTOR;
92 |
93 | /**
94 | If YES, the selected segment indicator will be drawn with a background gradient specified by the selectedSegmentIndicatorGradientTopColor and selectedSegmentIndicatorGradientBottomColor properties. If set to NO, the indicator will be filled with the color specified by the selectedSegmentIndicatorBackgroundColor property. The default value is YES.
95 |
96 | @see segmentIndicatorGradientTopColor
97 | @see segmentIndicatorGradientBottomColor
98 | */
99 | @property (nonatomic) BOOL drawsSegmentIndicatorGradientBackground;
100 |
101 | /**
102 | The color of the selected segment indicator.
103 | */
104 | @property (nonatomic) UIColor *segmentIndicatorBackgroundColor UI_APPEARANCE_SELECTOR;
105 |
106 | /**
107 | The start color of the gradient filling the selected segment indicator.
108 |
109 | @see drawsSegmentIndicatorGradientBackground
110 | */
111 | @property (nonatomic) UIColor *segmentIndicatorGradientTopColor UI_APPEARANCE_SELECTOR;
112 |
113 | /**
114 | The end color of the gradient filling the selected segment indicator.
115 |
116 | @see drawsSegmentIndicatorGradientBackground
117 | */
118 | @property (nonatomic) UIColor *segmentIndicatorGradientBottomColor UI_APPEARANCE_SELECTOR;
119 |
120 | /**
121 | The color of the selected segment indicator's border.
122 | */
123 | @property (nonatomic) UIColor *segmentIndicatorBorderColor UI_APPEARANCE_SELECTOR;
124 |
125 | /**
126 | The width of the selected segment indicator's border.
127 | */
128 | @property (nonatomic) CGFloat segmentIndicatorBorderWidth UI_APPEARANCE_SELECTOR;
129 |
130 | /**
131 | The number of segments in the control (read-only).
132 | */
133 | @property (nonatomic, readonly) NSUInteger numberOfSegments;
134 |
135 | /**
136 | The index of the currently selected segment.
137 | */
138 | @property (nonatomic) NSUInteger selectedSegmentIndex;
139 |
140 | #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_7_0
141 |
142 | /**
143 | If set to YES, UIView spring animations will be used to animate the position of the segment indicator.
144 | */
145 | @property (nonatomic) BOOL usesSpringAnimations UI_APPEARANCE_SELECTOR;
146 |
147 | /**
148 | The animation duration used if spring animations are enabled.
149 |
150 | @see usesSpringAnimations
151 | */
152 | @property (nonatomic) CGFloat springAnimationDuration UI_APPEARANCE_SELECTOR;
153 |
154 | /**
155 | The damping ratio for the spring animation used if spring animations are enabled.
156 |
157 | @see usesSpringAnimations
158 | */
159 | @property (nonatomic) CGFloat springAnimationDampingRatio UI_APPEARANCE_SELECTOR;
160 |
161 | /**
162 | The initial spring velocity used if spring animations are enabled.
163 |
164 | @see usesSpringAnimations
165 | */
166 | @property (nonatomic) CGFloat springAnimationVelocity UI_APPEARANCE_SELECTOR;
167 |
168 | #endif
169 |
170 | /**
171 | Initializes and returns a control with segments having the specified titles.
172 |
173 | @param items An array of NSString objects representing the titles of segments in the control.
174 |
175 | @return An initialized NYSegmentedControl object, or nil if it could not be created.
176 | */
177 | - (instancetype)initWithItems:(NSArray *)items;
178 |
179 | /**
180 | Inserts a segment at the specified index.
181 |
182 | @param title A string to use as the segment's title.
183 | @param index The index of the segment. It must be a number between 0 and the number of segments (numberOfSegments); values exceeding this upper range are pinned to it.
184 | */
185 | - (void)insertSegmentWithTitle:(NSString *)title atIndex:(NSUInteger)index;
186 |
187 | /**
188 | Removes the segment at the specified index.
189 |
190 | @param index The index of the segment. It must be a number between 0 and the number of segments (numberOfSegments) minus 1; values exceeding this upper range are pinned to it.
191 | */
192 | - (void)removeSegmentAtIndex:(NSUInteger)index;
193 |
194 | /**
195 | Removes all segments from the control.
196 | */
197 | - (void)removeAllSegments;
198 |
199 | /**
200 | Sets the title for a segment in the control.
201 |
202 | @param title A string to display in the segment as its title.
203 | @param index The index of the segment. It must be a number between 0 and the number of segments (numberOfSegments) minus 1; values exceeding this upper range are pinned to it.
204 | */
205 | - (void)setTitle:(NSString *)title forSegmentAtIndex:(NSUInteger)index;
206 |
207 | /**
208 | Gets the title of a segment in the control.
209 |
210 | @param index The index of the segment. It must be a number between 0 and the number of segments (numberOfSegments) minus 1; values exceeding this upper range are pinned to it.
211 |
212 | @return The title of the specified segment.
213 | */
214 | - (NSString *)titleForSegmentAtIndex:(NSUInteger)index;
215 |
216 | /**
217 | Sets the selected segment index.
218 |
219 | @param selectedSegmentIndex The index of the segment to select. It must be a number between 0 and the number of segments (numberOfSegments) minus 1; values exceeding this upper range are pinned to it.
220 | @param animated Specify YES if the selected segment indicator should animate its position change.
221 | */
222 | - (void)setSelectedSegmentIndex:(NSUInteger)selectedSegmentIndex animated:(BOOL)animated;
223 |
224 | /**
225 | Reloads the control's items from its data source, if defined.
226 |
227 | @see dataSource
228 | */
229 | - (void)reloadData;
230 |
231 | @end
232 |
233 | NS_ASSUME_NONNULL_END
234 |
--------------------------------------------------------------------------------
/NYSegmentedControlDemo/NYSegmentedControlDemo/DemoViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // DemoViewController.m
3 | // NYSegmentedControlDemo
4 | //
5 | // Created by Nealon Young on 3/22/14.
6 | // Copyright (c) 2014 Neal Young. All rights reserved.
7 | //
8 |
9 | #import "DemoViewController.h"
10 | #import "NYSegmentedControl.h"
11 |
12 | @interface DemoViewController ()
13 |
14 | @property (nonatomic, strong) UIStackView *stackView;
15 |
16 | @end
17 |
18 | @implementation DemoViewController
19 |
20 | - (void)viewDidLoad {
21 | [super viewDidLoad];
22 |
23 | self.stackView = [[UIStackView alloc] init];
24 | self.stackView.axis = UILayoutConstraintAxisVertical;
25 | self.stackView.distribution = UIStackViewDistributionFillEqually;
26 | [self.view addSubview:self.stackView];
27 | self.stackView.translatesAutoresizingMaskIntoConstraints = NO;
28 | [self.stackView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor].active = YES;
29 | [self.stackView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor].active = YES;
30 | [self.stackView.topAnchor constraintEqualToAnchor:self.view.topAnchor].active = YES;
31 | [self.stackView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor].active = YES;
32 |
33 | [self addSegmentedControlExample:[self graySegmentedControl] withBackgroundColor:[UIColor colorWithWhite:0.96f alpha:1.0f]];
34 | [self addSegmentedControlExample:[self blueSegmentedControl] withBackgroundColor:[UIColor colorWithRed:0.36f green:0.64f blue:0.88f alpha:1.0f]];
35 | [self addSegmentedControlExample:[self flatGraySegmentedControl] withBackgroundColor:[UIColor colorWithRed:0.12f green:0.12f blue:0.15f alpha:1.0f]];
36 | [self addSegmentedControlExample:[self purpleSegmentedControl] withBackgroundColor:[UIColor colorWithWhite:0.24f alpha:1.0f]];
37 | [self addSegmentedControlExample:[self switchSegmentedControl] withBackgroundColor:[UIColor colorWithWhite:0.18f alpha:1.0f]];
38 | }
39 |
40 | - (void)addSegmentedControlExample:(NYSegmentedControl *)segmentedControl withBackgroundColor:(UIColor *)backgroundColor {
41 | UIView *backgroundView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, CGRectGetWidth([UIScreen mainScreen].bounds), 44.0f)];
42 | backgroundView.backgroundColor = backgroundColor;
43 | [self.stackView addArrangedSubview:backgroundView];
44 |
45 | [backgroundView addSubview:segmentedControl];
46 | segmentedControl.translatesAutoresizingMaskIntoConstraints = NO;
47 | [segmentedControl.centerXAnchor constraintEqualToAnchor:backgroundView.centerXAnchor].active = YES;
48 | [segmentedControl.centerYAnchor constraintEqualToAnchor:backgroundView.centerYAnchor].active = YES;
49 | }
50 |
51 | - (NYSegmentedControl *)graySegmentedControl {
52 | NYSegmentedControl *graySegmentedControl = [[NYSegmentedControl alloc] initWithItems:@[@"Popular", @"Following", @"News"]];
53 | graySegmentedControl.backgroundColor = [UIColor colorWithWhite:0.9f alpha:1.0f];
54 | graySegmentedControl.segmentIndicatorBackgroundColor = [UIColor whiteColor];
55 | graySegmentedControl.segmentIndicatorInset = 0.0f;
56 | graySegmentedControl.titleTextColor = [UIColor lightGrayColor];
57 | graySegmentedControl.selectedTitleTextColor = [UIColor darkGrayColor];
58 |
59 | return graySegmentedControl;
60 | }
61 |
62 | - (NYSegmentedControl *)blueSegmentedControl {
63 | NYSegmentedControl *blueSegmentedControl = [[NYSegmentedControl alloc] initWithItems:@[@"Nearby", @"Worldwide"]];
64 | blueSegmentedControl.titleTextColor = [UIColor colorWithRed:0.38f green:0.68f blue:0.93f alpha:1.0f];
65 | blueSegmentedControl.selectedTitleTextColor = [UIColor whiteColor];
66 | blueSegmentedControl.segmentIndicatorBackgroundColor = [UIColor colorWithRed:0.38f green:0.68f blue:0.93f alpha:1.0f];
67 | blueSegmentedControl.backgroundColor = [UIColor colorWithRed:0.31f green:0.53f blue:0.72f alpha:1.0f];
68 | blueSegmentedControl.borderWidth = 0.0f;
69 | blueSegmentedControl.segmentIndicatorBorderWidth = 0.0f;
70 | blueSegmentedControl.segmentIndicatorInset = 2.0f;
71 | blueSegmentedControl.segmentIndicatorBorderColor = self.view.backgroundColor;
72 | blueSegmentedControl.cornerRadius = blueSegmentedControl.intrinsicContentSize.height / 2.0f;
73 | blueSegmentedControl.usesSpringAnimations = YES;
74 |
75 | return blueSegmentedControl;
76 | }
77 |
78 | - (NYSegmentedControl *)flatGraySegmentedControl {
79 | NYSegmentedControl *flatGraySegmentedControl = [[NYSegmentedControl alloc] initWithItems:@[@"ENGLISH", @"中文文学"]];
80 | flatGraySegmentedControl.backgroundColor = [UIColor colorWithRed:0.09f green:0.09f blue:0.12f alpha:1.0f];
81 | flatGraySegmentedControl.selectedTitleFont = [UIFont systemFontOfSize:12.0f weight:UIFontWeightSemibold];
82 | flatGraySegmentedControl.titleFont = [UIFont systemFontOfSize:12.0f weight:UIFontWeightSemibold];
83 | flatGraySegmentedControl.borderColor = [UIColor colorWithRed:0.18f green:0.18f blue:0.22f alpha:1.0f];
84 | flatGraySegmentedControl.borderWidth = 2.0f;
85 | flatGraySegmentedControl.segmentIndicatorBorderColor = [UIColor clearColor];
86 | flatGraySegmentedControl.segmentIndicatorBackgroundColor = [UIColor colorWithRed:0.18f green:0.18f blue:0.22f alpha:1.0f];
87 | flatGraySegmentedControl.segmentIndicatorInset = 5.0f;
88 | flatGraySegmentedControl.titleTextColor = [UIColor colorWithRed:0.30f green:0.31f blue:0.36f alpha:1.0f];
89 | flatGraySegmentedControl.selectedTitleTextColor = [UIColor whiteColor];
90 | flatGraySegmentedControl.cornerRadius = 22.0f;
91 | [flatGraySegmentedControl.widthAnchor constraintEqualToConstant:240.0f].active = YES;
92 | [flatGraySegmentedControl.heightAnchor constraintEqualToConstant:44.0f].active = YES;
93 |
94 | return flatGraySegmentedControl;
95 | }
96 |
97 | - (NYSegmentedControl *)purpleSegmentedControl {
98 | NYSegmentedControl *purpleSegmentedControl = [[NYSegmentedControl alloc] initWithItems:@[@"Lists", @"Followers"]];
99 | purpleSegmentedControl.borderWidth = 2.0f;
100 | purpleSegmentedControl.borderColor = [UIColor colorWithWhite:0.15f alpha:1.0f];
101 | purpleSegmentedControl.titleFont = [UIFont fontWithName:@"AvenirNext-Medium" size:14.0f];
102 | purpleSegmentedControl.titleTextColor = [UIColor colorWithWhite:0.34f alpha:1.0f];
103 | purpleSegmentedControl.selectedTitleFont = [UIFont fontWithName:@"AvenirNext-DemiBold" size:14.0f];
104 | purpleSegmentedControl.selectedTitleTextColor = [UIColor colorWithWhite:0.9f alpha:1.0f];
105 | purpleSegmentedControl.borderWidth = 0.0f;
106 | purpleSegmentedControl.drawsGradientBackground = YES;
107 | purpleSegmentedControl.gradientTopColor = [UIColor colorWithWhite:0.17f alpha:1.0f];
108 | purpleSegmentedControl.gradientBottomColor = [UIColor colorWithWhite:0.05f alpha:1.0f];
109 | purpleSegmentedControl.segmentIndicatorInset = 4.0f;
110 | purpleSegmentedControl.segmentIndicatorBackgroundColor = [UIColor clearColor];
111 | purpleSegmentedControl.segmentIndicatorBorderWidth = 0.0f;
112 | purpleSegmentedControl.drawsSegmentIndicatorGradientBackground = YES;
113 | purpleSegmentedControl.segmentIndicatorGradientTopColor = [UIColor colorWithRed:0.65f green:0.25f blue:0.95f alpha:1.0f];
114 | purpleSegmentedControl.segmentIndicatorGradientBottomColor = [UIColor colorWithRed:0.4f green:0.15f blue:0.8f alpha:1.0f];
115 | [purpleSegmentedControl.widthAnchor constraintEqualToConstant:200.0f].active = YES;
116 | [purpleSegmentedControl.heightAnchor constraintEqualToConstant:40.0f].active = YES;
117 |
118 | return purpleSegmentedControl;
119 | }
120 |
121 | - (NYSegmentedControl *)switchSegmentedControl {
122 | NYSegmentedControl *switchSegmentedControl = [[NYSegmentedControl alloc] initWithItems:@[@"On", @"Off"]];
123 | switchSegmentedControl.borderWidth = 2.0f;
124 | switchSegmentedControl.borderColor = [UIColor colorWithWhite:0.15f alpha:1.0f];
125 | switchSegmentedControl.titleFont = [UIFont fontWithName:@"AvenirNext-Medium" size:16.0f];
126 | switchSegmentedControl.titleTextColor = [UIColor colorWithWhite:0.3f alpha:1.0f];
127 | switchSegmentedControl.selectedTitleFont = [UIFont fontWithName:@"AvenirNext-DemiBold" size:18.0f];
128 | switchSegmentedControl.selectedTitleTextColor = [UIColor colorWithWhite:0.2f alpha:1.0f];
129 | switchSegmentedControl.drawsGradientBackground = YES;
130 | switchSegmentedControl.gradientTopColor = [UIColor colorWithWhite:0.17f alpha:1.0f];
131 | switchSegmentedControl.gradientBottomColor = [UIColor colorWithWhite:0.05f alpha:1.0f];
132 | switchSegmentedControl.segmentIndicatorAnimationDuration = 0.2f;
133 | switchSegmentedControl.segmentIndicatorInset = 6.0f;
134 | switchSegmentedControl.drawsSegmentIndicatorGradientBackground = YES;
135 | switchSegmentedControl.segmentIndicatorGradientTopColor = [UIColor colorWithRed:0.75f green:0.9f blue:0.4f alpha:1.0f];
136 | switchSegmentedControl.segmentIndicatorGradientBottomColor = [UIColor colorWithRed:0.47f green:0.72f blue:0.29f alpha:1.0f];
137 | switchSegmentedControl.segmentIndicatorBorderWidth = 0.0f;
138 | switchSegmentedControl.cornerRadius = 35.0f;
139 | switchSegmentedControl.translatesAutoresizingMaskIntoConstraints = NO;
140 | [switchSegmentedControl.widthAnchor constraintEqualToConstant:140.0f].active = YES;
141 | [switchSegmentedControl.heightAnchor constraintEqualToConstant:70.0f].active = YES;
142 |
143 | return switchSegmentedControl;
144 | }
145 |
146 | - (BOOL)prefersStatusBarHidden {
147 | return YES;
148 | }
149 |
150 | @end
151 |
--------------------------------------------------------------------------------
/NYSegmentedControl/NYSegmentedControl.m:
--------------------------------------------------------------------------------
1 | #import "NYSegmentedControl.h"
2 | #import "NYSegment.h"
3 | #import "NYSegmentIndicator.h"
4 | #import "NYSegmentTextRenderView.h"
5 |
6 | @interface NYSegmentedControl ()
7 |
8 | @property (nonatomic) NSArray *segments;
9 | @property (nonatomic) NYSegmentIndicator *selectedSegmentIndicator;
10 | @property (nonatomic, getter=isAnimating) BOOL animating;
11 |
12 | - (void)moveSelectedSegmentIndicatorToSegmentAtIndex:(NSUInteger)index animated:(BOOL)animated;
13 | - (CGRect)indicatorFrameForSegment:(NYSegment *)segment;
14 |
15 | - (void)panGestureRecognized:(UIPanGestureRecognizer *)panGestureRecognizer;
16 | - (void)tapGestureRecognized:(UITapGestureRecognizer *)tapGestureRecognizer;
17 |
18 | @end
19 |
20 | @implementation NYSegmentedControl
21 |
22 | + (Class)layerClass {
23 | return [CAGradientLayer class];
24 | }
25 |
26 | - (instancetype)initWithCoder:(NSCoder *)aDecoder {
27 | self = [super initWithCoder:aDecoder];
28 |
29 | if (self) {
30 | [self initialize];
31 | }
32 |
33 | return self;
34 | }
35 |
36 | - (instancetype)initWithFrame:(CGRect)frame {
37 | self = [super initWithFrame:frame];
38 |
39 | if (self) {
40 | [self initialize];
41 | }
42 |
43 | return self;
44 | }
45 |
46 | - (instancetype)initWithItems:(NSArray *)items {
47 | self = [self initWithFrame:CGRectZero];
48 |
49 | if (self) {
50 | NSMutableArray *mutableSegments = [NSMutableArray array];
51 |
52 | for (NSString *segmentTitle in items) {
53 | NYSegment *segment = [[NYSegment alloc] initWithTitle:segmentTitle];
54 | segment.titleLabel.maskCornerRadius = self.cornerRadius;
55 | [self addSubview:segment];
56 | [mutableSegments addObject:segment];
57 | }
58 |
59 | self.segments = [NSArray arrayWithArray:mutableSegments];
60 | self.selectedSegmentIndex = 0;
61 | }
62 |
63 | return self;
64 | }
65 |
66 | - (void)initialize {
67 | // We need to directly access the ivars for UIAppearance properties in the initializer
68 | _titleFont = [UIFont systemFontOfSize:13.0f];
69 | _titleTextColor = [UIColor blackColor];
70 | _selectedTitleFont = [UIFont boldSystemFontOfSize:13.0f];
71 | _selectedTitleTextColor = [UIColor blackColor];
72 | _stylesTitleForSelectedSegment = YES;
73 | _segmentIndicatorInset = 0.0f;
74 | _segmentIndicatorAnimationDuration = 0.15f;
75 | _gradientTopColor = [UIColor colorWithRed:0.21f green:0.21f blue:0.21f alpha:1.0f];
76 | _gradientBottomColor = [UIColor colorWithRed:0.16f green:0.16f blue:0.16f alpha:1.0f];
77 | _usesSpringAnimations = NO;
78 | _springAnimationDuration = 0.25f;
79 | _springAnimationDampingRatio = 0.7f;
80 | _springAnimationVelocity = 0.2f;
81 |
82 | self.layer.borderColor = [[UIColor lightGrayColor] CGColor];
83 | self.layer.masksToBounds = YES;
84 | self.layer.cornerRadius = 4.0f;
85 | self.layer.borderWidth = 1.0f;
86 |
87 | self.drawsGradientBackground = NO;
88 | self.opaque = NO;
89 |
90 | self.selectedSegmentIndicator = [[NYSegmentIndicator alloc] initWithFrame:CGRectZero];
91 | self.drawsSegmentIndicatorGradientBackground = YES;
92 | [self addSubview:self.selectedSegmentIndicator];
93 |
94 | UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGestureRecognized:)];
95 | panGestureRecognizer.maximumNumberOfTouches = 1;
96 | [self.selectedSegmentIndicator addGestureRecognizer:panGestureRecognizer];
97 |
98 | UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGestureRecognized:)];
99 | tapGestureRecognizer.numberOfTapsRequired = 1;
100 | [self addGestureRecognizer:tapGestureRecognizer];
101 | }
102 |
103 | - (void)reloadData {
104 | if (self.dataSource) {
105 | for (NYSegment *segment in self.segments) {
106 | [segment removeFromSuperview];
107 | }
108 | self.segments = [self buildSegmentsFromDataSource];
109 | }
110 | }
111 |
112 | - (NSArray *)buildSegmentsFromDataSource {
113 | if (self.dataSource) {
114 | NSUInteger numberOfSegments = [self.dataSource numberOfSegments:self];
115 | NSMutableArray *segmentsArray = [NSMutableArray arrayWithCapacity:numberOfSegments];
116 |
117 | for (int i = 0; i < numberOfSegments; i++) {
118 | NSString *title = [self.dataSource segmentedControl:self titleForSegmentAtIndex:i];
119 | NYSegment *segment = [[NYSegment alloc] initWithTitle:title];
120 | [self addSubview:segment];
121 | [segmentsArray addObject:segment];
122 | }
123 |
124 | return [segmentsArray copy];
125 | } else {
126 | return nil;
127 | }
128 | }
129 |
130 | - (NSArray *)segments {
131 | if (!_segments) {
132 | _segments = [self buildSegmentsFromDataSource];
133 | }
134 |
135 | return _segments;
136 | }
137 |
138 | - (CGSize)sizeThatFits:(CGSize)size {
139 | CGFloat maxSegmentWidth = 0.0f;
140 |
141 | for (NYSegment *segment in self.segments) {
142 | CGFloat segmentWidth = [segment sizeThatFits:size].width;
143 | if (segmentWidth > maxSegmentWidth) {
144 | maxSegmentWidth = segmentWidth;
145 | }
146 | }
147 |
148 | return CGSizeMake(maxSegmentWidth * self.segments.count, 32.0f);
149 | }
150 |
151 | - (CGSize)intrinsicContentSize {
152 | return [self sizeThatFits:self.bounds.size];
153 | }
154 |
155 | - (void)layoutSubviews {
156 | [super layoutSubviews];
157 |
158 | CGFloat segmentWidth = CGRectGetWidth(self.frame) / self.segments.count;
159 | CGFloat segmentHeight = CGRectGetHeight(self.frame);
160 | for (int i = 0; i < self.segments.count; i++) {
161 | NYSegment *segment = self.segments[i];
162 | segment.frame = CGRectMake(segmentWidth * i, 0.0f, segmentWidth, segmentHeight);
163 |
164 | if (self.stylesTitleForSelectedSegment) {
165 | if (self.selectedSegmentIndex == i) {
166 | segment.titleLabel.selectedTextDrawingRect = segment.titleLabel.bounds;
167 | }
168 |
169 | segment.titleLabel.font = self.titleFont;
170 | segment.titleLabel.selectedFont = self.selectedTitleFont;
171 |
172 | segment.titleLabel.textColor = self.titleTextColor;
173 | segment.titleLabel.selectedTextColor = self.selectedTitleTextColor;
174 | } else {
175 | segment.titleLabel.font = self.titleFont;
176 | segment.titleLabel.textColor = self.titleTextColor;
177 | }
178 | }
179 |
180 | self.selectedSegmentIndicator.frame = [self indicatorFrameForSegment:self.segments[self.selectedSegmentIndex]];
181 | }
182 |
183 | - (void)drawRect:(CGRect)rect {
184 | if (self.drawsGradientBackground) {
185 | CAGradientLayer *gradientLayer = (CAGradientLayer *)self.layer;
186 | gradientLayer.colors = @[(__bridge id)[self.gradientTopColor CGColor],
187 | (__bridge id)[self.gradientBottomColor CGColor]];
188 | } else {
189 | self.layer.backgroundColor = [self.backgroundColor CGColor];
190 | }
191 | }
192 |
193 | - (void)insertSegmentWithTitle:(NSString *)title atIndex:(NSUInteger)index {
194 | if (index >= self.segments.count) {
195 | index = self.segments.count;
196 | }
197 |
198 | NYSegment *newSegment = [[NYSegment alloc] initWithTitle:title];
199 | newSegment.titleLabel.maskCornerRadius = self.cornerRadius;
200 | [self addSubview:newSegment];
201 |
202 | NSMutableArray *mutableSegments = [NSMutableArray arrayWithArray:self.segments];
203 | [mutableSegments insertObject:newSegment atIndex:index];
204 | self.segments = [NSArray arrayWithArray:mutableSegments];
205 |
206 | [self setNeedsLayout];
207 | }
208 |
209 | - (void)removeSegmentAtIndex:(NSUInteger)index {
210 | if (index >= self.numberOfSegments) {
211 | index = self.numberOfSegments - 1;
212 | }
213 |
214 | NYSegment *segment = self.segments[index];
215 | [segment removeFromSuperview];
216 |
217 | NSMutableArray *mutableSegments = [NSMutableArray arrayWithArray:self.segments];
218 | [mutableSegments removeObjectAtIndex:index];
219 | self.segments = [NSArray arrayWithArray:mutableSegments];
220 |
221 | [self setNeedsLayout];
222 | }
223 |
224 | - (void)removeAllSegments {
225 | for (NYSegment *segment in self.segments) {
226 | [segment removeFromSuperview];
227 | }
228 |
229 | self.segments = [NSArray array];
230 | [self setNeedsLayout];
231 | }
232 |
233 | - (void)setTitle:(NSString *)title forSegmentAtIndex:(NSUInteger)index {
234 | NYSegment *segment = self.segments[index];
235 | segment.titleLabel.text = title;
236 | }
237 |
238 | - (NSString *)titleForSegmentAtIndex:(NSUInteger)index {
239 | NYSegment *segment = self.segments[index];
240 | return segment.titleLabel.text;
241 | }
242 |
243 | - (void)moveSelectedSegmentIndicatorToSegmentAtIndex:(NSUInteger)index animated:(BOOL)animated {
244 | NYSegment *selectedSegment = self.segments[index];
245 |
246 | // If we're moving the indicator back to the originally selected segment, don't change the segment's font style
247 | if (index != self.selectedSegmentIndex && self.stylesTitleForSelectedSegment) {
248 | NYSegment *previousSegment = self.segments[self.selectedSegmentIndex];
249 |
250 | [UIView transitionWithView:previousSegment.titleLabel
251 | duration:self.segmentIndicatorAnimationDuration
252 | options:UIViewAnimationOptionTransitionCrossDissolve
253 | animations:^{
254 | previousSegment.titleLabel.selectedTextDrawingRect = CGRectZero;
255 | }
256 | completion:nil];
257 |
258 | [UIView transitionWithView:selectedSegment.titleLabel
259 | duration:self.segmentIndicatorAnimationDuration
260 | options:UIViewAnimationOptionTransitionCrossDissolve
261 | animations:^{
262 | }
263 | completion:nil];
264 | }
265 |
266 | if (animated) {
267 | void (^animationsBlock)(void) = ^{
268 | self.selectedSegmentIndicator.frame = [self indicatorFrameForSegment:selectedSegment];
269 |
270 | if (self.stylesTitleForSelectedSegment) {
271 | [self.segments enumerateObjectsUsingBlock:^(NYSegment *segment, NSUInteger index, BOOL *stop) {
272 | segment.titleLabel.selectedTextDrawingRect = CGRectZero;
273 | }];
274 |
275 | selectedSegment.titleLabel.selectedTextDrawingRect = selectedSegment.titleLabel.bounds;
276 | }
277 | };
278 |
279 | if (NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_6_1 || !self.usesSpringAnimations) {
280 | [UIView animateWithDuration:self.segmentIndicatorAnimationDuration
281 | animations:animationsBlock
282 | completion:nil];
283 | } else {
284 | [UIView animateWithDuration:self.springAnimationDuration
285 | delay:0.f
286 | usingSpringWithDamping:self.springAnimationDampingRatio
287 | initialSpringVelocity:self.springAnimationVelocity
288 | options:kNilOptions
289 | animations:animationsBlock
290 | completion:nil];
291 | }
292 | } else {
293 | self.selectedSegmentIndicator.frame = [self indicatorFrameForSegment:selectedSegment];
294 |
295 | if (self.stylesTitleForSelectedSegment) {
296 | selectedSegment.titleLabel.selectedTextDrawingRect = selectedSegment.titleLabel.bounds;
297 | }
298 | }
299 | }
300 |
301 | #pragma mark - Touch Tracking
302 |
303 | - (void)panGestureRecognized:(UIPanGestureRecognizer *)panGestureRecognizer {
304 | CGPoint translation = [panGestureRecognizer translationInView:panGestureRecognizer.view.superview];
305 |
306 | if (self.stylesTitleForSelectedSegment) {
307 | // Style the segment the center of the indicator is covering
308 | [self.segments enumerateObjectsUsingBlock:^(NYSegment *segment, NSUInteger index, BOOL *stop) {
309 | // We get the intersection of the the selected segment indicator's frame and the segment's frame, so the text render view can show text with the selected style in the area covered by the selected segment indicator
310 | CGRect intersectionRect = CGRectIntersection(segment.frame, self.selectedSegmentIndicator.frame);
311 | segment.titleLabel.selectedTextDrawingRect = [segment convertRect:intersectionRect fromView:segment.superview];
312 | }];
313 | }
314 |
315 | // Find the difference in horizontal position between the current and previous touches
316 | CGFloat xDiff = translation.x;
317 |
318 | // Check that the indicator doesn't exit the bounds of the control
319 | CGRect newSegmentIndicatorFrame = self.selectedSegmentIndicator.frame;
320 | newSegmentIndicatorFrame.origin.x += xDiff;
321 |
322 | CGFloat selectedSegmentIndicatorCenterX;
323 |
324 | if (CGRectContainsRect(CGRectInset(self.bounds, self.segmentIndicatorInset, 0), newSegmentIndicatorFrame)) {
325 | selectedSegmentIndicatorCenterX = self.selectedSegmentIndicator.center.x + xDiff;
326 | } else {
327 | if (self.selectedSegmentIndicator.center.x < CGRectGetMidX(self.bounds)) {
328 | selectedSegmentIndicatorCenterX = self.segmentIndicatorInset + CGRectGetMidX(self.selectedSegmentIndicator.bounds);
329 | } else {
330 | selectedSegmentIndicatorCenterX = CGRectGetMaxX(self.bounds) - CGRectGetMidX(self.selectedSegmentIndicator.bounds) - self.segmentIndicatorInset;
331 | }
332 | }
333 |
334 | self.selectedSegmentIndicator.center = CGPointMake(selectedSegmentIndicatorCenterX, self.selectedSegmentIndicator.center.y);
335 |
336 | [panGestureRecognizer setTranslation:CGPointMake(0, 0) inView:panGestureRecognizer.view.superview];
337 |
338 | if (panGestureRecognizer.state == UIGestureRecognizerStateEnded) {
339 | [self.segments enumerateObjectsUsingBlock:^(NYSegment *segment, NSUInteger index, BOOL *stop) {
340 | if (CGRectContainsPoint(segment.frame, self.selectedSegmentIndicator.center)) {
341 | [self moveSelectedSegmentIndicatorToSegmentAtIndex:index animated:YES];
342 |
343 | if (index != self.selectedSegmentIndex) {
344 | _selectedSegmentIndex = index;
345 | [self sendActionsForControlEvents:UIControlEventValueChanged];
346 | }
347 | }
348 | }];
349 | }
350 | }
351 |
352 | - (void)tapGestureRecognized:(UITapGestureRecognizer *)tapGestureRecognizer {
353 | CGPoint location = [tapGestureRecognizer locationInView:self];
354 | [self.segments enumerateObjectsUsingBlock:^(NYSegment *segment, NSUInteger index, BOOL *stop) {
355 | if (CGRectContainsPoint(segment.frame, location)) {
356 | if (index != self.selectedSegmentIndex) {
357 | [self setSelectedSegmentIndex:index animated:YES];
358 | [self sendActionsForControlEvents:UIControlEventValueChanged];
359 | }
360 | }
361 | }];
362 | }
363 |
364 | #pragma mark - Helpers
365 |
366 | - (CGRect)indicatorFrameForSegment:(NYSegment *)segment {
367 | CGRect indicatorFrameRect = CGRectMake(CGRectGetMinX(segment.frame) + self.segmentIndicatorInset,
368 | CGRectGetMinY(segment.frame) + self.segmentIndicatorInset,
369 | CGRectGetWidth(segment.frame) - (2.0f * self.segmentIndicatorInset),
370 | CGRectGetHeight(segment.frame) - (2.0f * self.segmentIndicatorInset));
371 |
372 | return CGRectIntegral(indicatorFrameRect);
373 | }
374 |
375 | #pragma mark - Getters and Setters
376 |
377 | - (NSUInteger)numberOfSegments {
378 | return self.segments.count;
379 | }
380 |
381 | - (void)setBackgroundColor:(UIColor *)backgroundColor {
382 | self.layer.backgroundColor = [backgroundColor CGColor];
383 | }
384 |
385 | - (UIColor *)backgroundColor {
386 | return [UIColor colorWithCGColor:self.layer.backgroundColor];
387 | }
388 |
389 | - (void)setBorderColor:(UIColor *)borderColor {
390 | self.layer.borderColor = [borderColor CGColor];
391 | }
392 |
393 | - (UIColor *)borderColor {
394 | return [UIColor colorWithCGColor:self.layer.borderColor];
395 | }
396 |
397 | - (void)setBorderWidth:(CGFloat)borderWidth {
398 | self.layer.borderWidth = borderWidth;
399 | }
400 |
401 | - (CGFloat)borderWidth {
402 | return self.layer.borderWidth;
403 | }
404 |
405 | - (void)setCornerRadius:(CGFloat)cornerRadius {
406 | for (NYSegment *segment in self.segments) {
407 | segment.titleLabel.maskCornerRadius = cornerRadius;
408 | }
409 |
410 | self.layer.cornerRadius = cornerRadius;
411 | self.selectedSegmentIndicator.cornerRadius = cornerRadius * ((self.frame.size.height - self.segmentIndicatorInset * 2) / self.frame.size.height);
412 | [self setNeedsDisplay];
413 | }
414 |
415 | - (CGFloat)cornerRadius {
416 | return self.layer.cornerRadius;
417 | }
418 |
419 | - (void)setDrawsSegmentIndicatorGradientBackground:(BOOL)drawsSegmentIndicatorGradientBackground {
420 | self.selectedSegmentIndicator.drawsGradientBackground = drawsSegmentIndicatorGradientBackground;
421 | }
422 |
423 | - (BOOL)drawsSegmentIndicatorGradientBackground {
424 | return self.selectedSegmentIndicator.drawsGradientBackground;
425 | }
426 |
427 | - (void)setBounds:(CGRect)bounds {
428 | [super setBounds:bounds];
429 | self.selectedSegmentIndicator.cornerRadius = self.cornerRadius * ((self.frame.size.height - self.segmentIndicatorInset * 2) / self.frame.size.height);
430 | }
431 |
432 | - (void)setFrame:(CGRect)frame {
433 | [super setFrame:frame];
434 | self.selectedSegmentIndicator.cornerRadius = self.cornerRadius * ((self.frame.size.height - self.segmentIndicatorInset * 2) / self.frame.size.height);
435 | }
436 |
437 | - (void)setSegmentIndicatorBackgroundColor:(UIColor *)segmentIndicatorBackgroundColor {
438 | self.selectedSegmentIndicator.backgroundColor = segmentIndicatorBackgroundColor;
439 | }
440 |
441 | - (UIColor *)segmentIndicatorBackgroundColor {
442 | return self.selectedSegmentIndicator.backgroundColor;
443 | }
444 |
445 | - (void)setSegmentIndicatorInset:(CGFloat)segmentIndicatorInset {
446 | _segmentIndicatorInset = segmentIndicatorInset;
447 | self.selectedSegmentIndicator.cornerRadius = self.cornerRadius * ((self.frame.size.height - self.segmentIndicatorInset * 2) / self.frame.size.height);
448 | [self setNeedsLayout];
449 | }
450 |
451 | - (void)setSegmentIndicatorGradientTopColor:(UIColor *)segmentIndicatorGradientTopColor {
452 | self.selectedSegmentIndicator.gradientTopColor = segmentIndicatorGradientTopColor;
453 | }
454 |
455 | - (UIColor *)segmentIndicatorGradientTopColor {
456 | return self.selectedSegmentIndicator.gradientTopColor;
457 | }
458 |
459 | - (void)setSegmentIndicatorGradientBottomColor:(UIColor *)segmentIndicatorGradientBottomColor {
460 | self.selectedSegmentIndicator.gradientBottomColor = segmentIndicatorGradientBottomColor;
461 | }
462 |
463 | - (UIColor *)segmentIndicatorGradientBottomColor {
464 | return self.selectedSegmentIndicator.gradientBottomColor;
465 | }
466 |
467 | - (void)setSegmentIndicatorBorderColor:(UIColor *)segmentIndicatorBorderColor {
468 | self.selectedSegmentIndicator.borderColor = segmentIndicatorBorderColor;
469 | }
470 |
471 | - (UIColor *)segmentIndicatorBorderColor {
472 | return self.selectedSegmentIndicator.borderColor;
473 | }
474 |
475 | - (void)setSegmentIndicatorBorderWidth:(CGFloat)segmentIndicatorBorderWidth {
476 | self.selectedSegmentIndicator.borderWidth = segmentIndicatorBorderWidth;
477 | }
478 |
479 | - (CGFloat)segmentIndicatorBorderWidth {
480 | return self.selectedSegmentIndicator.borderWidth;
481 | }
482 |
483 | - (void)setTitleFont:(UIFont *)titleFont {
484 | _titleFont = titleFont;
485 | [self setNeedsLayout];
486 | }
487 |
488 | - (void)setTitleTextColor:(UIColor *)titleTextColor {
489 | _titleTextColor = titleTextColor;
490 | [self setNeedsLayout];
491 | }
492 |
493 | - (void)setSelectedTitleFont:(UIFont *)selectedTitleFont {
494 | _selectedTitleFont = selectedTitleFont;
495 | [self setNeedsLayout];
496 | }
497 |
498 | - (void)setSelectedTitleTextColor:(UIColor *)selectedTitleTextColor {
499 | _selectedTitleTextColor = selectedTitleTextColor;
500 | [self setNeedsLayout];
501 | }
502 |
503 | - (void)setSelectedSegmentIndex:(NSUInteger)selectedSegmentIndex {
504 | if (selectedSegmentIndex >= self.numberOfSegments) {
505 | selectedSegmentIndex = self.numberOfSegments - 1;
506 | }
507 |
508 | [self moveSelectedSegmentIndicatorToSegmentAtIndex:selectedSegmentIndex animated:NO];
509 |
510 | self.segments[_selectedSegmentIndex].selected = NO;
511 | self.segments[selectedSegmentIndex].selected = YES;
512 |
513 | _selectedSegmentIndex = selectedSegmentIndex;
514 | }
515 |
516 | - (void)setSelectedSegmentIndex:(NSUInteger)selectedSegmentIndex animated:(BOOL)animated {
517 | if (selectedSegmentIndex >= self.numberOfSegments) {
518 | selectedSegmentIndex = self.numberOfSegments - 1;
519 | }
520 |
521 | [self moveSelectedSegmentIndicatorToSegmentAtIndex:selectedSegmentIndex animated:animated];
522 |
523 | self.segments[_selectedSegmentIndex].selected = NO;
524 | self.segments[selectedSegmentIndex].selected = YES;
525 |
526 | _selectedSegmentIndex = selectedSegmentIndex;
527 | }
528 |
529 | @end
530 |
--------------------------------------------------------------------------------
/NYSegmentedControlDemo/NYSegmentedControlDemo.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 0E0A20AE1AF19FC3003855D5 /* Launch Screen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0E0A20AD1AF19FC3003855D5 /* Launch Screen.xib */; };
11 | 0E3CBE1118DECF82001EC237 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0E3CBE1018DECF82001EC237 /* Foundation.framework */; };
12 | 0E3CBE1518DECF82001EC237 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0E3CBE1418DECF82001EC237 /* UIKit.framework */; };
13 | 0E3CBE1B18DECF82001EC237 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0E3CBE1918DECF82001EC237 /* InfoPlist.strings */; };
14 | 0E3CBE1D18DECF82001EC237 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E3CBE1C18DECF82001EC237 /* main.m */; };
15 | 0E3CBE2918DECF82001EC237 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0E3CBE2818DECF82001EC237 /* Images.xcassets */; };
16 | 0E3CBE3018DECF82001EC237 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0E3CBE2F18DECF82001EC237 /* XCTest.framework */; };
17 | 0E3CBE3118DECF82001EC237 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0E3CBE1018DECF82001EC237 /* Foundation.framework */; };
18 | 0E3CBE3218DECF82001EC237 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0E3CBE1418DECF82001EC237 /* UIKit.framework */; };
19 | 0E3CBE3A18DECF82001EC237 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0E3CBE3818DECF82001EC237 /* InfoPlist.strings */; };
20 | 0E3CBE3C18DECF82001EC237 /* NYSegmentedControlDemoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E3CBE3B18DECF82001EC237 /* NYSegmentedControlDemoTests.m */; };
21 | 0E3CBE4918DECFAC001EC237 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E3CBE4618DECFAC001EC237 /* AppDelegate.m */; };
22 | 0E3CBE4A18DECFAC001EC237 /* DemoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E3CBE4818DECFAC001EC237 /* DemoViewController.m */; };
23 | 659F21897B4838586BF193C7 /* NYSegment.m in Sources */ = {isa = PBXBuildFile; fileRef = 659F26883AD0F08EA44F6774 /* NYSegment.m */; };
24 | 659F244CE6F6022E8146667F /* NYSegmentedControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 659F2880C9CF8CACC71FACF6 /* NYSegmentedControl.m */; };
25 | 659F2A3F8905B6E980263458 /* NYSegmentTextRenderView.m in Sources */ = {isa = PBXBuildFile; fileRef = 659F2E2AD1CACF14B488DE0F /* NYSegmentTextRenderView.m */; };
26 | 659F2CAA7E8B80BD4171B737 /* NYSegmentIndicator.m in Sources */ = {isa = PBXBuildFile; fileRef = 659F28C9E7C2C16F3C90C066 /* NYSegmentIndicator.m */; };
27 | /* End PBXBuildFile section */
28 |
29 | /* Begin PBXContainerItemProxy section */
30 | 0E3CBE3318DECF82001EC237 /* PBXContainerItemProxy */ = {
31 | isa = PBXContainerItemProxy;
32 | containerPortal = 0E3CBE0518DECF82001EC237 /* Project object */;
33 | proxyType = 1;
34 | remoteGlobalIDString = 0E3CBE0C18DECF82001EC237;
35 | remoteInfo = NYSegmentedControlDemo;
36 | };
37 | /* End PBXContainerItemProxy section */
38 |
39 | /* Begin PBXFileReference section */
40 | 0E0A20AD1AF19FC3003855D5 /* Launch Screen.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = "Launch Screen.xib"; sourceTree = ""; };
41 | 0E3CBE0D18DECF82001EC237 /* NYSegmentedControlDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NYSegmentedControlDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
42 | 0E3CBE1018DECF82001EC237 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
43 | 0E3CBE1218DECF82001EC237 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
44 | 0E3CBE1418DECF82001EC237 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
45 | 0E3CBE1818DECF82001EC237 /* NYSegmentedControlDemo-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "NYSegmentedControlDemo-Info.plist"; sourceTree = ""; };
46 | 0E3CBE1A18DECF82001EC237 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
47 | 0E3CBE1C18DECF82001EC237 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
48 | 0E3CBE1E18DECF82001EC237 /* NYSegmentedControlDemo-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NYSegmentedControlDemo-Prefix.pch"; sourceTree = ""; };
49 | 0E3CBE2818DECF82001EC237 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
50 | 0E3CBE2E18DECF82001EC237 /* NYSegmentedControlDemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NYSegmentedControlDemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
51 | 0E3CBE2F18DECF82001EC237 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
52 | 0E3CBE3718DECF82001EC237 /* NYSegmentedControlDemoTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "NYSegmentedControlDemoTests-Info.plist"; sourceTree = ""; };
53 | 0E3CBE3918DECF82001EC237 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
54 | 0E3CBE3B18DECF82001EC237 /* NYSegmentedControlDemoTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NYSegmentedControlDemoTests.m; sourceTree = ""; };
55 | 0E3CBE4518DECFAC001EC237 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
56 | 0E3CBE4618DECFAC001EC237 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
57 | 0E3CBE4718DECFAC001EC237 /* DemoViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DemoViewController.h; sourceTree = ""; };
58 | 0E3CBE4818DECFAC001EC237 /* DemoViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DemoViewController.m; sourceTree = ""; };
59 | 659F243FA0BCD42CEFAAE8E2 /* NYSegmentedControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NYSegmentedControl.h; sourceTree = ""; };
60 | 659F255C114426B98D821354 /* NYSegmentTextRenderView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NYSegmentTextRenderView.h; sourceTree = ""; };
61 | 659F26883AD0F08EA44F6774 /* NYSegment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NYSegment.m; sourceTree = ""; };
62 | 659F2880C9CF8CACC71FACF6 /* NYSegmentedControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NYSegmentedControl.m; sourceTree = ""; };
63 | 659F28C9E7C2C16F3C90C066 /* NYSegmentIndicator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NYSegmentIndicator.m; sourceTree = ""; };
64 | 659F29086DDA90B516DACA22 /* NYSegmentIndicator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NYSegmentIndicator.h; sourceTree = ""; };
65 | 659F2E2AD1CACF14B488DE0F /* NYSegmentTextRenderView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NYSegmentTextRenderView.m; sourceTree = ""; };
66 | 659F2E554A1A4D16DA1FA816 /* NYSegment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NYSegment.h; sourceTree = ""; };
67 | /* End PBXFileReference section */
68 |
69 | /* Begin PBXFrameworksBuildPhase section */
70 | 0E3CBE0A18DECF82001EC237 /* Frameworks */ = {
71 | isa = PBXFrameworksBuildPhase;
72 | buildActionMask = 2147483647;
73 | files = (
74 | 0E3CBE1518DECF82001EC237 /* UIKit.framework in Frameworks */,
75 | 0E3CBE1118DECF82001EC237 /* Foundation.framework in Frameworks */,
76 | );
77 | runOnlyForDeploymentPostprocessing = 0;
78 | };
79 | 0E3CBE2B18DECF82001EC237 /* Frameworks */ = {
80 | isa = PBXFrameworksBuildPhase;
81 | buildActionMask = 2147483647;
82 | files = (
83 | 0E3CBE3018DECF82001EC237 /* XCTest.framework in Frameworks */,
84 | 0E3CBE3218DECF82001EC237 /* UIKit.framework in Frameworks */,
85 | 0E3CBE3118DECF82001EC237 /* Foundation.framework in Frameworks */,
86 | );
87 | runOnlyForDeploymentPostprocessing = 0;
88 | };
89 | /* End PBXFrameworksBuildPhase section */
90 |
91 | /* Begin PBXGroup section */
92 | 0E3CBE0418DECF82001EC237 = {
93 | isa = PBXGroup;
94 | children = (
95 | 0E3CBE1618DECF82001EC237 /* NYSegmentedControlDemo */,
96 | 0E3CBE3518DECF82001EC237 /* NYSegmentedControlDemoTests */,
97 | 0E3CBE0F18DECF82001EC237 /* Frameworks */,
98 | 0E3CBE0E18DECF82001EC237 /* Products */,
99 | );
100 | sourceTree = "";
101 | };
102 | 0E3CBE0E18DECF82001EC237 /* Products */ = {
103 | isa = PBXGroup;
104 | children = (
105 | 0E3CBE0D18DECF82001EC237 /* NYSegmentedControlDemo.app */,
106 | 0E3CBE2E18DECF82001EC237 /* NYSegmentedControlDemoTests.xctest */,
107 | );
108 | name = Products;
109 | sourceTree = "";
110 | };
111 | 0E3CBE0F18DECF82001EC237 /* Frameworks */ = {
112 | isa = PBXGroup;
113 | children = (
114 | 0E3CBE1018DECF82001EC237 /* Foundation.framework */,
115 | 0E3CBE1218DECF82001EC237 /* CoreGraphics.framework */,
116 | 0E3CBE1418DECF82001EC237 /* UIKit.framework */,
117 | 0E3CBE2F18DECF82001EC237 /* XCTest.framework */,
118 | );
119 | name = Frameworks;
120 | sourceTree = "";
121 | };
122 | 0E3CBE1618DECF82001EC237 /* NYSegmentedControlDemo */ = {
123 | isa = PBXGroup;
124 | children = (
125 | C53E593E1932DA7100087BCD /* NYSegmentedControl */,
126 | 0E3CBE4518DECFAC001EC237 /* AppDelegate.h */,
127 | 0E3CBE4618DECFAC001EC237 /* AppDelegate.m */,
128 | 0E3CBE4718DECFAC001EC237 /* DemoViewController.h */,
129 | 0E3CBE4818DECFAC001EC237 /* DemoViewController.m */,
130 | 0E3CBE2818DECF82001EC237 /* Images.xcassets */,
131 | 0E3CBE1718DECF82001EC237 /* Supporting Files */,
132 | );
133 | path = NYSegmentedControlDemo;
134 | sourceTree = "";
135 | };
136 | 0E3CBE1718DECF82001EC237 /* Supporting Files */ = {
137 | isa = PBXGroup;
138 | children = (
139 | 0E0A20AD1AF19FC3003855D5 /* Launch Screen.xib */,
140 | 0E3CBE1818DECF82001EC237 /* NYSegmentedControlDemo-Info.plist */,
141 | 0E3CBE1918DECF82001EC237 /* InfoPlist.strings */,
142 | 0E3CBE1C18DECF82001EC237 /* main.m */,
143 | 0E3CBE1E18DECF82001EC237 /* NYSegmentedControlDemo-Prefix.pch */,
144 | );
145 | name = "Supporting Files";
146 | sourceTree = "";
147 | };
148 | 0E3CBE3518DECF82001EC237 /* NYSegmentedControlDemoTests */ = {
149 | isa = PBXGroup;
150 | children = (
151 | 0E3CBE3B18DECF82001EC237 /* NYSegmentedControlDemoTests.m */,
152 | 0E3CBE3618DECF82001EC237 /* Supporting Files */,
153 | );
154 | path = NYSegmentedControlDemoTests;
155 | sourceTree = "";
156 | };
157 | 0E3CBE3618DECF82001EC237 /* Supporting Files */ = {
158 | isa = PBXGroup;
159 | children = (
160 | 0E3CBE3718DECF82001EC237 /* NYSegmentedControlDemoTests-Info.plist */,
161 | 0E3CBE3818DECF82001EC237 /* InfoPlist.strings */,
162 | );
163 | name = "Supporting Files";
164 | sourceTree = "";
165 | };
166 | C53E593E1932DA7100087BCD /* NYSegmentedControl */ = {
167 | isa = PBXGroup;
168 | children = (
169 | 659F243FA0BCD42CEFAAE8E2 /* NYSegmentedControl.h */,
170 | 659F2880C9CF8CACC71FACF6 /* NYSegmentedControl.m */,
171 | 659F29086DDA90B516DACA22 /* NYSegmentIndicator.h */,
172 | 659F28C9E7C2C16F3C90C066 /* NYSegmentIndicator.m */,
173 | 659F255C114426B98D821354 /* NYSegmentTextRenderView.h */,
174 | 659F2E2AD1CACF14B488DE0F /* NYSegmentTextRenderView.m */,
175 | 659F2E554A1A4D16DA1FA816 /* NYSegment.h */,
176 | 659F26883AD0F08EA44F6774 /* NYSegment.m */,
177 | );
178 | name = NYSegmentedControl;
179 | path = ../../NYSegmentedControl;
180 | sourceTree = "";
181 | };
182 | /* End PBXGroup section */
183 |
184 | /* Begin PBXNativeTarget section */
185 | 0E3CBE0C18DECF82001EC237 /* NYSegmentedControlDemo */ = {
186 | isa = PBXNativeTarget;
187 | buildConfigurationList = 0E3CBE3F18DECF82001EC237 /* Build configuration list for PBXNativeTarget "NYSegmentedControlDemo" */;
188 | buildPhases = (
189 | 0E3CBE0918DECF82001EC237 /* Sources */,
190 | 0E3CBE0A18DECF82001EC237 /* Frameworks */,
191 | 0E3CBE0B18DECF82001EC237 /* Resources */,
192 | );
193 | buildRules = (
194 | );
195 | dependencies = (
196 | );
197 | name = NYSegmentedControlDemo;
198 | productName = NYSegmentedControlDemo;
199 | productReference = 0E3CBE0D18DECF82001EC237 /* NYSegmentedControlDemo.app */;
200 | productType = "com.apple.product-type.application";
201 | };
202 | 0E3CBE2D18DECF82001EC237 /* NYSegmentedControlDemoTests */ = {
203 | isa = PBXNativeTarget;
204 | buildConfigurationList = 0E3CBE4218DECF82001EC237 /* Build configuration list for PBXNativeTarget "NYSegmentedControlDemoTests" */;
205 | buildPhases = (
206 | 0E3CBE2A18DECF82001EC237 /* Sources */,
207 | 0E3CBE2B18DECF82001EC237 /* Frameworks */,
208 | 0E3CBE2C18DECF82001EC237 /* Resources */,
209 | );
210 | buildRules = (
211 | );
212 | dependencies = (
213 | 0E3CBE3418DECF82001EC237 /* PBXTargetDependency */,
214 | );
215 | name = NYSegmentedControlDemoTests;
216 | productName = NYSegmentedControlDemoTests;
217 | productReference = 0E3CBE2E18DECF82001EC237 /* NYSegmentedControlDemoTests.xctest */;
218 | productType = "com.apple.product-type.bundle.unit-test";
219 | };
220 | /* End PBXNativeTarget section */
221 |
222 | /* Begin PBXProject section */
223 | 0E3CBE0518DECF82001EC237 /* Project object */ = {
224 | isa = PBXProject;
225 | attributes = {
226 | CLASSPREFIX = NY;
227 | LastUpgradeCheck = 0510;
228 | ORGANIZATIONNAME = "Neal Young";
229 | TargetAttributes = {
230 | 0E3CBE2D18DECF82001EC237 = {
231 | TestTargetID = 0E3CBE0C18DECF82001EC237;
232 | };
233 | };
234 | };
235 | buildConfigurationList = 0E3CBE0818DECF82001EC237 /* Build configuration list for PBXProject "NYSegmentedControlDemo" */;
236 | compatibilityVersion = "Xcode 3.2";
237 | developmentRegion = English;
238 | hasScannedForEncodings = 0;
239 | knownRegions = (
240 | en,
241 | Base,
242 | );
243 | mainGroup = 0E3CBE0418DECF82001EC237;
244 | productRefGroup = 0E3CBE0E18DECF82001EC237 /* Products */;
245 | projectDirPath = "";
246 | projectRoot = "";
247 | targets = (
248 | 0E3CBE0C18DECF82001EC237 /* NYSegmentedControlDemo */,
249 | 0E3CBE2D18DECF82001EC237 /* NYSegmentedControlDemoTests */,
250 | );
251 | };
252 | /* End PBXProject section */
253 |
254 | /* Begin PBXResourcesBuildPhase section */
255 | 0E3CBE0B18DECF82001EC237 /* Resources */ = {
256 | isa = PBXResourcesBuildPhase;
257 | buildActionMask = 2147483647;
258 | files = (
259 | 0E3CBE2918DECF82001EC237 /* Images.xcassets in Resources */,
260 | 0E3CBE1B18DECF82001EC237 /* InfoPlist.strings in Resources */,
261 | 0E0A20AE1AF19FC3003855D5 /* Launch Screen.xib in Resources */,
262 | );
263 | runOnlyForDeploymentPostprocessing = 0;
264 | };
265 | 0E3CBE2C18DECF82001EC237 /* Resources */ = {
266 | isa = PBXResourcesBuildPhase;
267 | buildActionMask = 2147483647;
268 | files = (
269 | 0E3CBE3A18DECF82001EC237 /* InfoPlist.strings in Resources */,
270 | );
271 | runOnlyForDeploymentPostprocessing = 0;
272 | };
273 | /* End PBXResourcesBuildPhase section */
274 |
275 | /* Begin PBXSourcesBuildPhase section */
276 | 0E3CBE0918DECF82001EC237 /* Sources */ = {
277 | isa = PBXSourcesBuildPhase;
278 | buildActionMask = 2147483647;
279 | files = (
280 | 0E3CBE4A18DECFAC001EC237 /* DemoViewController.m in Sources */,
281 | 0E3CBE4918DECFAC001EC237 /* AppDelegate.m in Sources */,
282 | 0E3CBE1D18DECF82001EC237 /* main.m in Sources */,
283 | 659F2CAA7E8B80BD4171B737 /* NYSegmentIndicator.m in Sources */,
284 | 659F2A3F8905B6E980263458 /* NYSegmentTextRenderView.m in Sources */,
285 | 659F21897B4838586BF193C7 /* NYSegment.m in Sources */,
286 | 659F244CE6F6022E8146667F /* NYSegmentedControl.m in Sources */,
287 | );
288 | runOnlyForDeploymentPostprocessing = 0;
289 | };
290 | 0E3CBE2A18DECF82001EC237 /* Sources */ = {
291 | isa = PBXSourcesBuildPhase;
292 | buildActionMask = 2147483647;
293 | files = (
294 | 0E3CBE3C18DECF82001EC237 /* NYSegmentedControlDemoTests.m in Sources */,
295 | );
296 | runOnlyForDeploymentPostprocessing = 0;
297 | };
298 | /* End PBXSourcesBuildPhase section */
299 |
300 | /* Begin PBXTargetDependency section */
301 | 0E3CBE3418DECF82001EC237 /* PBXTargetDependency */ = {
302 | isa = PBXTargetDependency;
303 | target = 0E3CBE0C18DECF82001EC237 /* NYSegmentedControlDemo */;
304 | targetProxy = 0E3CBE3318DECF82001EC237 /* PBXContainerItemProxy */;
305 | };
306 | /* End PBXTargetDependency section */
307 |
308 | /* Begin PBXVariantGroup section */
309 | 0E3CBE1918DECF82001EC237 /* InfoPlist.strings */ = {
310 | isa = PBXVariantGroup;
311 | children = (
312 | 0E3CBE1A18DECF82001EC237 /* en */,
313 | );
314 | name = InfoPlist.strings;
315 | sourceTree = "";
316 | };
317 | 0E3CBE3818DECF82001EC237 /* InfoPlist.strings */ = {
318 | isa = PBXVariantGroup;
319 | children = (
320 | 0E3CBE3918DECF82001EC237 /* en */,
321 | );
322 | name = InfoPlist.strings;
323 | sourceTree = "";
324 | };
325 | /* End PBXVariantGroup section */
326 |
327 | /* Begin XCBuildConfiguration section */
328 | 0E3CBE3D18DECF82001EC237 /* Debug */ = {
329 | isa = XCBuildConfiguration;
330 | buildSettings = {
331 | ALWAYS_SEARCH_USER_PATHS = NO;
332 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
333 | CLANG_CXX_LIBRARY = "libc++";
334 | CLANG_ENABLE_MODULES = YES;
335 | CLANG_ENABLE_OBJC_ARC = YES;
336 | CLANG_WARN_BOOL_CONVERSION = YES;
337 | CLANG_WARN_CONSTANT_CONVERSION = YES;
338 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
339 | CLANG_WARN_EMPTY_BODY = YES;
340 | CLANG_WARN_ENUM_CONVERSION = YES;
341 | CLANG_WARN_INT_CONVERSION = YES;
342 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
343 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
344 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
345 | COPY_PHASE_STRIP = NO;
346 | GCC_C_LANGUAGE_STANDARD = gnu99;
347 | GCC_DYNAMIC_NO_PIC = NO;
348 | GCC_OPTIMIZATION_LEVEL = 0;
349 | GCC_PREPROCESSOR_DEFINITIONS = (
350 | "DEBUG=1",
351 | "$(inherited)",
352 | );
353 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
354 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
355 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
356 | GCC_WARN_UNDECLARED_SELECTOR = YES;
357 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
358 | GCC_WARN_UNUSED_FUNCTION = YES;
359 | GCC_WARN_UNUSED_VARIABLE = YES;
360 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
361 | ONLY_ACTIVE_ARCH = YES;
362 | SDKROOT = iphoneos;
363 | };
364 | name = Debug;
365 | };
366 | 0E3CBE3E18DECF82001EC237 /* Release */ = {
367 | isa = XCBuildConfiguration;
368 | buildSettings = {
369 | ALWAYS_SEARCH_USER_PATHS = NO;
370 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
371 | CLANG_CXX_LIBRARY = "libc++";
372 | CLANG_ENABLE_MODULES = YES;
373 | CLANG_ENABLE_OBJC_ARC = YES;
374 | CLANG_WARN_BOOL_CONVERSION = YES;
375 | CLANG_WARN_CONSTANT_CONVERSION = YES;
376 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
377 | CLANG_WARN_EMPTY_BODY = YES;
378 | CLANG_WARN_ENUM_CONVERSION = YES;
379 | CLANG_WARN_INT_CONVERSION = YES;
380 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
381 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
382 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
383 | COPY_PHASE_STRIP = YES;
384 | ENABLE_NS_ASSERTIONS = NO;
385 | GCC_C_LANGUAGE_STANDARD = gnu99;
386 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
387 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
388 | GCC_WARN_UNDECLARED_SELECTOR = YES;
389 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
390 | GCC_WARN_UNUSED_FUNCTION = YES;
391 | GCC_WARN_UNUSED_VARIABLE = YES;
392 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
393 | SDKROOT = iphoneos;
394 | VALIDATE_PRODUCT = YES;
395 | };
396 | name = Release;
397 | };
398 | 0E3CBE4018DECF82001EC237 /* Debug */ = {
399 | isa = XCBuildConfiguration;
400 | buildSettings = {
401 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
402 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
403 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
404 | GCC_PREFIX_HEADER = "NYSegmentedControlDemo/NYSegmentedControlDemo-Prefix.pch";
405 | INFOPLIST_FILE = "NYSegmentedControlDemo/NYSegmentedControlDemo-Info.plist";
406 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
407 | PRODUCT_NAME = "$(TARGET_NAME)";
408 | WRAPPER_EXTENSION = app;
409 | };
410 | name = Debug;
411 | };
412 | 0E3CBE4118DECF82001EC237 /* Release */ = {
413 | isa = XCBuildConfiguration;
414 | buildSettings = {
415 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
416 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
417 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
418 | GCC_PREFIX_HEADER = "NYSegmentedControlDemo/NYSegmentedControlDemo-Prefix.pch";
419 | INFOPLIST_FILE = "NYSegmentedControlDemo/NYSegmentedControlDemo-Info.plist";
420 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
421 | PRODUCT_NAME = "$(TARGET_NAME)";
422 | WRAPPER_EXTENSION = app;
423 | };
424 | name = Release;
425 | };
426 | 0E3CBE4318DECF82001EC237 /* Debug */ = {
427 | isa = XCBuildConfiguration;
428 | buildSettings = {
429 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/NYSegmentedControlDemo.app/NYSegmentedControlDemo";
430 | FRAMEWORK_SEARCH_PATHS = (
431 | "$(SDKROOT)/Developer/Library/Frameworks",
432 | "$(inherited)",
433 | "$(DEVELOPER_FRAMEWORKS_DIR)",
434 | );
435 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
436 | GCC_PREFIX_HEADER = "NYSegmentedControlDemo/NYSegmentedControlDemo-Prefix.pch";
437 | GCC_PREPROCESSOR_DEFINITIONS = (
438 | "DEBUG=1",
439 | "$(inherited)",
440 | );
441 | INFOPLIST_FILE = "NYSegmentedControlDemoTests/NYSegmentedControlDemoTests-Info.plist";
442 | PRODUCT_NAME = "$(TARGET_NAME)";
443 | TEST_HOST = "$(BUNDLE_LOADER)";
444 | WRAPPER_EXTENSION = xctest;
445 | };
446 | name = Debug;
447 | };
448 | 0E3CBE4418DECF82001EC237 /* Release */ = {
449 | isa = XCBuildConfiguration;
450 | buildSettings = {
451 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/NYSegmentedControlDemo.app/NYSegmentedControlDemo";
452 | FRAMEWORK_SEARCH_PATHS = (
453 | "$(SDKROOT)/Developer/Library/Frameworks",
454 | "$(inherited)",
455 | "$(DEVELOPER_FRAMEWORKS_DIR)",
456 | );
457 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
458 | GCC_PREFIX_HEADER = "NYSegmentedControlDemo/NYSegmentedControlDemo-Prefix.pch";
459 | INFOPLIST_FILE = "NYSegmentedControlDemoTests/NYSegmentedControlDemoTests-Info.plist";
460 | PRODUCT_NAME = "$(TARGET_NAME)";
461 | TEST_HOST = "$(BUNDLE_LOADER)";
462 | WRAPPER_EXTENSION = xctest;
463 | };
464 | name = Release;
465 | };
466 | /* End XCBuildConfiguration section */
467 |
468 | /* Begin XCConfigurationList section */
469 | 0E3CBE0818DECF82001EC237 /* Build configuration list for PBXProject "NYSegmentedControlDemo" */ = {
470 | isa = XCConfigurationList;
471 | buildConfigurations = (
472 | 0E3CBE3D18DECF82001EC237 /* Debug */,
473 | 0E3CBE3E18DECF82001EC237 /* Release */,
474 | );
475 | defaultConfigurationIsVisible = 0;
476 | defaultConfigurationName = Release;
477 | };
478 | 0E3CBE3F18DECF82001EC237 /* Build configuration list for PBXNativeTarget "NYSegmentedControlDemo" */ = {
479 | isa = XCConfigurationList;
480 | buildConfigurations = (
481 | 0E3CBE4018DECF82001EC237 /* Debug */,
482 | 0E3CBE4118DECF82001EC237 /* Release */,
483 | );
484 | defaultConfigurationIsVisible = 0;
485 | defaultConfigurationName = Release;
486 | };
487 | 0E3CBE4218DECF82001EC237 /* Build configuration list for PBXNativeTarget "NYSegmentedControlDemoTests" */ = {
488 | isa = XCConfigurationList;
489 | buildConfigurations = (
490 | 0E3CBE4318DECF82001EC237 /* Debug */,
491 | 0E3CBE4418DECF82001EC237 /* Release */,
492 | );
493 | defaultConfigurationIsVisible = 0;
494 | defaultConfigurationName = Release;
495 | };
496 | /* End XCConfigurationList section */
497 | };
498 | rootObject = 0E3CBE0518DECF82001EC237 /* Project object */;
499 | }
500 |
--------------------------------------------------------------------------------