├── Screenshot.png
├── HMSegmentedControlExample
├── Images
│ ├── 1.png
│ ├── 2.png
│ ├── 3.png
│ ├── 4.png
│ ├── 1@2x.png
│ ├── 2@2x.png
│ ├── 3@2x.png
│ ├── 4@2x.png
│ ├── 1-selected.png
│ ├── 2-selected.png
│ ├── 3-selected.png
│ ├── 4-selected.png
│ ├── 1-selected@2x.png
│ ├── 2-selected@2x.png
│ ├── 3-selected@2x.png
│ └── 4-selected@2x.png
├── ViewController.h
├── HMSegmentedControlExample-Prefix.pch
├── main.m
├── AppDelegate.h
├── AppDelegate.m
├── Launch Screen.xib
├── HMSegmentedControlExample-Info.plist
└── ViewController.m
├── Framework
├── module.modulemap
├── HMSegmentedControl-umbrella.h
└── Info.plist
├── HMSegmentedControl.xcodeproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
├── xcshareddata
│ └── xcschemes
│ │ └── HMSegmentedControl.xcscheme
└── project.pbxproj
├── .gitignore
├── HMSegmentedControl.podspec
├── LICENSE.md
├── README.md
└── HMSegmentedControl
├── HMSegmentedControl.h
└── HMSegmentedControl.m
/Screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ml-archive/HMSegmentedControl/master/Screenshot.png
--------------------------------------------------------------------------------
/HMSegmentedControlExample/Images/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ml-archive/HMSegmentedControl/master/HMSegmentedControlExample/Images/1.png
--------------------------------------------------------------------------------
/HMSegmentedControlExample/Images/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ml-archive/HMSegmentedControl/master/HMSegmentedControlExample/Images/2.png
--------------------------------------------------------------------------------
/HMSegmentedControlExample/Images/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ml-archive/HMSegmentedControl/master/HMSegmentedControlExample/Images/3.png
--------------------------------------------------------------------------------
/HMSegmentedControlExample/Images/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ml-archive/HMSegmentedControl/master/HMSegmentedControlExample/Images/4.png
--------------------------------------------------------------------------------
/HMSegmentedControlExample/Images/1@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ml-archive/HMSegmentedControl/master/HMSegmentedControlExample/Images/1@2x.png
--------------------------------------------------------------------------------
/HMSegmentedControlExample/Images/2@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ml-archive/HMSegmentedControl/master/HMSegmentedControlExample/Images/2@2x.png
--------------------------------------------------------------------------------
/HMSegmentedControlExample/Images/3@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ml-archive/HMSegmentedControl/master/HMSegmentedControlExample/Images/3@2x.png
--------------------------------------------------------------------------------
/HMSegmentedControlExample/Images/4@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ml-archive/HMSegmentedControl/master/HMSegmentedControlExample/Images/4@2x.png
--------------------------------------------------------------------------------
/HMSegmentedControlExample/Images/1-selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ml-archive/HMSegmentedControl/master/HMSegmentedControlExample/Images/1-selected.png
--------------------------------------------------------------------------------
/HMSegmentedControlExample/Images/2-selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ml-archive/HMSegmentedControl/master/HMSegmentedControlExample/Images/2-selected.png
--------------------------------------------------------------------------------
/HMSegmentedControlExample/Images/3-selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ml-archive/HMSegmentedControl/master/HMSegmentedControlExample/Images/3-selected.png
--------------------------------------------------------------------------------
/HMSegmentedControlExample/Images/4-selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ml-archive/HMSegmentedControl/master/HMSegmentedControlExample/Images/4-selected.png
--------------------------------------------------------------------------------
/HMSegmentedControlExample/Images/1-selected@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ml-archive/HMSegmentedControl/master/HMSegmentedControlExample/Images/1-selected@2x.png
--------------------------------------------------------------------------------
/HMSegmentedControlExample/Images/2-selected@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ml-archive/HMSegmentedControl/master/HMSegmentedControlExample/Images/2-selected@2x.png
--------------------------------------------------------------------------------
/HMSegmentedControlExample/Images/3-selected@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ml-archive/HMSegmentedControl/master/HMSegmentedControlExample/Images/3-selected@2x.png
--------------------------------------------------------------------------------
/HMSegmentedControlExample/Images/4-selected@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ml-archive/HMSegmentedControl/master/HMSegmentedControlExample/Images/4-selected@2x.png
--------------------------------------------------------------------------------
/Framework/module.modulemap:
--------------------------------------------------------------------------------
1 | framework module HMSegmentedControl {
2 | umbrella header "HMSegmentedControl-umbrella.h"
3 | export *
4 | module * { export * }
5 | }
6 |
--------------------------------------------------------------------------------
/HMSegmentedControl.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | .DS_Store
3 | */build/*
4 | *.pbxuser
5 | !default.pbxuser
6 | *.mode1v3
7 | !default.mode1v3
8 | *.mode2v3
9 | !default.mode2v3
10 | *.perspectivev3
11 | !default.perspectivev3
12 | xcuserdata
13 | profile
14 | *.moved-aside
15 | DerivedData
16 | .idea/
17 | *.hmap
--------------------------------------------------------------------------------
/HMSegmentedControlExample/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // HMSegmentedControlExample
4 | //
5 | // Created by Hesham Abd-Elmegid on 25/12/12.
6 | // Copyright (c) 2012 Hesham Abd-Elmegid. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/HMSegmentedControlExample/HMSegmentedControlExample-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header for all source files of the 'HMSegmentedControlExample' target in the 'HMSegmentedControlExample' project
3 | //
4 |
5 | #import
6 |
7 | #ifndef __IPHONE_4_0
8 | #warning "This project uses features only available in iOS SDK 4.0 and later."
9 | #endif
10 |
11 | #ifdef __OBJC__
12 | #import
13 | #import
14 | #endif
15 |
--------------------------------------------------------------------------------
/HMSegmentedControlExample/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // HMSegmentedControlExample
4 | //
5 | // Created by Hesham Abd-Elmegid on 25/12/12.
6 | // Copyright (c) 2012 Hesham Abd-Elmegid. 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 |
--------------------------------------------------------------------------------
/HMSegmentedControlExample/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // HMSegmentedControlExample
4 | //
5 | // Created by Hesham Abd-Elmegid on 25/12/12.
6 | // Copyright (c) 2012 Hesham Abd-Elmegid. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @class ViewController;
12 |
13 | @interface AppDelegate : UIResponder
14 |
15 | @property (strong, nonatomic) UIWindow *window;
16 |
17 | @property (strong, nonatomic) ViewController *viewController;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/Framework/HMSegmentedControl-umbrella.h:
--------------------------------------------------------------------------------
1 | //
2 | // HMSegmentedControl.h
3 | // HMSegmentedControl
4 | //
5 | // Created by Maxime Epain on 05/10/2016.
6 | // Copyright © 2012-2015 Hesham Abd-Elmegid. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for HMSegmentedControl.
12 | FOUNDATION_EXPORT double HMSegmentedControlVersionNumber;
13 |
14 | //! Project version string for HMSegmentedControl.
15 | FOUNDATION_EXPORT const unsigned char HMSegmentedControlVersionString[];
16 |
17 | #import
18 |
19 |
20 |
--------------------------------------------------------------------------------
/HMSegmentedControl.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = "HMSegmentedControl"
3 | s.version = "1.5.4"
4 | s.summary = "A drop-in replacement for UISegmentedControl mimicking the style of the one in Google Currents and various other Google products."
5 | s.homepage = "https://github.com/HeshamMegid/HMSegmentedControl"
6 | s.license = { :type => 'MIT', :file => 'LICENSE.md' }
7 | s.author = { "Hesham Abd-Elmegid" => "hesham.abdelmegid@gmail.com" }
8 | s.source = { :git => "https://github.com/fuzz-productions/HMSegmentedControl.git", :tag => "v1.5.4" }
9 | s.platform = :ios, '7.0'
10 | s.requires_arc = true
11 | s.source_files = 'HMSegmentedControl/*.{h,m}'
12 | s.framework = 'QuartzCore'
13 | end
14 |
--------------------------------------------------------------------------------
/Framework/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.5.3
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 | NSPrincipalClass
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/HMSegmentedControlExample/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // HMSegmentedControlExample
4 | //
5 | // Created by Hesham Abd-Elmegid on 25/12/12.
6 | // Copyright (c) 2012 Hesham Abd-Elmegid. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | #import "ViewController.h"
12 |
13 | @implementation AppDelegate
14 |
15 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
16 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
17 | self.viewController = [[ViewController alloc] init];
18 | UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
19 | self.window.rootViewController = navigationController;
20 | [self.window makeKeyAndVisible];
21 | return YES;
22 | }
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | # License
2 |
3 | ## MIT License
4 |
5 | Copyright (c) 2012 Hesham Abd-Elmegid (http://www.hesh.am)
6 |
7 | Permission is hereby granted, free of charge, to any person obtaining a copy
8 | of this software and associated documentation files (the "Software"), to deal
9 | in the Software without restriction, including without limitation the rights
10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | copies of the Software, and to permit persons to whom the Software is
12 | furnished to do so, subject to the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included in
15 | all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | THE SOFTWARE.
--------------------------------------------------------------------------------
/HMSegmentedControlExample/Launch Screen.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/HMSegmentedControlExample/HMSegmentedControlExample-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIcons
12 |
13 | CFBundleIcons~ipad
14 |
15 | CFBundleIdentifier
16 | $(PRODUCT_BUNDLE_IDENTIFIER)
17 | CFBundleInfoDictionaryVersion
18 | 6.0
19 | CFBundleName
20 | ${PRODUCT_NAME}
21 | CFBundlePackageType
22 | APPL
23 | CFBundleShortVersionString
24 | 1.0
25 | CFBundleSignature
26 | ????
27 | CFBundleVersion
28 | 1.0
29 | LSRequiresIPhoneOS
30 |
31 | UILaunchStoryboardName
32 | Launch Screen
33 | UIRequiredDeviceCapabilities
34 |
35 | armv7
36 |
37 | UISupportedInterfaceOrientations
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationLandscapeLeft
41 | UIInterfaceOrientationLandscapeRight
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | HMSegmentedControl
2 | ===
3 |
4 | [](http://cocoadocs.org/docsets/HMSegmentedControl)
5 | [](https://github.com/Carthage/Carthage)
6 | [](http://cocoadocs.org/docsets/HMSegmentedControl)
7 | [](http://opensource.org/licenses/MIT)
8 |
9 | A drop-in replacement for UISegmentedControl mimicking the style of the segmented control used in Google Currents and various other Google products.
10 |
11 | # Features
12 | - Supports both text and images
13 | - Support horizontal scrolling
14 | - Supports advanced title styling with text attributes for font, color, kerning, shadow, etc.
15 | - Supports selection indicator both on top and bottom
16 | - Supports blocks
17 | - Works with ARC and iOS >= 7
18 |
19 | # Installation
20 |
21 | ### CocoaPods
22 | The easiest way of installing HMSegmentedControl is via [CocoaPods](http://cocoapods.org/).
23 |
24 | ```
25 | pod 'HMSegmentedControl'
26 | ```
27 |
28 | ### Old-fashioned way
29 |
30 | - Add `HMSegmentedControl.h` and `HMSegmentedControl.m` to your project.
31 | - Add `QuartzCore.framework` to your linked frameworks.
32 | - `#import "HMSegmentedControl.h"` where you want to add the control.
33 |
34 | # Usage
35 |
36 | The code below will create a segmented control with the default looks:
37 |
38 | ``` objective-c
39 | HMSegmentedControl *segmentedControl = [[HMSegmentedControl alloc] initWithSectionTitles:@[@"One", @"Two", @"Three"]];
40 | segmentedControl.frame = CGRectMake(10, 10, 300, 60);
41 | [segmentedControl addTarget:self action:@selector(segmentedControlChangedValue:) forControlEvents:UIControlEventValueChanged];
42 | [self.view addSubview:segmentedControl];
43 | ```
44 |
45 | Included is a demo project showing how to fully customise the control.
46 |
47 | 
48 |
49 | # Apps using HMSegmentedControl
50 |
51 | If you are using HMSegmentedControl in your app or know of an app that uses it, please add it to [this list](https://github.com/HeshamMegid/HMSegmentedControl/wiki/Apps-using-HMSegmentedControl).
52 |
53 |
54 | # License
55 |
56 | HMSegmentedControl is licensed under the terms of the MIT License. Please see the [LICENSE](LICENSE.md) file for full details.
57 |
58 | If this code was helpful, I would love to hear from you.
59 |
60 | [@HeshamMegid](http://twitter.com/HeshamMegid)
61 | [http://hesh.am](http://hesh.am)
62 |
--------------------------------------------------------------------------------
/HMSegmentedControl.xcodeproj/xcshareddata/xcschemes/HMSegmentedControl.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
34 |
35 |
45 |
46 |
52 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
70 |
71 |
72 |
73 |
75 |
76 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/HMSegmentedControl/HMSegmentedControl.h:
--------------------------------------------------------------------------------
1 | //
2 | // HMSegmentedControl.h
3 | // HMSegmentedControl
4 | //
5 | // Created by Hesham Abd-Elmegid on 23/12/12.
6 | // Copyright (c) 2012-2015 Hesham Abd-Elmegid. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @class HMSegmentedControl;
12 |
13 | typedef void (^IndexChangeBlock)(NSInteger index);
14 | typedef NSAttributedString *(^HMTitleFormatterBlock)(HMSegmentedControl *segmentedControl, NSString *title, NSUInteger index, BOOL selected);
15 |
16 | typedef NS_ENUM(NSInteger, HMSegmentedControlSelectionStyle) {
17 | HMSegmentedControlSelectionStyleTextWidthStripe, // Indicator width will only be as big as the text width
18 | HMSegmentedControlSelectionStyleFullWidthStripe, // Indicator width will fill the whole segment
19 | HMSegmentedControlSelectionStyleBox, // A rectangle that covers the whole segment
20 | HMSegmentedControlSelectionStyleArrow // An arrow in the middle of the segment pointing up or down depending on `HMSegmentedControlSelectionIndicatorLocation`
21 | };
22 |
23 | typedef NS_ENUM(NSInteger, HMSegmentedControlSelectionIndicatorLocation) {
24 | HMSegmentedControlSelectionIndicatorLocationUp,
25 | HMSegmentedControlSelectionIndicatorLocationDown,
26 | HMSegmentedControlSelectionIndicatorLocationNone // No selection indicator
27 | };
28 |
29 | typedef NS_ENUM(NSInteger, HMSegmentedControlSegmentWidthStyle) {
30 | HMSegmentedControlSegmentWidthStyleFixed, // Segment width is fixed
31 | HMSegmentedControlSegmentWidthStyleDynamic, // Segment width will only be as big as the text width (including inset)
32 | };
33 |
34 | typedef NS_OPTIONS(NSInteger, HMSegmentedControlBorderType) {
35 | HMSegmentedControlBorderTypeNone = 0,
36 | HMSegmentedControlBorderTypeTop = (1 << 0),
37 | HMSegmentedControlBorderTypeLeft = (1 << 1),
38 | HMSegmentedControlBorderTypeBottom = (1 << 2),
39 | HMSegmentedControlBorderTypeRight = (1 << 3)
40 | };
41 |
42 | enum {
43 | HMSegmentedControlNoSegment = -1 // Segment index for no selected segment
44 | };
45 |
46 | typedef NS_ENUM(NSInteger, HMSegmentedControlType) {
47 | HMSegmentedControlTypeText,
48 | HMSegmentedControlTypeImages,
49 | HMSegmentedControlTypeTextImages
50 | };
51 |
52 | @interface HMSegmentedControl : UIControl
53 |
54 | @property (nonatomic, strong) NSArray *sectionTitles;
55 | @property (nonatomic, strong) NSArray *sectionImages;
56 | @property (nonatomic, strong) NSArray *sectionSelectedImages;
57 |
58 | /**
59 | Provide a block to be executed when selected index is changed.
60 |
61 | Alternativly, you could use `addTarget:action:forControlEvents:`
62 | */
63 | @property (nonatomic, copy) IndexChangeBlock indexChangeBlock;
64 |
65 | /**
66 | Used to apply custom text styling to titles when set.
67 |
68 | When this block is set, no additional styling is applied to the `NSAttributedString` object returned from this block.
69 | */
70 | @property (nonatomic, copy) HMTitleFormatterBlock titleFormatter;
71 |
72 | /**
73 | Text attributes to apply to item title text.
74 | */
75 | @property (nonatomic, strong) NSDictionary *titleTextAttributes UI_APPEARANCE_SELECTOR;
76 |
77 | /*
78 | Text attributes to apply to selected item title text.
79 |
80 | Attributes not set in this dictionary are inherited from `titleTextAttributes`.
81 | */
82 | @property (nonatomic, strong) NSDictionary *selectedTitleTextAttributes UI_APPEARANCE_SELECTOR;
83 |
84 | /**
85 | Segmented control background color.
86 |
87 | Default is `[UIColor whiteColor]`
88 | */
89 | @property (nonatomic, strong) UIColor *backgroundColor UI_APPEARANCE_SELECTOR;
90 |
91 | /**
92 | Color for the selection indicator stripe
93 |
94 | Default is `R:52, G:181, B:229`
95 | */
96 | @property (nonatomic, strong) UIColor *selectionIndicatorColor UI_APPEARANCE_SELECTOR;
97 |
98 | /**
99 | Color for the selection indicator box
100 |
101 | Default is selectionIndicatorColor
102 | */
103 | @property (nonatomic, strong) UIColor *selectionIndicatorBoxColor UI_APPEARANCE_SELECTOR;
104 |
105 | /**
106 | Color for the vertical divider between segments.
107 |
108 | Default is `[UIColor blackColor]`
109 | */
110 | @property (nonatomic, strong) UIColor *verticalDividerColor UI_APPEARANCE_SELECTOR;
111 |
112 | /**
113 | Opacity for the seletion indicator box.
114 |
115 | Default is `0.2f`
116 | */
117 | @property (nonatomic) CGFloat selectionIndicatorBoxOpacity;
118 |
119 | /**
120 | Width the vertical divider between segments that is added when `verticalDividerEnabled` is set to YES.
121 |
122 | Default is `1.0f`
123 | */
124 | @property (nonatomic, assign) CGFloat verticalDividerWidth;
125 |
126 | /**
127 | Specifies the style of the control
128 |
129 | Default is `HMSegmentedControlTypeText`
130 | */
131 | @property (nonatomic, assign) HMSegmentedControlType type;
132 |
133 | /**
134 | Specifies the style of the selection indicator.
135 |
136 | Default is `HMSegmentedControlSelectionStyleTextWidthStripe`
137 | */
138 | @property (nonatomic, assign) HMSegmentedControlSelectionStyle selectionStyle;
139 |
140 | /**
141 | Specifies the style of the segment's width.
142 |
143 | Default is `HMSegmentedControlSegmentWidthStyleFixed`
144 | */
145 | @property (nonatomic, assign) HMSegmentedControlSegmentWidthStyle segmentWidthStyle;
146 |
147 | /**
148 | Specifies the location of the selection indicator.
149 |
150 | Default is `HMSegmentedControlSelectionIndicatorLocationUp`
151 | */
152 | @property (nonatomic, assign) HMSegmentedControlSelectionIndicatorLocation selectionIndicatorLocation;
153 |
154 | /*
155 | Specifies the border type.
156 |
157 | Default is `HMSegmentedControlBorderTypeNone`
158 | */
159 | @property (nonatomic, assign) HMSegmentedControlBorderType borderType;
160 |
161 | /**
162 | Specifies the border color.
163 |
164 | Default is `[UIColor blackColor]`
165 | */
166 | @property (nonatomic, strong) UIColor *borderColor;
167 |
168 | /**
169 | Specifies the border width.
170 |
171 | Default is `1.0f`
172 | */
173 | @property (nonatomic, assign) CGFloat borderWidth;
174 |
175 | /**
176 | Default is YES. Set to NO to deny scrolling by dragging the scrollView by the user.
177 | */
178 | @property(nonatomic, getter = isUserDraggable) BOOL userDraggable;
179 |
180 | /**
181 | Default is YES. Set to NO to deny any touch events by the user.
182 | */
183 | @property(nonatomic, getter = isTouchEnabled) BOOL touchEnabled;
184 |
185 | /**
186 | Default is NO. Set to YES to show a vertical divider between the segments.
187 | */
188 | @property(nonatomic, getter = isVerticalDividerEnabled) BOOL verticalDividerEnabled;
189 |
190 | /**
191 | Index of the currently selected segment.
192 | */
193 | @property (nonatomic, assign) NSInteger selectedSegmentIndex;
194 |
195 | /**
196 | Height of the selection indicator. Only effective when `HMSegmentedControlSelectionStyle` is either `HMSegmentedControlSelectionStyleTextWidthStripe` or `HMSegmentedControlSelectionStyleFullWidthStripe`.
197 |
198 | Default is 5.0
199 | */
200 | @property (nonatomic, readwrite) CGFloat selectionIndicatorHeight;
201 |
202 | /**
203 | Edge insets for the selection indicator.
204 | NOTE: This does not affect the bounding box of HMSegmentedControlSelectionStyleBox
205 |
206 | When HMSegmentedControlSelectionIndicatorLocationUp is selected, bottom edge insets are not used
207 |
208 | When HMSegmentedControlSelectionIndicatorLocationDown is selected, top edge insets are not used
209 |
210 | Defaults are top: 0.0f
211 | left: 0.0f
212 | bottom: 0.0f
213 | right: 0.0f
214 | */
215 | @property (nonatomic, readwrite) UIEdgeInsets selectionIndicatorEdgeInsets;
216 |
217 | /**
218 | Inset left and right edges of segments.
219 |
220 | Default is UIEdgeInsetsMake(0, 5, 0, 5)
221 | */
222 | @property (nonatomic, readwrite) UIEdgeInsets segmentEdgeInset;
223 |
224 | @property (nonatomic, readwrite) UIEdgeInsets enlargeEdgeInset;
225 |
226 | /**
227 | Default is YES. Set to NO to disable animation during user selection.
228 | */
229 | @property (nonatomic) BOOL shouldAnimateUserSelection;
230 |
231 | - (id)initWithSectionTitles:(NSArray *)sectiontitles;
232 | - (id)initWithSectionImages:(NSArray *)sectionImages sectionSelectedImages:(NSArray *)sectionSelectedImages;
233 | - (instancetype)initWithSectionImages:(NSArray *)sectionImages sectionSelectedImages:(NSArray *)sectionSelectedImages titlesForSections:(NSArray *)sectiontitles;
234 | - (void)setSelectedSegmentIndex:(NSUInteger)index animated:(BOOL)animated;
235 | - (void)setIndexChangeBlock:(IndexChangeBlock)indexChangeBlock;
236 | - (void)setTitleFormatter:(HMTitleFormatterBlock)titleFormatter;
237 |
238 | @end
239 |
--------------------------------------------------------------------------------
/HMSegmentedControlExample/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // HMSegmentedControlExample
4 | //
5 | // Created by Hesham Abd-Elmegid on 23/12/12.
6 | // Copyright (c) 2012 Hesham Abd-Elmegid. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | @import HMSegmentedControl;
11 |
12 | @interface ViewController ()
13 |
14 | @property (nonatomic, strong) UIScrollView *scrollView;
15 | @property (nonatomic, strong) HMSegmentedControl *segmentedControl4;
16 |
17 | @end
18 |
19 | @implementation ViewController
20 |
21 | - (void)viewDidLoad {
22 | [super viewDidLoad];
23 |
24 | self.title = @"HMSegmentedControl Demo";
25 | self.view.backgroundColor = [UIColor whiteColor];
26 | self.edgesForExtendedLayout = UIRectEdgeNone;
27 |
28 | CGFloat viewWidth = CGRectGetWidth(self.view.frame);
29 |
30 | // Minimum code required to use the segmented control with the default styling.
31 | HMSegmentedControl *segmentedControl = [[HMSegmentedControl alloc] initWithSectionTitles:@[@"Trending", @"News", @"Library"]];
32 | segmentedControl.frame = CGRectMake(0, 20, viewWidth, 40);
33 | segmentedControl.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth;
34 | [segmentedControl addTarget:self action:@selector(segmentedControlChangedValue:) forControlEvents:UIControlEventValueChanged];
35 | [self.view addSubview:segmentedControl];
36 |
37 |
38 | // Segmented control with scrolling
39 | HMSegmentedControl *segmentedControl1 = [[HMSegmentedControl alloc] initWithSectionTitles:@[@"One", @"Two", @"Three", @"Four", @"Five", @"Six", @"Seven", @"Eight"]];
40 | segmentedControl1.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth;
41 | segmentedControl1.frame = CGRectMake(0, 60, viewWidth, 40);
42 | segmentedControl1.segmentEdgeInset = UIEdgeInsetsMake(0, 10, 0, 10);
43 | segmentedControl1.selectionStyle = HMSegmentedControlSelectionStyleFullWidthStripe;
44 | segmentedControl1.selectionIndicatorLocation = HMSegmentedControlSelectionIndicatorLocationDown;
45 | segmentedControl1.verticalDividerEnabled = YES;
46 | segmentedControl1.verticalDividerColor = [UIColor blackColor];
47 | segmentedControl1.verticalDividerWidth = 1.0f;
48 | [segmentedControl1 setTitleFormatter:^NSAttributedString *(HMSegmentedControl *segmentedControl, NSString *title, NSUInteger index, BOOL selected) {
49 | NSAttributedString *attString = [[NSAttributedString alloc] initWithString:title attributes:@{NSForegroundColorAttributeName : [UIColor blueColor]}];
50 | return attString;
51 | }];
52 | [segmentedControl1 addTarget:self action:@selector(segmentedControlChangedValue:) forControlEvents:UIControlEventValueChanged];
53 | [self.view addSubview:segmentedControl1];
54 |
55 |
56 | // Segmented control with images
57 | NSArray *images = @[[UIImage imageNamed:@"1"],
58 | [UIImage imageNamed:@"2"],
59 | [UIImage imageNamed:@"3"],
60 | [UIImage imageNamed:@"4"]];
61 |
62 | NSArray *selectedImages = @[[UIImage imageNamed:@"1-selected"],
63 | [UIImage imageNamed:@"2-selected"],
64 | [UIImage imageNamed:@"3-selected"],
65 | [UIImage imageNamed:@"4-selected"]];
66 |
67 | HMSegmentedControl *segmentedControl2 = [[HMSegmentedControl alloc] initWithSectionImages:images sectionSelectedImages:selectedImages];
68 | segmentedControl2.frame = CGRectMake(0, 120, viewWidth, 50);
69 | segmentedControl2.selectionIndicatorHeight = 4.0f;
70 | segmentedControl2.backgroundColor = [UIColor clearColor];
71 | segmentedControl2.selectionIndicatorLocation = HMSegmentedControlSelectionIndicatorLocationDown;
72 | segmentedControl2.selectionStyle = HMSegmentedControlSelectionStyleTextWidthStripe;
73 | [segmentedControl2 addTarget:self action:@selector(segmentedControlChangedValue:) forControlEvents:UIControlEventValueChanged];
74 | [self.view addSubview:segmentedControl2];
75 |
76 |
77 | // Segmented control with more customization and indexChangeBlock
78 | HMSegmentedControl *segmentedControl3 = [[HMSegmentedControl alloc] initWithSectionTitles:@[@"One", @"Two", @"Three", @"4", @"Five"]];
79 | [segmentedControl3 setFrame:CGRectMake(0, 180, viewWidth, 50)];
80 | [segmentedControl3 setIndexChangeBlock:^(NSInteger index) {
81 | NSLog(@"Selected index %ld (via block)", (long)index);
82 | }];
83 | segmentedControl3.selectionIndicatorHeight = 4.0f;
84 | segmentedControl3.backgroundColor = [UIColor colorWithRed:0.1 green:0.4 blue:0.8 alpha:1];
85 | segmentedControl3.titleTextAttributes = @{NSForegroundColorAttributeName : [UIColor whiteColor]};
86 | segmentedControl3.selectionIndicatorColor = [UIColor colorWithRed:0.5 green:0.8 blue:1 alpha:1];
87 | segmentedControl3.selectionIndicatorBoxColor = [UIColor blackColor];
88 | segmentedControl3.selectionIndicatorBoxOpacity = 1.0;
89 | segmentedControl3.selectionStyle = HMSegmentedControlSelectionStyleBox;
90 | segmentedControl3.selectedSegmentIndex = HMSegmentedControlNoSegment;
91 | segmentedControl3.selectionIndicatorLocation = HMSegmentedControlSelectionIndicatorLocationDown;
92 | segmentedControl3.shouldAnimateUserSelection = NO;
93 | segmentedControl3.tag = 2;
94 | [self.view addSubview:segmentedControl3];
95 |
96 | // Tying up the segmented control to a scroll view
97 | self.segmentedControl4 = [[HMSegmentedControl alloc] initWithFrame:CGRectMake(0, 260, viewWidth, 50)];
98 | self.segmentedControl4.sectionTitles = @[@"Worldwide", @"Local", @"Headlines"];
99 | self.segmentedControl4.selectedSegmentIndex = 1;
100 | self.segmentedControl4.backgroundColor = [UIColor colorWithRed:0.7 green:0.7 blue:0.7 alpha:1];
101 | self.segmentedControl4.titleTextAttributes = @{NSForegroundColorAttributeName : [UIColor whiteColor]};
102 | self.segmentedControl4.selectedTitleTextAttributes = @{NSForegroundColorAttributeName : [UIColor colorWithRed:0.1 green:0.1 blue:0.1 alpha:1]};
103 | self.segmentedControl4.selectionIndicatorColor = [UIColor colorWithRed:0.3 green:0.3 blue:0.3 alpha:1];
104 | self.segmentedControl4.selectionStyle = HMSegmentedControlSelectionStyleBox;
105 | self.segmentedControl4.selectionIndicatorLocation = HMSegmentedControlSelectionIndicatorLocationUp;
106 | self.segmentedControl4.tag = 3;
107 |
108 | __weak typeof(self) weakSelf = self;
109 | [self.segmentedControl4 setIndexChangeBlock:^(NSInteger index) {
110 | [weakSelf.scrollView scrollRectToVisible:CGRectMake(viewWidth * index, 0, viewWidth, 200) animated:YES];
111 | }];
112 |
113 | [self.view addSubview:self.segmentedControl4];
114 |
115 | self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 310, viewWidth, 210)];
116 | self.scrollView.backgroundColor = [UIColor colorWithRed:0.7 green:0.7 blue:0.7 alpha:1];
117 | self.scrollView.pagingEnabled = YES;
118 | self.scrollView.showsHorizontalScrollIndicator = NO;
119 | self.scrollView.contentSize = CGSizeMake(viewWidth * 3, 200);
120 | self.scrollView.delegate = self;
121 | [self.scrollView scrollRectToVisible:CGRectMake(viewWidth, 0, viewWidth, 200) animated:NO];
122 | [self.view addSubview:self.scrollView];
123 |
124 | UILabel *label1 = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, viewWidth, 210)];
125 | [self setApperanceForLabel:label1];
126 | label1.text = @"Worldwide";
127 | [self.scrollView addSubview:label1];
128 |
129 | UILabel *label2 = [[UILabel alloc] initWithFrame:CGRectMake(viewWidth, 0, viewWidth, 210)];
130 | [self setApperanceForLabel:label2];
131 | label2.text = @"Local";
132 | [self.scrollView addSubview:label2];
133 |
134 | UILabel *label3 = [[UILabel alloc] initWithFrame:CGRectMake(viewWidth * 2, 0, viewWidth, 210)];
135 | [self setApperanceForLabel:label3];
136 | label3.text = @"Headlines";
137 | [self.scrollView addSubview:label3];
138 | }
139 |
140 | - (void)setApperanceForLabel:(UILabel *)label {
141 | CGFloat hue = ( arc4random() % 256 / 256.0 ); // 0.0 to 1.0
142 | CGFloat saturation = ( arc4random() % 128 / 256.0 ) + 0.5; // 0.5 to 1.0, away from white
143 | CGFloat brightness = ( arc4random() % 128 / 256.0 ) + 0.5; // 0.5 to 1.0, away from black
144 | UIColor *color = [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:1];
145 | label.backgroundColor = color;
146 | label.textColor = [UIColor whiteColor];
147 | label.font = [UIFont systemFontOfSize:21.0f];
148 | label.textAlignment = NSTextAlignmentCenter;
149 | }
150 |
151 | - (void)segmentedControlChangedValue:(HMSegmentedControl *)segmentedControl {
152 | NSLog(@"Selected index %ld (via UIControlEventValueChanged)", (long)segmentedControl.selectedSegmentIndex);
153 | }
154 |
155 | - (void)uisegmentedControlChangedValue:(UISegmentedControl *)segmentedControl {
156 | NSLog(@"Selected index %ld", (long)segmentedControl.selectedSegmentIndex);
157 | }
158 |
159 | #pragma mark - UIScrollViewDelegate
160 |
161 | - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
162 | CGFloat pageWidth = scrollView.frame.size.width;
163 | NSInteger page = scrollView.contentOffset.x / pageWidth;
164 |
165 | [self.segmentedControl4 setSelectedSegmentIndex:page animated:YES];
166 | }
167 |
168 | @end
169 |
--------------------------------------------------------------------------------
/HMSegmentedControl.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 9C1632E71DA57214001FB468 /* HMSegmentedControl-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C1632E41DA57214001FB468 /* HMSegmentedControl-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
11 | 9C1632EC1DA57220001FB468 /* HMSegmentedControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C1632EA1DA57220001FB468 /* HMSegmentedControl.h */; settings = {ATTRIBUTES = (Public, ); }; };
12 | 9C1632ED1DA57220001FB468 /* HMSegmentedControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C1632EB1DA57220001FB468 /* HMSegmentedControl.m */; };
13 | 9C1633241DA57320001FB468 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C16330A1DA57320001FB468 /* AppDelegate.m */; };
14 | 9C1633271DA57320001FB468 /* 1-selected.png in Resources */ = {isa = PBXBuildFile; fileRef = 9C1633111DA57320001FB468 /* 1-selected.png */; };
15 | 9C1633281DA57320001FB468 /* 1-selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 9C1633121DA57320001FB468 /* 1-selected@2x.png */; };
16 | 9C1633291DA57320001FB468 /* 1.png in Resources */ = {isa = PBXBuildFile; fileRef = 9C1633131DA57320001FB468 /* 1.png */; };
17 | 9C16332A1DA57320001FB468 /* 1@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 9C1633141DA57320001FB468 /* 1@2x.png */; };
18 | 9C16332B1DA57320001FB468 /* 2-selected.png in Resources */ = {isa = PBXBuildFile; fileRef = 9C1633151DA57320001FB468 /* 2-selected.png */; };
19 | 9C16332C1DA57320001FB468 /* 2-selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 9C1633161DA57320001FB468 /* 2-selected@2x.png */; };
20 | 9C16332D1DA57320001FB468 /* 2.png in Resources */ = {isa = PBXBuildFile; fileRef = 9C1633171DA57320001FB468 /* 2.png */; };
21 | 9C16332E1DA57320001FB468 /* 2@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 9C1633181DA57320001FB468 /* 2@2x.png */; };
22 | 9C16332F1DA57320001FB468 /* 3-selected.png in Resources */ = {isa = PBXBuildFile; fileRef = 9C1633191DA57320001FB468 /* 3-selected.png */; };
23 | 9C1633301DA57320001FB468 /* 3-selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 9C16331A1DA57320001FB468 /* 3-selected@2x.png */; };
24 | 9C1633311DA57320001FB468 /* 3.png in Resources */ = {isa = PBXBuildFile; fileRef = 9C16331B1DA57320001FB468 /* 3.png */; };
25 | 9C1633321DA57320001FB468 /* 3@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 9C16331C1DA57320001FB468 /* 3@2x.png */; };
26 | 9C1633331DA57320001FB468 /* 4-selected.png in Resources */ = {isa = PBXBuildFile; fileRef = 9C16331D1DA57320001FB468 /* 4-selected.png */; };
27 | 9C1633341DA57320001FB468 /* 4-selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 9C16331E1DA57320001FB468 /* 4-selected@2x.png */; };
28 | 9C1633351DA57320001FB468 /* 4.png in Resources */ = {isa = PBXBuildFile; fileRef = 9C16331F1DA57320001FB468 /* 4.png */; };
29 | 9C1633361DA57320001FB468 /* 4@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 9C1633201DA57320001FB468 /* 4@2x.png */; };
30 | 9C1633371DA57320001FB468 /* Launch Screen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9C1633211DA57320001FB468 /* Launch Screen.xib */; };
31 | 9C1633381DA57320001FB468 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C1633231DA57320001FB468 /* ViewController.m */; };
32 | 9C16333B1DA573C5001FB468 /* HMSegmentedControl.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C1632D81DA57134001FB468 /* HMSegmentedControl.framework */; };
33 | 9C16333C1DA573C5001FB468 /* HMSegmentedControl.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9C1632D81DA57134001FB468 /* HMSegmentedControl.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
34 | 9C1633421DA574EB001FB468 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C1633411DA574EB001FB468 /* main.m */; };
35 | /* End PBXBuildFile section */
36 |
37 | /* Begin PBXContainerItemProxy section */
38 | 9C1633391DA573BD001FB468 /* PBXContainerItemProxy */ = {
39 | isa = PBXContainerItemProxy;
40 | containerPortal = 9C1632CF1DA57134001FB468 /* Project object */;
41 | proxyType = 1;
42 | remoteGlobalIDString = 9C1632D71DA57134001FB468;
43 | remoteInfo = HMSegmentedControl;
44 | };
45 | /* End PBXContainerItemProxy section */
46 |
47 | /* Begin PBXCopyFilesBuildPhase section */
48 | 9C16333D1DA573C5001FB468 /* Embed Frameworks */ = {
49 | isa = PBXCopyFilesBuildPhase;
50 | buildActionMask = 2147483647;
51 | dstPath = "";
52 | dstSubfolderSpec = 10;
53 | files = (
54 | 9C16333C1DA573C5001FB468 /* HMSegmentedControl.framework in Embed Frameworks */,
55 | );
56 | name = "Embed Frameworks";
57 | runOnlyForDeploymentPostprocessing = 0;
58 | };
59 | /* End PBXCopyFilesBuildPhase section */
60 |
61 | /* Begin PBXFileReference section */
62 | 9C1632D81DA57134001FB468 /* HMSegmentedControl.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = HMSegmentedControl.framework; sourceTree = BUILT_PRODUCTS_DIR; };
63 | 9C1632E41DA57214001FB468 /* HMSegmentedControl-umbrella.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "HMSegmentedControl-umbrella.h"; sourceTree = ""; };
64 | 9C1632E51DA57214001FB468 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
65 | 9C1632E61DA57214001FB468 /* module.modulemap */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = "sourcecode.module-map"; path = module.modulemap; sourceTree = ""; };
66 | 9C1632EA1DA57220001FB468 /* HMSegmentedControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HMSegmentedControl.h; sourceTree = ""; };
67 | 9C1632EB1DA57220001FB468 /* HMSegmentedControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HMSegmentedControl.m; sourceTree = ""; };
68 | 9C1632F21DA572BA001FB468 /* HMSegmentedControlExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HMSegmentedControlExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
69 | 9C1633091DA57320001FB468 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
70 | 9C16330A1DA57320001FB468 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
71 | 9C16330E1DA57320001FB468 /* HMSegmentedControlExample-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "HMSegmentedControlExample-Info.plist"; sourceTree = ""; };
72 | 9C16330F1DA57320001FB468 /* HMSegmentedControlExample-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "HMSegmentedControlExample-Prefix.pch"; sourceTree = ""; };
73 | 9C1633111DA57320001FB468 /* 1-selected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "1-selected.png"; sourceTree = ""; };
74 | 9C1633121DA57320001FB468 /* 1-selected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "1-selected@2x.png"; sourceTree = ""; };
75 | 9C1633131DA57320001FB468 /* 1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = 1.png; sourceTree = ""; };
76 | 9C1633141DA57320001FB468 /* 1@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "1@2x.png"; sourceTree = ""; };
77 | 9C1633151DA57320001FB468 /* 2-selected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "2-selected.png"; sourceTree = ""; };
78 | 9C1633161DA57320001FB468 /* 2-selected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "2-selected@2x.png"; sourceTree = ""; };
79 | 9C1633171DA57320001FB468 /* 2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = 2.png; sourceTree = ""; };
80 | 9C1633181DA57320001FB468 /* 2@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "2@2x.png"; sourceTree = ""; };
81 | 9C1633191DA57320001FB468 /* 3-selected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "3-selected.png"; sourceTree = ""; };
82 | 9C16331A1DA57320001FB468 /* 3-selected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "3-selected@2x.png"; sourceTree = ""; };
83 | 9C16331B1DA57320001FB468 /* 3.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = 3.png; sourceTree = ""; };
84 | 9C16331C1DA57320001FB468 /* 3@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "3@2x.png"; sourceTree = ""; };
85 | 9C16331D1DA57320001FB468 /* 4-selected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "4-selected.png"; sourceTree = ""; };
86 | 9C16331E1DA57320001FB468 /* 4-selected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "4-selected@2x.png"; sourceTree = ""; };
87 | 9C16331F1DA57320001FB468 /* 4.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = 4.png; sourceTree = ""; };
88 | 9C1633201DA57320001FB468 /* 4@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "4@2x.png"; sourceTree = ""; };
89 | 9C1633211DA57320001FB468 /* Launch Screen.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = "Launch Screen.xib"; sourceTree = ""; };
90 | 9C1633221DA57320001FB468 /* ViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; };
91 | 9C1633231DA57320001FB468 /* ViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; };
92 | 9C1633411DA574EB001FB468 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
93 | /* End PBXFileReference section */
94 |
95 | /* Begin PBXFrameworksBuildPhase section */
96 | 9C1632D41DA57134001FB468 /* Frameworks */ = {
97 | isa = PBXFrameworksBuildPhase;
98 | buildActionMask = 2147483647;
99 | files = (
100 | );
101 | runOnlyForDeploymentPostprocessing = 0;
102 | };
103 | 9C1632EF1DA572BA001FB468 /* Frameworks */ = {
104 | isa = PBXFrameworksBuildPhase;
105 | buildActionMask = 2147483647;
106 | files = (
107 | 9C16333B1DA573C5001FB468 /* HMSegmentedControl.framework in Frameworks */,
108 | );
109 | runOnlyForDeploymentPostprocessing = 0;
110 | };
111 | /* End PBXFrameworksBuildPhase section */
112 |
113 | /* Begin PBXGroup section */
114 | 9C1632CE1DA57134001FB468 = {
115 | isa = PBXGroup;
116 | children = (
117 | 9C1632E91DA57220001FB468 /* HMSegmentedControl */,
118 | 9C1632F31DA572BA001FB468 /* HMSegmentedControlExample */,
119 | 9C1632E31DA57214001FB468 /* Framework */,
120 | 9C1632D91DA57134001FB468 /* Products */,
121 | );
122 | sourceTree = "";
123 | };
124 | 9C1632D91DA57134001FB468 /* Products */ = {
125 | isa = PBXGroup;
126 | children = (
127 | 9C1632D81DA57134001FB468 /* HMSegmentedControl.framework */,
128 | 9C1632F21DA572BA001FB468 /* HMSegmentedControlExample.app */,
129 | );
130 | name = Products;
131 | sourceTree = "";
132 | };
133 | 9C1632E31DA57214001FB468 /* Framework */ = {
134 | isa = PBXGroup;
135 | children = (
136 | 9C1632E41DA57214001FB468 /* HMSegmentedControl-umbrella.h */,
137 | 9C1632E51DA57214001FB468 /* Info.plist */,
138 | 9C1632E61DA57214001FB468 /* module.modulemap */,
139 | );
140 | path = Framework;
141 | sourceTree = "";
142 | };
143 | 9C1632E91DA57220001FB468 /* HMSegmentedControl */ = {
144 | isa = PBXGroup;
145 | children = (
146 | 9C1632EA1DA57220001FB468 /* HMSegmentedControl.h */,
147 | 9C1632EB1DA57220001FB468 /* HMSegmentedControl.m */,
148 | );
149 | path = HMSegmentedControl;
150 | sourceTree = "";
151 | };
152 | 9C1632F31DA572BA001FB468 /* HMSegmentedControlExample */ = {
153 | isa = PBXGroup;
154 | children = (
155 | 9C1633091DA57320001FB468 /* AppDelegate.h */,
156 | 9C16330A1DA57320001FB468 /* AppDelegate.m */,
157 | 9C1633221DA57320001FB468 /* ViewController.h */,
158 | 9C1633231DA57320001FB468 /* ViewController.m */,
159 | 9C1633101DA57320001FB468 /* Images */,
160 | 9C16330E1DA57320001FB468 /* HMSegmentedControlExample-Info.plist */,
161 | 9C16330F1DA57320001FB468 /* HMSegmentedControlExample-Prefix.pch */,
162 | 9C1633211DA57320001FB468 /* Launch Screen.xib */,
163 | 9C1632F41DA572BA001FB468 /* Supporting Files */,
164 | );
165 | path = HMSegmentedControlExample;
166 | sourceTree = "";
167 | };
168 | 9C1632F41DA572BA001FB468 /* Supporting Files */ = {
169 | isa = PBXGroup;
170 | children = (
171 | 9C1633411DA574EB001FB468 /* main.m */,
172 | );
173 | name = "Supporting Files";
174 | sourceTree = "";
175 | };
176 | 9C1633101DA57320001FB468 /* Images */ = {
177 | isa = PBXGroup;
178 | children = (
179 | 9C1633111DA57320001FB468 /* 1-selected.png */,
180 | 9C1633121DA57320001FB468 /* 1-selected@2x.png */,
181 | 9C1633131DA57320001FB468 /* 1.png */,
182 | 9C1633141DA57320001FB468 /* 1@2x.png */,
183 | 9C1633151DA57320001FB468 /* 2-selected.png */,
184 | 9C1633161DA57320001FB468 /* 2-selected@2x.png */,
185 | 9C1633171DA57320001FB468 /* 2.png */,
186 | 9C1633181DA57320001FB468 /* 2@2x.png */,
187 | 9C1633191DA57320001FB468 /* 3-selected.png */,
188 | 9C16331A1DA57320001FB468 /* 3-selected@2x.png */,
189 | 9C16331B1DA57320001FB468 /* 3.png */,
190 | 9C16331C1DA57320001FB468 /* 3@2x.png */,
191 | 9C16331D1DA57320001FB468 /* 4-selected.png */,
192 | 9C16331E1DA57320001FB468 /* 4-selected@2x.png */,
193 | 9C16331F1DA57320001FB468 /* 4.png */,
194 | 9C1633201DA57320001FB468 /* 4@2x.png */,
195 | );
196 | path = Images;
197 | sourceTree = "";
198 | };
199 | /* End PBXGroup section */
200 |
201 | /* Begin PBXHeadersBuildPhase section */
202 | 9C1632D51DA57134001FB468 /* Headers */ = {
203 | isa = PBXHeadersBuildPhase;
204 | buildActionMask = 2147483647;
205 | files = (
206 | 9C1632EC1DA57220001FB468 /* HMSegmentedControl.h in Headers */,
207 | 9C1632E71DA57214001FB468 /* HMSegmentedControl-umbrella.h in Headers */,
208 | );
209 | runOnlyForDeploymentPostprocessing = 0;
210 | };
211 | /* End PBXHeadersBuildPhase section */
212 |
213 | /* Begin PBXNativeTarget section */
214 | 9C1632D71DA57134001FB468 /* HMSegmentedControl */ = {
215 | isa = PBXNativeTarget;
216 | buildConfigurationList = 9C1632E01DA57134001FB468 /* Build configuration list for PBXNativeTarget "HMSegmentedControl" */;
217 | buildPhases = (
218 | 9C1632D31DA57134001FB468 /* Sources */,
219 | 9C1632D41DA57134001FB468 /* Frameworks */,
220 | 9C1632D51DA57134001FB468 /* Headers */,
221 | 9C1632D61DA57134001FB468 /* Resources */,
222 | );
223 | buildRules = (
224 | );
225 | dependencies = (
226 | );
227 | name = HMSegmentedControl;
228 | productName = HMSegmentedControl;
229 | productReference = 9C1632D81DA57134001FB468 /* HMSegmentedControl.framework */;
230 | productType = "com.apple.product-type.framework";
231 | };
232 | 9C1632F11DA572BA001FB468 /* HMSegmentedControlExample */ = {
233 | isa = PBXNativeTarget;
234 | buildConfigurationList = 9C1633061DA572BA001FB468 /* Build configuration list for PBXNativeTarget "HMSegmentedControlExample" */;
235 | buildPhases = (
236 | 9C1632EE1DA572BA001FB468 /* Sources */,
237 | 9C1632EF1DA572BA001FB468 /* Frameworks */,
238 | 9C1632F01DA572BA001FB468 /* Resources */,
239 | 9C16333D1DA573C5001FB468 /* Embed Frameworks */,
240 | );
241 | buildRules = (
242 | );
243 | dependencies = (
244 | 9C16333A1DA573BD001FB468 /* PBXTargetDependency */,
245 | );
246 | name = HMSegmentedControlExample;
247 | productName = HMSegmentedControlExample;
248 | productReference = 9C1632F21DA572BA001FB468 /* HMSegmentedControlExample.app */;
249 | productType = "com.apple.product-type.application";
250 | };
251 | /* End PBXNativeTarget section */
252 |
253 | /* Begin PBXProject section */
254 | 9C1632CF1DA57134001FB468 /* Project object */ = {
255 | isa = PBXProject;
256 | attributes = {
257 | LastUpgradeCheck = 0800;
258 | ORGANIZATIONNAME = HeshamMegid;
259 | TargetAttributes = {
260 | 9C1632D71DA57134001FB468 = {
261 | CreatedOnToolsVersion = 8.0;
262 | DevelopmentTeam = C75GEDTP26;
263 | ProvisioningStyle = Automatic;
264 | };
265 | 9C1632F11DA572BA001FB468 = {
266 | CreatedOnToolsVersion = 8.0;
267 | DevelopmentTeam = C75GEDTP26;
268 | ProvisioningStyle = Automatic;
269 | };
270 | };
271 | };
272 | buildConfigurationList = 9C1632D21DA57134001FB468 /* Build configuration list for PBXProject "HMSegmentedControl" */;
273 | compatibilityVersion = "Xcode 3.2";
274 | developmentRegion = English;
275 | hasScannedForEncodings = 0;
276 | knownRegions = (
277 | en,
278 | Base,
279 | );
280 | mainGroup = 9C1632CE1DA57134001FB468;
281 | productRefGroup = 9C1632D91DA57134001FB468 /* Products */;
282 | projectDirPath = "";
283 | projectRoot = "";
284 | targets = (
285 | 9C1632D71DA57134001FB468 /* HMSegmentedControl */,
286 | 9C1632F11DA572BA001FB468 /* HMSegmentedControlExample */,
287 | );
288 | };
289 | /* End PBXProject section */
290 |
291 | /* Begin PBXResourcesBuildPhase section */
292 | 9C1632D61DA57134001FB468 /* Resources */ = {
293 | isa = PBXResourcesBuildPhase;
294 | buildActionMask = 2147483647;
295 | files = (
296 | );
297 | runOnlyForDeploymentPostprocessing = 0;
298 | };
299 | 9C1632F01DA572BA001FB468 /* Resources */ = {
300 | isa = PBXResourcesBuildPhase;
301 | buildActionMask = 2147483647;
302 | files = (
303 | 9C16332A1DA57320001FB468 /* 1@2x.png in Resources */,
304 | 9C1633281DA57320001FB468 /* 1-selected@2x.png in Resources */,
305 | 9C1633271DA57320001FB468 /* 1-selected.png in Resources */,
306 | 9C1633351DA57320001FB468 /* 4.png in Resources */,
307 | 9C16332B1DA57320001FB468 /* 2-selected.png in Resources */,
308 | 9C16332D1DA57320001FB468 /* 2.png in Resources */,
309 | 9C1633301DA57320001FB468 /* 3-selected@2x.png in Resources */,
310 | 9C1633371DA57320001FB468 /* Launch Screen.xib in Resources */,
311 | 9C1633361DA57320001FB468 /* 4@2x.png in Resources */,
312 | 9C1633341DA57320001FB468 /* 4-selected@2x.png in Resources */,
313 | 9C1633311DA57320001FB468 /* 3.png in Resources */,
314 | 9C16332F1DA57320001FB468 /* 3-selected.png in Resources */,
315 | 9C16332E1DA57320001FB468 /* 2@2x.png in Resources */,
316 | 9C16332C1DA57320001FB468 /* 2-selected@2x.png in Resources */,
317 | 9C1633331DA57320001FB468 /* 4-selected.png in Resources */,
318 | 9C1633321DA57320001FB468 /* 3@2x.png in Resources */,
319 | 9C1633291DA57320001FB468 /* 1.png in Resources */,
320 | );
321 | runOnlyForDeploymentPostprocessing = 0;
322 | };
323 | /* End PBXResourcesBuildPhase section */
324 |
325 | /* Begin PBXSourcesBuildPhase section */
326 | 9C1632D31DA57134001FB468 /* Sources */ = {
327 | isa = PBXSourcesBuildPhase;
328 | buildActionMask = 2147483647;
329 | files = (
330 | 9C1632ED1DA57220001FB468 /* HMSegmentedControl.m in Sources */,
331 | );
332 | runOnlyForDeploymentPostprocessing = 0;
333 | };
334 | 9C1632EE1DA572BA001FB468 /* Sources */ = {
335 | isa = PBXSourcesBuildPhase;
336 | buildActionMask = 2147483647;
337 | files = (
338 | 9C1633381DA57320001FB468 /* ViewController.m in Sources */,
339 | 9C1633421DA574EB001FB468 /* main.m in Sources */,
340 | 9C1633241DA57320001FB468 /* AppDelegate.m in Sources */,
341 | );
342 | runOnlyForDeploymentPostprocessing = 0;
343 | };
344 | /* End PBXSourcesBuildPhase section */
345 |
346 | /* Begin PBXTargetDependency section */
347 | 9C16333A1DA573BD001FB468 /* PBXTargetDependency */ = {
348 | isa = PBXTargetDependency;
349 | target = 9C1632D71DA57134001FB468 /* HMSegmentedControl */;
350 | targetProxy = 9C1633391DA573BD001FB468 /* PBXContainerItemProxy */;
351 | };
352 | /* End PBXTargetDependency section */
353 |
354 | /* Begin XCBuildConfiguration section */
355 | 9C1632DE1DA57134001FB468 /* Debug */ = {
356 | isa = XCBuildConfiguration;
357 | buildSettings = {
358 | ALWAYS_SEARCH_USER_PATHS = NO;
359 | CLANG_ANALYZER_NONNULL = YES;
360 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
361 | CLANG_CXX_LIBRARY = "libc++";
362 | CLANG_ENABLE_MODULES = YES;
363 | CLANG_ENABLE_OBJC_ARC = YES;
364 | CLANG_WARN_BOOL_CONVERSION = YES;
365 | CLANG_WARN_CONSTANT_CONVERSION = YES;
366 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
367 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
368 | CLANG_WARN_EMPTY_BODY = YES;
369 | CLANG_WARN_ENUM_CONVERSION = YES;
370 | CLANG_WARN_INFINITE_RECURSION = YES;
371 | CLANG_WARN_INT_CONVERSION = YES;
372 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
373 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
374 | CLANG_WARN_SUSPICIOUS_MOVES = YES;
375 | CLANG_WARN_UNREACHABLE_CODE = YES;
376 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
377 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
378 | COPY_PHASE_STRIP = NO;
379 | CURRENT_PROJECT_VERSION = 1;
380 | DEBUG_INFORMATION_FORMAT = dwarf;
381 | ENABLE_STRICT_OBJC_MSGSEND = YES;
382 | ENABLE_TESTABILITY = YES;
383 | GCC_C_LANGUAGE_STANDARD = gnu99;
384 | GCC_DYNAMIC_NO_PIC = NO;
385 | GCC_NO_COMMON_BLOCKS = YES;
386 | GCC_OPTIMIZATION_LEVEL = 0;
387 | GCC_PREPROCESSOR_DEFINITIONS = (
388 | "DEBUG=1",
389 | "$(inherited)",
390 | );
391 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
392 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
393 | GCC_WARN_UNDECLARED_SELECTOR = YES;
394 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
395 | GCC_WARN_UNUSED_FUNCTION = YES;
396 | GCC_WARN_UNUSED_VARIABLE = YES;
397 | IPHONEOS_DEPLOYMENT_TARGET = 10.0;
398 | MTL_ENABLE_DEBUG_INFO = YES;
399 | ONLY_ACTIVE_ARCH = YES;
400 | SDKROOT = iphoneos;
401 | TARGETED_DEVICE_FAMILY = "1,2";
402 | VERSIONING_SYSTEM = "apple-generic";
403 | VERSION_INFO_PREFIX = "";
404 | };
405 | name = Debug;
406 | };
407 | 9C1632DF1DA57134001FB468 /* Release */ = {
408 | isa = XCBuildConfiguration;
409 | buildSettings = {
410 | ALWAYS_SEARCH_USER_PATHS = NO;
411 | CLANG_ANALYZER_NONNULL = YES;
412 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
413 | CLANG_CXX_LIBRARY = "libc++";
414 | CLANG_ENABLE_MODULES = YES;
415 | CLANG_ENABLE_OBJC_ARC = YES;
416 | CLANG_WARN_BOOL_CONVERSION = YES;
417 | CLANG_WARN_CONSTANT_CONVERSION = YES;
418 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
419 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
420 | CLANG_WARN_EMPTY_BODY = YES;
421 | CLANG_WARN_ENUM_CONVERSION = YES;
422 | CLANG_WARN_INFINITE_RECURSION = YES;
423 | CLANG_WARN_INT_CONVERSION = YES;
424 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
425 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
426 | CLANG_WARN_SUSPICIOUS_MOVES = YES;
427 | CLANG_WARN_UNREACHABLE_CODE = YES;
428 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
429 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
430 | COPY_PHASE_STRIP = NO;
431 | CURRENT_PROJECT_VERSION = 1;
432 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
433 | ENABLE_NS_ASSERTIONS = NO;
434 | ENABLE_STRICT_OBJC_MSGSEND = YES;
435 | GCC_C_LANGUAGE_STANDARD = gnu99;
436 | GCC_NO_COMMON_BLOCKS = YES;
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_AGGRESSIVE;
441 | GCC_WARN_UNUSED_FUNCTION = YES;
442 | GCC_WARN_UNUSED_VARIABLE = YES;
443 | IPHONEOS_DEPLOYMENT_TARGET = 10.0;
444 | MTL_ENABLE_DEBUG_INFO = NO;
445 | SDKROOT = iphoneos;
446 | TARGETED_DEVICE_FAMILY = "1,2";
447 | VALIDATE_PRODUCT = YES;
448 | VERSIONING_SYSTEM = "apple-generic";
449 | VERSION_INFO_PREFIX = "";
450 | };
451 | name = Release;
452 | };
453 | 9C1632E11DA57134001FB468 /* Debug */ = {
454 | isa = XCBuildConfiguration;
455 | buildSettings = {
456 | CODE_SIGN_IDENTITY = "";
457 | DEFINES_MODULE = YES;
458 | DEVELOPMENT_TEAM = C75GEDTP26;
459 | DYLIB_COMPATIBILITY_VERSION = 1;
460 | DYLIB_CURRENT_VERSION = 1;
461 | DYLIB_INSTALL_NAME_BASE = "@rpath";
462 | INFOPLIST_FILE = "$(SRCROOT)/Framework/Info.plist";
463 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
464 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
465 | MODULEMAP_FILE = Framework/module.modulemap;
466 | PRODUCT_BUNDLE_IDENTIFIER = com.heshammegid.HMSegmentedControl;
467 | PRODUCT_NAME = "$(TARGET_NAME)";
468 | SKIP_INSTALL = YES;
469 | };
470 | name = Debug;
471 | };
472 | 9C1632E21DA57134001FB468 /* Release */ = {
473 | isa = XCBuildConfiguration;
474 | buildSettings = {
475 | CODE_SIGN_IDENTITY = "";
476 | DEFINES_MODULE = YES;
477 | DEVELOPMENT_TEAM = C75GEDTP26;
478 | DYLIB_COMPATIBILITY_VERSION = 1;
479 | DYLIB_CURRENT_VERSION = 1;
480 | DYLIB_INSTALL_NAME_BASE = "@rpath";
481 | INFOPLIST_FILE = "$(SRCROOT)/Framework/Info.plist";
482 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
483 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
484 | MODULEMAP_FILE = Framework/module.modulemap;
485 | PRODUCT_BUNDLE_IDENTIFIER = com.heshammegid.HMSegmentedControl;
486 | PRODUCT_NAME = "$(TARGET_NAME)";
487 | SKIP_INSTALL = YES;
488 | };
489 | name = Release;
490 | };
491 | 9C1633071DA572BA001FB468 /* Debug */ = {
492 | isa = XCBuildConfiguration;
493 | buildSettings = {
494 | DEVELOPMENT_TEAM = C75GEDTP26;
495 | INFOPLIST_FILE = "$(SRCROOT)/HMSegmentedControlExample/HMSegmentedControlExample-Info.plist";
496 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
497 | PRODUCT_BUNDLE_IDENTIFIER = com.heshammegid.HMSegmentedControlExample;
498 | PRODUCT_NAME = "$(TARGET_NAME)";
499 | };
500 | name = Debug;
501 | };
502 | 9C1633081DA572BA001FB468 /* Release */ = {
503 | isa = XCBuildConfiguration;
504 | buildSettings = {
505 | DEVELOPMENT_TEAM = C75GEDTP26;
506 | INFOPLIST_FILE = "$(SRCROOT)/HMSegmentedControlExample/HMSegmentedControlExample-Info.plist";
507 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
508 | PRODUCT_BUNDLE_IDENTIFIER = com.heshammegid.HMSegmentedControlExample;
509 | PRODUCT_NAME = "$(TARGET_NAME)";
510 | };
511 | name = Release;
512 | };
513 | /* End XCBuildConfiguration section */
514 |
515 | /* Begin XCConfigurationList section */
516 | 9C1632D21DA57134001FB468 /* Build configuration list for PBXProject "HMSegmentedControl" */ = {
517 | isa = XCConfigurationList;
518 | buildConfigurations = (
519 | 9C1632DE1DA57134001FB468 /* Debug */,
520 | 9C1632DF1DA57134001FB468 /* Release */,
521 | );
522 | defaultConfigurationIsVisible = 0;
523 | defaultConfigurationName = Release;
524 | };
525 | 9C1632E01DA57134001FB468 /* Build configuration list for PBXNativeTarget "HMSegmentedControl" */ = {
526 | isa = XCConfigurationList;
527 | buildConfigurations = (
528 | 9C1632E11DA57134001FB468 /* Debug */,
529 | 9C1632E21DA57134001FB468 /* Release */,
530 | );
531 | defaultConfigurationIsVisible = 0;
532 | defaultConfigurationName = Release;
533 | };
534 | 9C1633061DA572BA001FB468 /* Build configuration list for PBXNativeTarget "HMSegmentedControlExample" */ = {
535 | isa = XCConfigurationList;
536 | buildConfigurations = (
537 | 9C1633071DA572BA001FB468 /* Debug */,
538 | 9C1633081DA572BA001FB468 /* Release */,
539 | );
540 | defaultConfigurationIsVisible = 0;
541 | defaultConfigurationName = Release;
542 | };
543 | /* End XCConfigurationList section */
544 | };
545 | rootObject = 9C1632CF1DA57134001FB468 /* Project object */;
546 | }
547 |
--------------------------------------------------------------------------------
/HMSegmentedControl/HMSegmentedControl.m:
--------------------------------------------------------------------------------
1 | //
2 | // HMSegmentedControl.m
3 | // HMSegmentedControl
4 | //
5 | // Created by Hesham Abd-Elmegid on 23/12/12.
6 | // Copyright (c) 2012-2015 Hesham Abd-Elmegid. All rights reserved.
7 | //
8 |
9 | #import "HMSegmentedControl.h"
10 | #import
11 | #import
12 |
13 | @interface HMScrollView : UIScrollView
14 | @end
15 |
16 | @interface HMSegmentedControl ()
17 |
18 | @property (nonatomic, strong) CALayer *selectionIndicatorStripLayer;
19 | @property (nonatomic, strong) CALayer *selectionIndicatorBoxLayer;
20 | @property (nonatomic, strong) CALayer *selectionIndicatorArrowLayer;
21 | @property (nonatomic, readwrite) CGFloat segmentWidth;
22 | @property (nonatomic, readwrite) NSArray *segmentWidthsArray;
23 | @property (nonatomic, strong) HMScrollView *scrollView;
24 |
25 | @end
26 |
27 | @implementation HMScrollView
28 |
29 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
30 | if (!self.dragging) {
31 | [self.nextResponder touchesBegan:touches withEvent:event];
32 | } else {
33 | [super touchesBegan:touches withEvent:event];
34 | }
35 | }
36 |
37 | - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
38 | if (!self.dragging) {
39 | [self.nextResponder touchesMoved:touches withEvent:event];
40 | } else{
41 | [super touchesMoved:touches withEvent:event];
42 | }
43 | }
44 |
45 | - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
46 | if (!self.dragging) {
47 | [self.nextResponder touchesEnded:touches withEvent:event];
48 | } else {
49 | [super touchesEnded:touches withEvent:event];
50 | }
51 | }
52 |
53 | @end
54 |
55 | @implementation HMSegmentedControl
56 |
57 | - (id)initWithCoder:(NSCoder *)aDecoder {
58 | self = [super initWithCoder:aDecoder];
59 | if (self) {
60 | [self commonInit];
61 | }
62 | return self;
63 | }
64 |
65 | - (id)initWithFrame:(CGRect)frame {
66 | self = [super initWithFrame:frame];
67 |
68 | if (self) {
69 | [self commonInit];
70 | }
71 |
72 | return self;
73 | }
74 |
75 | - (id)initWithSectionTitles:(NSArray *)sectiontitles {
76 | self = [super initWithFrame:CGRectZero];
77 |
78 | if (self) {
79 | [self commonInit];
80 | self.sectionTitles = sectiontitles;
81 | self.type = HMSegmentedControlTypeText;
82 | }
83 |
84 | return self;
85 | }
86 |
87 | - (id)initWithSectionImages:(NSArray *)sectionImages sectionSelectedImages:(NSArray *)sectionSelectedImages {
88 | self = [super initWithFrame:CGRectZero];
89 |
90 | if (self) {
91 | [self commonInit];
92 | self.sectionImages = sectionImages;
93 | self.sectionSelectedImages = sectionSelectedImages;
94 | self.type = HMSegmentedControlTypeImages;
95 | }
96 |
97 | return self;
98 | }
99 |
100 | - (instancetype)initWithSectionImages:(NSArray *)sectionImages sectionSelectedImages:(NSArray *)sectionSelectedImages titlesForSections:(NSArray *)sectiontitles {
101 | self = [super initWithFrame:CGRectZero];
102 |
103 | if (self) {
104 | [self commonInit];
105 |
106 | if (sectionImages.count != sectiontitles.count) {
107 | [NSException raise:NSRangeException format:@"***%s: Images bounds (%ld) Don't match Title bounds (%ld)", sel_getName(_cmd), (unsigned long)sectionImages.count, (unsigned long)sectiontitles.count];
108 | }
109 |
110 | self.sectionImages = sectionImages;
111 | self.sectionSelectedImages = sectionSelectedImages;
112 | self.sectionTitles = sectiontitles;
113 | self.type = HMSegmentedControlTypeTextImages;
114 | }
115 |
116 | return self;
117 | }
118 |
119 | - (void)awakeFromNib {
120 | [super awakeFromNib];
121 |
122 | self.segmentWidth = 0.0f;
123 | }
124 |
125 | - (void)commonInit {
126 | self.scrollView = [[HMScrollView alloc] init];
127 | self.scrollView.scrollsToTop = NO;
128 | self.scrollView.showsVerticalScrollIndicator = NO;
129 | self.scrollView.showsHorizontalScrollIndicator = NO;
130 | [self addSubview:self.scrollView];
131 |
132 | _backgroundColor = [UIColor whiteColor];
133 | self.opaque = NO;
134 | _selectionIndicatorColor = [UIColor colorWithRed:52.0f/255.0f green:181.0f/255.0f blue:229.0f/255.0f alpha:1.0f];
135 | _selectionIndicatorBoxColor = _selectionIndicatorColor;
136 |
137 | self.selectedSegmentIndex = 0;
138 | self.segmentEdgeInset = UIEdgeInsetsMake(0, 5, 0, 5);
139 | self.selectionIndicatorHeight = 5.0f;
140 | self.selectionIndicatorEdgeInsets = UIEdgeInsetsMake(0.0f, 0.0f, 0.0f, 0.0f);
141 | self.selectionStyle = HMSegmentedControlSelectionStyleTextWidthStripe;
142 | self.selectionIndicatorLocation = HMSegmentedControlSelectionIndicatorLocationUp;
143 | self.segmentWidthStyle = HMSegmentedControlSegmentWidthStyleFixed;
144 | self.userDraggable = YES;
145 | self.touchEnabled = YES;
146 | self.verticalDividerEnabled = NO;
147 | self.type = HMSegmentedControlTypeText;
148 | self.verticalDividerWidth = 1.0f;
149 | _verticalDividerColor = [UIColor blackColor];
150 | self.borderColor = [UIColor blackColor];
151 | self.borderWidth = 1.0f;
152 |
153 | self.shouldAnimateUserSelection = YES;
154 |
155 | self.selectionIndicatorArrowLayer = [CALayer layer];
156 | self.selectionIndicatorStripLayer = [CALayer layer];
157 | self.selectionIndicatorBoxLayer = [CALayer layer];
158 | self.selectionIndicatorBoxLayer.opacity = self.selectionIndicatorBoxOpacity;
159 | self.selectionIndicatorBoxLayer.borderWidth = 1.0f;
160 | self.selectionIndicatorBoxOpacity = 0.2;
161 |
162 | self.contentMode = UIViewContentModeRedraw;
163 | }
164 |
165 | - (void)layoutSubviews {
166 | [super layoutSubviews];
167 |
168 | [self updateSegmentsRects];
169 | }
170 |
171 | - (void)setFrame:(CGRect)frame {
172 | [super setFrame:frame];
173 |
174 | [self updateSegmentsRects];
175 | }
176 |
177 | - (void)setSectionTitles:(NSArray *)sectionTitles {
178 | _sectionTitles = sectionTitles;
179 |
180 | [self setNeedsLayout];
181 | [self setNeedsDisplay];
182 | }
183 |
184 | - (void)setSectionImages:(NSArray *)sectionImages {
185 | _sectionImages = sectionImages;
186 |
187 | [self setNeedsLayout];
188 | [self setNeedsDisplay];
189 | }
190 |
191 | - (void)setSelectionIndicatorLocation:(HMSegmentedControlSelectionIndicatorLocation)selectionIndicatorLocation {
192 | _selectionIndicatorLocation = selectionIndicatorLocation;
193 |
194 | if (selectionIndicatorLocation == HMSegmentedControlSelectionIndicatorLocationNone) {
195 | self.selectionIndicatorHeight = 0.0f;
196 | }
197 | }
198 |
199 | - (void)setSelectionIndicatorBoxOpacity:(CGFloat)selectionIndicatorBoxOpacity {
200 | _selectionIndicatorBoxOpacity = selectionIndicatorBoxOpacity;
201 |
202 | self.selectionIndicatorBoxLayer.opacity = _selectionIndicatorBoxOpacity;
203 | }
204 |
205 | - (void)setSegmentWidthStyle:(HMSegmentedControlSegmentWidthStyle)segmentWidthStyle {
206 | // Force HMSegmentedControlSegmentWidthStyleFixed when type is HMSegmentedControlTypeImages.
207 | if (self.type == HMSegmentedControlTypeImages) {
208 | _segmentWidthStyle = HMSegmentedControlSegmentWidthStyleFixed;
209 | } else {
210 | _segmentWidthStyle = segmentWidthStyle;
211 | }
212 | }
213 |
214 | - (void)setBorderType:(HMSegmentedControlBorderType)borderType {
215 | _borderType = borderType;
216 | [self setNeedsDisplay];
217 | }
218 |
219 | #pragma mark - Drawing
220 |
221 | - (CGSize)measureTitleAtIndex:(NSUInteger)index {
222 | if (index >= self.sectionTitles.count) {
223 | return CGSizeZero;
224 | }
225 |
226 | id title = self.sectionTitles[index];
227 | CGSize size = CGSizeZero;
228 | BOOL selected = (index == self.selectedSegmentIndex) ? YES : NO;
229 | if ([title isKindOfClass:[NSString class]] && !self.titleFormatter) {
230 | NSDictionary *titleAttrs = selected ? [self resultingSelectedTitleTextAttributes] : [self resultingTitleTextAttributes];
231 | size = [(NSString *)title sizeWithAttributes:titleAttrs];
232 | } else if ([title isKindOfClass:[NSString class]] && self.titleFormatter) {
233 | size = [self.titleFormatter(self, title, index, selected) size];
234 | } else if ([title isKindOfClass:[NSAttributedString class]]) {
235 | size = [(NSAttributedString *)title size];
236 | } else {
237 | NSAssert(title == nil, @"Unexpected type of segment title: %@", [title class]);
238 | size = CGSizeZero;
239 | }
240 | return CGRectIntegral((CGRect){CGPointZero, size}).size;
241 | }
242 |
243 | - (NSAttributedString *)attributedTitleAtIndex:(NSUInteger)index {
244 | id title = self.sectionTitles[index];
245 | BOOL selected = (index == self.selectedSegmentIndex) ? YES : NO;
246 |
247 | if ([title isKindOfClass:[NSAttributedString class]]) {
248 | return (NSAttributedString *)title;
249 | } else if (!self.titleFormatter) {
250 | NSDictionary *titleAttrs = selected ? [self resultingSelectedTitleTextAttributes] : [self resultingTitleTextAttributes];
251 |
252 | // the color should be cast to CGColor in order to avoid invalid context on iOS7
253 | UIColor *titleColor = titleAttrs[NSForegroundColorAttributeName];
254 |
255 | if (titleColor) {
256 | NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:titleAttrs];
257 |
258 | dict[NSForegroundColorAttributeName] = (id)titleColor.CGColor;
259 |
260 | titleAttrs = [NSDictionary dictionaryWithDictionary:dict];
261 | }
262 |
263 | return [[NSAttributedString alloc] initWithString:(NSString *)title attributes:titleAttrs];
264 | } else {
265 | return self.titleFormatter(self, title, index, selected);
266 | }
267 | }
268 |
269 | - (void)drawRect:(CGRect)rect {
270 | [self.backgroundColor setFill];
271 | UIRectFill([self bounds]);
272 |
273 | self.selectionIndicatorArrowLayer.backgroundColor = self.selectionIndicatorColor.CGColor;
274 |
275 | self.selectionIndicatorStripLayer.backgroundColor = self.selectionIndicatorColor.CGColor;
276 |
277 | self.selectionIndicatorBoxLayer.backgroundColor = self.selectionIndicatorBoxColor.CGColor;
278 | self.selectionIndicatorBoxLayer.borderColor = self.selectionIndicatorBoxColor.CGColor;
279 |
280 | // Remove all sublayers to avoid drawing images over existing ones
281 | self.scrollView.layer.sublayers = nil;
282 |
283 | CGRect oldRect = rect;
284 |
285 | if (self.type == HMSegmentedControlTypeText) {
286 | [self.sectionTitles enumerateObjectsUsingBlock:^(id titleString, NSUInteger idx, BOOL *stop) {
287 |
288 | CGFloat stringWidth = 0;
289 | CGFloat stringHeight = 0;
290 | CGSize size = [self measureTitleAtIndex:idx];
291 | stringWidth = size.width;
292 | stringHeight = size.height;
293 | CGRect rectDiv = CGRectZero;
294 | CGRect fullRect = CGRectZero;
295 |
296 | // Text inside the CATextLayer will appear blurry unless the rect values are rounded
297 | BOOL locationUp = (self.selectionIndicatorLocation == HMSegmentedControlSelectionIndicatorLocationUp);
298 | BOOL selectionStyleNotBox = (self.selectionStyle != HMSegmentedControlSelectionStyleBox);
299 |
300 | CGFloat y = roundf((CGRectGetHeight(self.frame) - selectionStyleNotBox * self.selectionIndicatorHeight) / 2 - stringHeight / 2 + self.selectionIndicatorHeight * locationUp);
301 | CGRect rect;
302 | if (self.segmentWidthStyle == HMSegmentedControlSegmentWidthStyleFixed) {
303 | rect = CGRectMake((self.segmentWidth * idx) + (self.segmentWidth - stringWidth) / 2, y, stringWidth, stringHeight);
304 | rectDiv = CGRectMake((self.segmentWidth * idx) - (self.verticalDividerWidth / 2), self.selectionIndicatorHeight * 2, self.verticalDividerWidth, self.frame.size.height - (self.selectionIndicatorHeight * 4));
305 | fullRect = CGRectMake(self.segmentWidth * idx, 0, self.segmentWidth, oldRect.size.height);
306 | } else {
307 | // When we are drawing dynamic widths, we need to loop the widths array to calculate the xOffset
308 | CGFloat xOffset = 0;
309 | NSInteger i = 0;
310 | for (NSNumber *width in self.segmentWidthsArray) {
311 | if (idx == i)
312 | break;
313 | xOffset = xOffset + [width floatValue];
314 | i++;
315 | }
316 |
317 | CGFloat widthForIndex = [[self.segmentWidthsArray objectAtIndex:idx] floatValue];
318 | rect = CGRectMake(xOffset, y, widthForIndex, stringHeight);
319 | fullRect = CGRectMake(self.segmentWidth * idx, 0, widthForIndex, oldRect.size.height);
320 | rectDiv = CGRectMake(xOffset - (self.verticalDividerWidth / 2), self.selectionIndicatorHeight * 2, self.verticalDividerWidth, self.frame.size.height - (self.selectionIndicatorHeight * 4));
321 | }
322 |
323 | // Fix rect position/size to avoid blurry labels
324 | rect = CGRectMake(ceilf(rect.origin.x), ceilf(rect.origin.y), ceilf(rect.size.width), ceilf(rect.size.height));
325 |
326 | CATextLayer *titleLayer = [CATextLayer layer];
327 | titleLayer.frame = rect;
328 | titleLayer.alignmentMode = kCAAlignmentCenter;
329 | if ([UIDevice currentDevice].systemVersion.floatValue < 10.0 ) {
330 | titleLayer.truncationMode = kCATruncationEnd;
331 | }
332 | titleLayer.string = [self attributedTitleAtIndex:idx];
333 | titleLayer.contentsScale = [[UIScreen mainScreen] scale];
334 |
335 | [self.scrollView.layer addSublayer:titleLayer];
336 |
337 | // Vertical Divider
338 | if (self.isVerticalDividerEnabled && idx > 0) {
339 | CALayer *verticalDividerLayer = [CALayer layer];
340 | verticalDividerLayer.frame = rectDiv;
341 | verticalDividerLayer.backgroundColor = self.verticalDividerColor.CGColor;
342 |
343 | [self.scrollView.layer addSublayer:verticalDividerLayer];
344 | }
345 |
346 | [self addBackgroundAndBorderLayerWithRect:fullRect];
347 | }];
348 | } else if (self.type == HMSegmentedControlTypeImages) {
349 | [self.sectionImages enumerateObjectsUsingBlock:^(id iconImage, NSUInteger idx, BOOL *stop) {
350 | UIImage *icon = iconImage;
351 | CGFloat imageWidth = icon.size.width;
352 | CGFloat imageHeight = icon.size.height;
353 | CGFloat y = roundf(CGRectGetHeight(self.frame) - self.selectionIndicatorHeight) / 2 - imageHeight / 2 + ((self.selectionIndicatorLocation == HMSegmentedControlSelectionIndicatorLocationUp) ? self.selectionIndicatorHeight : 0);
354 | CGFloat x = self.segmentWidth * idx + (self.segmentWidth - imageWidth)/2.0f;
355 | CGRect rect = CGRectMake(x, y, imageWidth, imageHeight);
356 |
357 | CALayer *imageLayer = [CALayer layer];
358 | imageLayer.frame = rect;
359 |
360 | if (self.selectedSegmentIndex == idx) {
361 | if (self.sectionSelectedImages) {
362 | UIImage *highlightIcon = [self.sectionSelectedImages objectAtIndex:idx];
363 | imageLayer.contents = (id)highlightIcon.CGImage;
364 | } else {
365 | imageLayer.contents = (id)icon.CGImage;
366 | }
367 | } else {
368 | imageLayer.contents = (id)icon.CGImage;
369 | }
370 |
371 | [self.scrollView.layer addSublayer:imageLayer];
372 | // Vertical Divider
373 | if (self.isVerticalDividerEnabled && idx>0) {
374 | CALayer *verticalDividerLayer = [CALayer layer];
375 | verticalDividerLayer.frame = CGRectMake((self.segmentWidth * idx) - (self.verticalDividerWidth / 2), self.selectionIndicatorHeight * 2, self.verticalDividerWidth, self.frame.size.height-(self.selectionIndicatorHeight * 4));
376 | verticalDividerLayer.backgroundColor = self.verticalDividerColor.CGColor;
377 |
378 | [self.scrollView.layer addSublayer:verticalDividerLayer];
379 | }
380 |
381 | [self addBackgroundAndBorderLayerWithRect:rect];
382 | }];
383 | } else if (self.type == HMSegmentedControlTypeTextImages){
384 | [self.sectionImages enumerateObjectsUsingBlock:^(id iconImage, NSUInteger idx, BOOL *stop) {
385 | UIImage *icon = iconImage;
386 | CGFloat imageWidth = icon.size.width;
387 | CGFloat imageHeight = icon.size.height;
388 |
389 | CGFloat stringHeight = [self measureTitleAtIndex:idx].height;
390 | CGFloat yOffset = roundf(((CGRectGetHeight(self.frame) - self.selectionIndicatorHeight) / 2) - (stringHeight / 2));
391 |
392 | CGFloat imageXOffset = self.segmentEdgeInset.left; // Start with edge inset
393 | CGFloat textXOffset = self.segmentEdgeInset.left;
394 | CGFloat textWidth = 0;
395 |
396 | if (self.segmentWidthStyle == HMSegmentedControlSegmentWidthStyleFixed) {
397 | imageXOffset = (self.segmentWidth * idx) + (self.segmentWidth / 2.0f) - (imageWidth / 2.0f);
398 | textXOffset = self.segmentWidth * idx;
399 | textWidth = self.segmentWidth;
400 | } else if (self.segmentWidthStyle == HMSegmentedControlSegmentWidthStyleDynamic) {
401 | // When we are drawing dynamic widths, we need to loop the widths array to calculate the xOffset
402 | CGFloat xOffset = 0;
403 | NSInteger i = 0;
404 |
405 | for (NSNumber *width in self.segmentWidthsArray) {
406 | if (idx == i) {
407 | break;
408 | }
409 |
410 | xOffset = xOffset + [width floatValue];
411 | i++;
412 | }
413 |
414 | imageXOffset = xOffset + ([self.segmentWidthsArray[idx] floatValue] / 2.0f) - (imageWidth / 2.0f); //(self.segmentWidth / 2.0f) - (imageWidth / 2.0f)
415 | textXOffset = xOffset;
416 | textWidth = [self.segmentWidthsArray[idx] floatValue];
417 | }
418 |
419 | CGFloat imageYOffset = roundf((CGRectGetHeight(self.frame) - self.selectionIndicatorHeight) / 2.0f);
420 | CGRect imageRect = CGRectMake(imageXOffset, imageYOffset, imageWidth, imageHeight);
421 | CGRect textRect = CGRectMake(textXOffset, yOffset, textWidth, stringHeight);
422 |
423 | // Fix rect position/size to avoid blurry labels
424 | textRect = CGRectMake(ceilf(textRect.origin.x), ceilf(textRect.origin.y), ceilf(textRect.size.width), ceilf(textRect.size.height));
425 |
426 | CATextLayer *titleLayer = [CATextLayer layer];
427 | titleLayer.frame = textRect;
428 | titleLayer.alignmentMode = kCAAlignmentCenter;
429 | titleLayer.string = [self attributedTitleAtIndex:idx];
430 | if ([UIDevice currentDevice].systemVersion.floatValue < 10.0 ) {
431 | titleLayer.truncationMode = kCATruncationEnd;
432 | }
433 | CALayer *imageLayer = [CALayer layer];
434 | imageLayer.frame = imageRect;
435 |
436 | if (self.selectedSegmentIndex == idx) {
437 | if (self.sectionSelectedImages) {
438 | UIImage *highlightIcon = [self.sectionSelectedImages objectAtIndex:idx];
439 | imageLayer.contents = (id)highlightIcon.CGImage;
440 | } else {
441 | imageLayer.contents = (id)icon.CGImage;
442 | }
443 | } else {
444 | imageLayer.contents = (id)icon.CGImage;
445 | }
446 |
447 | [self.scrollView.layer addSublayer:imageLayer];
448 | titleLayer.contentsScale = [[UIScreen mainScreen] scale];
449 | [self.scrollView.layer addSublayer:titleLayer];
450 |
451 | [self addBackgroundAndBorderLayerWithRect:imageRect];
452 | }];
453 | }
454 |
455 | // Add the selection indicators
456 | if (self.selectedSegmentIndex != HMSegmentedControlNoSegment) {
457 | if (self.selectionStyle == HMSegmentedControlSelectionStyleArrow) {
458 | if (!self.selectionIndicatorArrowLayer.superlayer) {
459 | [self setArrowFrame];
460 | [self.scrollView.layer addSublayer:self.selectionIndicatorArrowLayer];
461 | }
462 | } else {
463 | if (!self.selectionIndicatorStripLayer.superlayer) {
464 | self.selectionIndicatorStripLayer.frame = [self frameForSelectionIndicator];
465 | [self.scrollView.layer addSublayer:self.selectionIndicatorStripLayer];
466 |
467 | if (self.selectionStyle == HMSegmentedControlSelectionStyleBox && !self.selectionIndicatorBoxLayer.superlayer) {
468 | self.selectionIndicatorBoxLayer.frame = [self frameForFillerSelectionIndicator];
469 | [self.scrollView.layer insertSublayer:self.selectionIndicatorBoxLayer atIndex:0];
470 | }
471 | }
472 | }
473 | }
474 | }
475 |
476 | - (void)addBackgroundAndBorderLayerWithRect:(CGRect)fullRect {
477 | // Background layer
478 | CALayer *backgroundLayer = [CALayer layer];
479 | backgroundLayer.frame = fullRect;
480 | [self.layer insertSublayer:backgroundLayer atIndex:0];
481 |
482 | // Border layer
483 | if (self.borderType & HMSegmentedControlBorderTypeTop) {
484 | CALayer *borderLayer = [CALayer layer];
485 | borderLayer.frame = CGRectMake(0, 0, fullRect.size.width, self.borderWidth);
486 | borderLayer.backgroundColor = self.borderColor.CGColor;
487 | [backgroundLayer addSublayer: borderLayer];
488 | }
489 | if (self.borderType & HMSegmentedControlBorderTypeLeft) {
490 | CALayer *borderLayer = [CALayer layer];
491 | borderLayer.frame = CGRectMake(0, 0, self.borderWidth, fullRect.size.height);
492 | borderLayer.backgroundColor = self.borderColor.CGColor;
493 | [backgroundLayer addSublayer: borderLayer];
494 | }
495 | if (self.borderType & HMSegmentedControlBorderTypeBottom) {
496 | CALayer *borderLayer = [CALayer layer];
497 | borderLayer.frame = CGRectMake(0, fullRect.size.height - self.borderWidth, fullRect.size.width, self.borderWidth);
498 | borderLayer.backgroundColor = self.borderColor.CGColor;
499 | [backgroundLayer addSublayer: borderLayer];
500 | }
501 | if (self.borderType & HMSegmentedControlBorderTypeRight) {
502 | CALayer *borderLayer = [CALayer layer];
503 | borderLayer.frame = CGRectMake(fullRect.size.width - self.borderWidth, 0, self.borderWidth, fullRect.size.height);
504 | borderLayer.backgroundColor = self.borderColor.CGColor;
505 | [backgroundLayer addSublayer: borderLayer];
506 | }
507 | }
508 |
509 | - (void)setArrowFrame {
510 | self.selectionIndicatorArrowLayer.frame = [self frameForSelectionIndicator];
511 |
512 | self.selectionIndicatorArrowLayer.mask = nil;
513 |
514 | UIBezierPath *arrowPath = [UIBezierPath bezierPath];
515 |
516 | CGPoint p1 = CGPointZero;
517 | CGPoint p2 = CGPointZero;
518 | CGPoint p3 = CGPointZero;
519 |
520 | if (self.selectionIndicatorLocation == HMSegmentedControlSelectionIndicatorLocationDown) {
521 | p1 = CGPointMake(self.selectionIndicatorArrowLayer.bounds.size.width / 2, 0);
522 | p2 = CGPointMake(0, self.selectionIndicatorArrowLayer.bounds.size.height);
523 | p3 = CGPointMake(self.selectionIndicatorArrowLayer.bounds.size.width, self.selectionIndicatorArrowLayer.bounds.size.height);
524 | }
525 |
526 | if (self.selectionIndicatorLocation == HMSegmentedControlSelectionIndicatorLocationUp) {
527 | p1 = CGPointMake(self.selectionIndicatorArrowLayer.bounds.size.width / 2, self.selectionIndicatorArrowLayer.bounds.size.height);
528 | p2 = CGPointMake(self.selectionIndicatorArrowLayer.bounds.size.width, 0);
529 | p3 = CGPointMake(0, 0);
530 | }
531 |
532 | [arrowPath moveToPoint:p1];
533 | [arrowPath addLineToPoint:p2];
534 | [arrowPath addLineToPoint:p3];
535 | [arrowPath closePath];
536 |
537 | CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
538 | maskLayer.frame = self.selectionIndicatorArrowLayer.bounds;
539 | maskLayer.path = arrowPath.CGPath;
540 | self.selectionIndicatorArrowLayer.mask = maskLayer;
541 | }
542 |
543 | - (CGRect)frameForSelectionIndicator {
544 | CGFloat indicatorYOffset = 0.0f;
545 |
546 | if (self.selectionIndicatorLocation == HMSegmentedControlSelectionIndicatorLocationDown) {
547 | indicatorYOffset = self.bounds.size.height - self.selectionIndicatorHeight + self.selectionIndicatorEdgeInsets.bottom;
548 | }
549 |
550 | if (self.selectionIndicatorLocation == HMSegmentedControlSelectionIndicatorLocationUp) {
551 | indicatorYOffset = self.selectionIndicatorEdgeInsets.top;
552 | }
553 |
554 | CGFloat sectionWidth = 0.0f;
555 |
556 | if (self.type == HMSegmentedControlTypeText) {
557 | CGFloat stringWidth = [self measureTitleAtIndex:self.selectedSegmentIndex].width;
558 | sectionWidth = stringWidth;
559 | } else if (self.type == HMSegmentedControlTypeImages) {
560 | UIImage *sectionImage = [self.sectionImages objectAtIndex:self.selectedSegmentIndex];
561 | CGFloat imageWidth = sectionImage.size.width;
562 | sectionWidth = imageWidth;
563 | } else if (self.type == HMSegmentedControlTypeTextImages) {
564 | CGFloat stringWidth = [self measureTitleAtIndex:self.selectedSegmentIndex].width;
565 | UIImage *sectionImage = [self.sectionImages objectAtIndex:self.selectedSegmentIndex];
566 | CGFloat imageWidth = sectionImage.size.width;
567 | sectionWidth = MAX(stringWidth, imageWidth);
568 | }
569 |
570 | if (self.selectionStyle == HMSegmentedControlSelectionStyleArrow) {
571 | CGFloat widthToEndOfSelectedSegment = (self.segmentWidth * self.selectedSegmentIndex) + self.segmentWidth;
572 | CGFloat widthToStartOfSelectedIndex = (self.segmentWidth * self.selectedSegmentIndex);
573 |
574 | CGFloat x = widthToStartOfSelectedIndex + ((widthToEndOfSelectedSegment - widthToStartOfSelectedIndex) / 2) - (self.selectionIndicatorHeight/2);
575 | return CGRectMake(x - (self.selectionIndicatorHeight / 2), indicatorYOffset, self.selectionIndicatorHeight * 2, self.selectionIndicatorHeight);
576 | } else {
577 | if (self.selectionStyle == HMSegmentedControlSelectionStyleTextWidthStripe &&
578 | sectionWidth <= self.segmentWidth &&
579 | self.segmentWidthStyle != HMSegmentedControlSegmentWidthStyleDynamic) {
580 | CGFloat widthToEndOfSelectedSegment = (self.segmentWidth * self.selectedSegmentIndex) + self.segmentWidth;
581 | CGFloat widthToStartOfSelectedIndex = (self.segmentWidth * self.selectedSegmentIndex);
582 |
583 | CGFloat x = ((widthToEndOfSelectedSegment - widthToStartOfSelectedIndex) / 2) + (widthToStartOfSelectedIndex - sectionWidth / 2);
584 | return CGRectMake(x + self.selectionIndicatorEdgeInsets.left, indicatorYOffset, sectionWidth - self.selectionIndicatorEdgeInsets.right, self.selectionIndicatorHeight);
585 | } else {
586 | if (self.segmentWidthStyle == HMSegmentedControlSegmentWidthStyleDynamic) {
587 | CGFloat selectedSegmentOffset = 0.0f;
588 |
589 | NSInteger i = 0;
590 | for (NSNumber *width in self.segmentWidthsArray) {
591 | if (self.selectedSegmentIndex == i)
592 | break;
593 | selectedSegmentOffset = selectedSegmentOffset + [width floatValue];
594 | i++;
595 | }
596 | return CGRectMake(selectedSegmentOffset + self.selectionIndicatorEdgeInsets.left, indicatorYOffset, [[self.segmentWidthsArray objectAtIndex:self.selectedSegmentIndex] floatValue] - self.selectionIndicatorEdgeInsets.right, self.selectionIndicatorHeight + self.selectionIndicatorEdgeInsets.bottom);
597 | }
598 |
599 | return CGRectMake((self.segmentWidth + self.selectionIndicatorEdgeInsets.left) * self.selectedSegmentIndex, indicatorYOffset, self.segmentWidth - self.selectionIndicatorEdgeInsets.right, self.selectionIndicatorHeight);
600 | }
601 | }
602 | }
603 |
604 | - (CGRect)frameForFillerSelectionIndicator {
605 | if (self.segmentWidthStyle == HMSegmentedControlSegmentWidthStyleDynamic) {
606 | CGFloat selectedSegmentOffset = 0.0f;
607 |
608 | NSInteger i = 0;
609 | for (NSNumber *width in self.segmentWidthsArray) {
610 | if (self.selectedSegmentIndex == i) {
611 | break;
612 | }
613 | selectedSegmentOffset = selectedSegmentOffset + [width floatValue];
614 |
615 | i++;
616 | }
617 |
618 | return CGRectMake(selectedSegmentOffset, 0, [[self.segmentWidthsArray objectAtIndex:self.selectedSegmentIndex] floatValue], CGRectGetHeight(self.frame));
619 | }
620 | return CGRectMake(self.segmentWidth * self.selectedSegmentIndex, 0, self.segmentWidth, CGRectGetHeight(self.frame));
621 | }
622 |
623 | - (void)updateSegmentsRects {
624 | self.scrollView.contentInset = UIEdgeInsetsZero;
625 | self.scrollView.frame = CGRectMake(0, 0, CGRectGetWidth(self.frame), CGRectGetHeight(self.frame));
626 |
627 | if ([self sectionCount] > 0) {
628 | self.segmentWidth = self.frame.size.width / [self sectionCount];
629 | }
630 |
631 | if (self.type == HMSegmentedControlTypeText && self.segmentWidthStyle == HMSegmentedControlSegmentWidthStyleFixed) {
632 | [self.sectionTitles enumerateObjectsUsingBlock:^(id titleString, NSUInteger idx, BOOL *stop) {
633 | CGFloat stringWidth = [self measureTitleAtIndex:idx].width + self.segmentEdgeInset.left + self.segmentEdgeInset.right;
634 | self.segmentWidth = MAX(stringWidth, self.segmentWidth);
635 | }];
636 | } else if (self.type == HMSegmentedControlTypeText && self.segmentWidthStyle == HMSegmentedControlSegmentWidthStyleDynamic) {
637 | NSMutableArray *mutableSegmentWidths = [NSMutableArray array];
638 |
639 | [self.sectionTitles enumerateObjectsUsingBlock:^(id titleString, NSUInteger idx, BOOL *stop) {
640 | CGFloat stringWidth = [self measureTitleAtIndex:idx].width + self.segmentEdgeInset.left + self.segmentEdgeInset.right;
641 | [mutableSegmentWidths addObject:[NSNumber numberWithFloat:stringWidth]];
642 | }];
643 | self.segmentWidthsArray = [mutableSegmentWidths copy];
644 | } else if (self.type == HMSegmentedControlTypeImages) {
645 | for (UIImage *sectionImage in self.sectionImages) {
646 | CGFloat imageWidth = sectionImage.size.width + self.segmentEdgeInset.left + self.segmentEdgeInset.right;
647 | self.segmentWidth = MAX(imageWidth, self.segmentWidth);
648 | }
649 | } else if (self.type == HMSegmentedControlTypeTextImages && self.segmentWidthStyle == HMSegmentedControlSegmentWidthStyleFixed){
650 | //lets just use the title.. we will assume it is wider then images...
651 | [self.sectionTitles enumerateObjectsUsingBlock:^(id titleString, NSUInteger idx, BOOL *stop) {
652 | CGFloat stringWidth = [self measureTitleAtIndex:idx].width + self.segmentEdgeInset.left + self.segmentEdgeInset.right;
653 | self.segmentWidth = MAX(stringWidth, self.segmentWidth);
654 | }];
655 | } else if (self.type == HMSegmentedControlTypeTextImages && self.segmentWidthStyle == HMSegmentedControlSegmentWidthStyleDynamic) {
656 | NSMutableArray *mutableSegmentWidths = [NSMutableArray array];
657 |
658 | int i = 0;
659 | [self.sectionTitles enumerateObjectsUsingBlock:^(id titleString, NSUInteger idx, BOOL *stop) {
660 | CGFloat stringWidth = [self measureTitleAtIndex:idx].width + self.segmentEdgeInset.right;
661 | UIImage *sectionImage = [self.sectionImages objectAtIndex:i];
662 | CGFloat imageWidth = sectionImage.size.width + self.segmentEdgeInset.left;
663 |
664 | CGFloat combinedWidth = MAX(imageWidth, stringWidth);
665 |
666 | [mutableSegmentWidths addObject:[NSNumber numberWithFloat:combinedWidth]];
667 | }];
668 | self.segmentWidthsArray = [mutableSegmentWidths copy];
669 | }
670 |
671 | self.scrollView.scrollEnabled = self.isUserDraggable;
672 | self.scrollView.contentSize = CGSizeMake([self totalSegmentedControlWidth], self.frame.size.height);
673 | }
674 |
675 | - (NSUInteger)sectionCount {
676 | if (self.type == HMSegmentedControlTypeText) {
677 | return self.sectionTitles.count;
678 | } else if (self.type == HMSegmentedControlTypeImages ||
679 | self.type == HMSegmentedControlTypeTextImages) {
680 | return self.sectionImages.count;
681 | }
682 |
683 | return 0;
684 | }
685 |
686 | - (void)willMoveToSuperview:(UIView *)newSuperview {
687 | // Control is being removed
688 | if (newSuperview == nil)
689 | return;
690 |
691 | if (self.sectionTitles || self.sectionImages) {
692 | [self updateSegmentsRects];
693 | }
694 | }
695 |
696 | #pragma mark - Touch
697 |
698 | - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
699 | UITouch *touch = [touches anyObject];
700 | CGPoint touchLocation = [touch locationInView:self];
701 |
702 | CGRect enlargeRect = CGRectMake(self.bounds.origin.x - self.enlargeEdgeInset.left,
703 | self.bounds.origin.y - self.enlargeEdgeInset.top,
704 | self.bounds.size.width + self.enlargeEdgeInset.left + self.enlargeEdgeInset.right,
705 | self.bounds.size.height + self.enlargeEdgeInset.top + self.enlargeEdgeInset.bottom);
706 |
707 | if (CGRectContainsPoint(enlargeRect, touchLocation)) {
708 | NSInteger segment = 0;
709 | if (self.segmentWidthStyle == HMSegmentedControlSegmentWidthStyleFixed) {
710 | segment = (touchLocation.x + self.scrollView.contentOffset.x) / self.segmentWidth;
711 | } else if (self.segmentWidthStyle == HMSegmentedControlSegmentWidthStyleDynamic) {
712 | // To know which segment the user touched, we need to loop over the widths and substract it from the x position.
713 | CGFloat widthLeft = (touchLocation.x + self.scrollView.contentOffset.x);
714 | for (NSNumber *width in self.segmentWidthsArray) {
715 | widthLeft = widthLeft - [width floatValue];
716 |
717 | // When we don't have any width left to substract, we have the segment index.
718 | if (widthLeft <= 0)
719 | break;
720 |
721 | segment++;
722 | }
723 | }
724 |
725 | NSUInteger sectionsCount = 0;
726 |
727 | if (self.type == HMSegmentedControlTypeImages) {
728 | sectionsCount = [self.sectionImages count];
729 | } else if (self.type == HMSegmentedControlTypeTextImages || self.type == HMSegmentedControlTypeText) {
730 | sectionsCount = [self.sectionTitles count];
731 | }
732 |
733 | if (segment != self.selectedSegmentIndex && segment < sectionsCount) {
734 | // Check if we have to do anything with the touch event
735 | if (self.isTouchEnabled)
736 | [self setSelectedSegmentIndex:segment animated:self.shouldAnimateUserSelection notify:YES];
737 | }
738 | }
739 | }
740 |
741 | #pragma mark - Scrolling
742 |
743 | - (CGFloat)totalSegmentedControlWidth {
744 | if (self.type == HMSegmentedControlTypeText && self.segmentWidthStyle == HMSegmentedControlSegmentWidthStyleFixed) {
745 | return self.sectionTitles.count * self.segmentWidth;
746 | } else if (self.segmentWidthStyle == HMSegmentedControlSegmentWidthStyleDynamic) {
747 | return [[self.segmentWidthsArray valueForKeyPath:@"@sum.self"] floatValue];
748 | } else {
749 | return self.sectionImages.count * self.segmentWidth;
750 | }
751 | }
752 |
753 | - (void)scrollToSelectedSegmentIndex:(BOOL)animated {
754 | CGRect rectForSelectedIndex = CGRectZero;
755 | CGFloat selectedSegmentOffset = 0;
756 | if (self.segmentWidthStyle == HMSegmentedControlSegmentWidthStyleFixed) {
757 | rectForSelectedIndex = CGRectMake(self.segmentWidth * self.selectedSegmentIndex,
758 | 0,
759 | self.segmentWidth,
760 | self.frame.size.height);
761 |
762 | selectedSegmentOffset = (CGRectGetWidth(self.frame) / 2) - (self.segmentWidth / 2);
763 | } else {
764 | NSInteger i = 0;
765 | CGFloat offsetter = 0;
766 | for (NSNumber *width in self.segmentWidthsArray) {
767 | if (self.selectedSegmentIndex == i)
768 | break;
769 | offsetter = offsetter + [width floatValue];
770 | i++;
771 | }
772 |
773 | rectForSelectedIndex = CGRectMake(offsetter,
774 | 0,
775 | [[self.segmentWidthsArray objectAtIndex:self.selectedSegmentIndex] floatValue],
776 | self.frame.size.height);
777 |
778 | selectedSegmentOffset = (CGRectGetWidth(self.frame) / 2) - ([[self.segmentWidthsArray objectAtIndex:self.selectedSegmentIndex] floatValue] / 2);
779 | }
780 |
781 |
782 | CGRect rectToScrollTo = rectForSelectedIndex;
783 | rectToScrollTo.origin.x -= selectedSegmentOffset;
784 | rectToScrollTo.size.width += selectedSegmentOffset * 2;
785 | [self.scrollView scrollRectToVisible:rectToScrollTo animated:animated];
786 | }
787 |
788 | #pragma mark - Index Change
789 |
790 | - (void)setSelectedSegmentIndex:(NSInteger)index {
791 | [self setSelectedSegmentIndex:index animated:NO notify:NO];
792 | }
793 |
794 | - (void)setSelectedSegmentIndex:(NSUInteger)index animated:(BOOL)animated {
795 | [self setSelectedSegmentIndex:index animated:animated notify:NO];
796 | }
797 |
798 | - (void)setSelectedSegmentIndex:(NSUInteger)index animated:(BOOL)animated notify:(BOOL)notify {
799 | _selectedSegmentIndex = index;
800 | [self setNeedsDisplay];
801 |
802 | if (index == HMSegmentedControlNoSegment) {
803 | [self.selectionIndicatorArrowLayer removeFromSuperlayer];
804 | [self.selectionIndicatorStripLayer removeFromSuperlayer];
805 | [self.selectionIndicatorBoxLayer removeFromSuperlayer];
806 | } else {
807 | [self scrollToSelectedSegmentIndex:animated];
808 |
809 | if (animated) {
810 | // If the selected segment layer is not added to the super layer, that means no
811 | // index is currently selected, so add the layer then move it to the new
812 | // segment index without animating.
813 | if(self.selectionStyle == HMSegmentedControlSelectionStyleArrow) {
814 | if ([self.selectionIndicatorArrowLayer superlayer] == nil) {
815 | [self.scrollView.layer addSublayer:self.selectionIndicatorArrowLayer];
816 |
817 | [self setSelectedSegmentIndex:index animated:NO notify:YES];
818 | return;
819 | }
820 | }else {
821 | if ([self.selectionIndicatorStripLayer superlayer] == nil) {
822 | [self.scrollView.layer addSublayer:self.selectionIndicatorStripLayer];
823 |
824 | if (self.selectionStyle == HMSegmentedControlSelectionStyleBox && [self.selectionIndicatorBoxLayer superlayer] == nil)
825 | [self.scrollView.layer insertSublayer:self.selectionIndicatorBoxLayer atIndex:0];
826 |
827 | [self setSelectedSegmentIndex:index animated:NO notify:YES];
828 | return;
829 | }
830 | }
831 |
832 | if (notify)
833 | [self notifyForSegmentChangeToIndex:index];
834 |
835 | // Restore CALayer animations
836 | self.selectionIndicatorArrowLayer.actions = nil;
837 | self.selectionIndicatorStripLayer.actions = nil;
838 | self.selectionIndicatorBoxLayer.actions = nil;
839 |
840 | // Animate to new position
841 | [CATransaction begin];
842 | [CATransaction setAnimationDuration:0.15f];
843 | [CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
844 | [self setArrowFrame];
845 | self.selectionIndicatorBoxLayer.frame = [self frameForSelectionIndicator];
846 | self.selectionIndicatorStripLayer.frame = [self frameForSelectionIndicator];
847 | self.selectionIndicatorBoxLayer.frame = [self frameForFillerSelectionIndicator];
848 | [CATransaction commit];
849 | } else {
850 | // Disable CALayer animations
851 | NSMutableDictionary *newActions = [[NSMutableDictionary alloc] initWithObjectsAndKeys:[NSNull null], @"position", [NSNull null], @"bounds", nil];
852 | self.selectionIndicatorArrowLayer.actions = newActions;
853 | [self setArrowFrame];
854 |
855 | self.selectionIndicatorStripLayer.actions = newActions;
856 | self.selectionIndicatorStripLayer.frame = [self frameForSelectionIndicator];
857 |
858 | self.selectionIndicatorBoxLayer.actions = newActions;
859 | self.selectionIndicatorBoxLayer.frame = [self frameForFillerSelectionIndicator];
860 |
861 | if (notify)
862 | [self notifyForSegmentChangeToIndex:index];
863 | }
864 | }
865 | }
866 |
867 | - (void)notifyForSegmentChangeToIndex:(NSInteger)index {
868 | if (self.superview)
869 | [self sendActionsForControlEvents:UIControlEventValueChanged];
870 |
871 | if (self.indexChangeBlock)
872 | self.indexChangeBlock(index);
873 | }
874 |
875 | #pragma mark - Styling Support
876 |
877 | - (NSDictionary *)resultingTitleTextAttributes {
878 | NSDictionary *defaults = @{
879 | NSFontAttributeName : [UIFont systemFontOfSize:19.0f],
880 | NSForegroundColorAttributeName : [UIColor blackColor],
881 | };
882 |
883 | NSMutableDictionary *resultingAttrs = [NSMutableDictionary dictionaryWithDictionary:defaults];
884 |
885 | if (self.titleTextAttributes) {
886 | [resultingAttrs addEntriesFromDictionary:self.titleTextAttributes];
887 | }
888 |
889 | return [resultingAttrs copy];
890 | }
891 |
892 | - (NSDictionary *)resultingSelectedTitleTextAttributes {
893 | NSMutableDictionary *resultingAttrs = [NSMutableDictionary dictionaryWithDictionary:[self resultingTitleTextAttributes]];
894 |
895 | if (self.selectedTitleTextAttributes) {
896 | [resultingAttrs addEntriesFromDictionary:self.selectedTitleTextAttributes];
897 | }
898 |
899 | return [resultingAttrs copy];
900 | }
901 |
902 | @end
903 |
--------------------------------------------------------------------------------