react-native-navigation 7.21.0 → 7.22.0-snapshot.1649
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ReactNativeNavigation.podspec +1 -0
- package/lib/android/app/src/main/java/com/reactnativenavigation/NavigationActivity.java +1 -2
- package/lib/android/app/src/main/java/com/reactnativenavigation/options/BackButton.java +5 -4
- package/lib/android/app/src/main/java/com/reactnativenavigation/options/ElementTransitionOptions.kt +0 -1
- package/lib/android/app/src/main/java/com/reactnativenavigation/options/HardwareBackButtonOptions.kt +2 -5
- package/lib/android/app/src/main/java/com/reactnativenavigation/options/LayoutFactory.java +120 -120
- package/lib/android/app/src/main/java/com/reactnativenavigation/options/ValueAnimationOptions.kt +3 -3
- package/lib/android/app/src/main/java/com/reactnativenavigation/options/interpolators/SpringInterpolator.kt +16 -16
- package/lib/android/app/src/main/java/com/reactnativenavigation/options/parsers/TypefaceLoader.kt +0 -1
- package/lib/android/app/src/main/java/com/reactnativenavigation/react/CommandListenerAdapter.java +0 -2
- package/lib/android/app/src/main/java/com/reactnativenavigation/react/NavigationModule.java +7 -6
- package/lib/android/app/src/main/java/com/reactnativenavigation/react/NavigationPackage.kt +27 -0
- package/lib/android/app/src/main/java/com/reactnativenavigation/react/NavigationReactInitializer.java +50 -50
- package/lib/android/app/src/main/java/com/reactnativenavigation/react/modal/Events.kt +34 -0
- package/lib/android/app/src/main/java/com/reactnativenavigation/react/modal/ModalContentLayout.kt +81 -0
- package/lib/android/app/src/main/java/com/reactnativenavigation/react/modal/ModalFrameLayout.kt +19 -0
- package/lib/android/app/src/main/java/com/reactnativenavigation/react/modal/ModalHostLayout.kt +78 -0
- package/lib/android/app/src/main/java/com/reactnativenavigation/react/modal/ModalLayoutController.kt +51 -0
- package/lib/android/app/src/main/java/com/reactnativenavigation/react/modal/ModalViewManager.kt +131 -0
- package/lib/android/app/src/main/java/com/reactnativenavigation/utils/CoordinatorLayoutUtils.java +1 -1
- package/lib/android/app/src/main/java/com/reactnativenavigation/utils/OutlineProvider.kt +0 -1
- package/lib/android/app/src/main/java/com/reactnativenavigation/utils/ReflectionUtils.java +1 -1
- package/lib/android/app/src/main/java/com/reactnativenavigation/utils/RenderChecker.java +1 -1
- package/lib/android/app/src/main/java/com/reactnativenavigation/utils/StatusBarUtils.java +0 -2
- package/lib/android/app/src/main/java/com/reactnativenavigation/utils/UiUtils.java +5 -6
- package/lib/android/app/src/main/java/com/reactnativenavigation/utils/ViewParent.kt +0 -3
- package/lib/android/app/src/main/java/com/reactnativenavigation/utils/ViewUtils.java +4 -5
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/bottomtabs/BottomTabPresenter.java +6 -8
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/bottomtabs/BottomTabsAnimator.kt +0 -1
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/bottomtabs/BottomTabsController.java +3 -3
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/bottomtabs/attacher/BottomTabsAttacher.java +1 -1
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/bottomtabs/attacher/modes/AttachMode.java +3 -3
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/bottomtabs/attacher/modes/OnSwitchToTab.java +2 -2
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/child/ChildController.java +1 -1
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/child/ChildControllersRegistry.java +5 -5
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/component/ComponentPresenterBase.java +3 -0
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/component/ComponentViewController.java +1 -1
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/modal/ModalPresenter.java +6 -6
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/modal/ModalStack.java +18 -18
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/navigator/Navigator.java +12 -12
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/parent/ParentController.java +22 -22
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/sidemenu/SideMenuController.java +16 -16
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/sidemenu/SideMenuPresenter.java +4 -4
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/FabPresenter.java +8 -8
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/IdStack.java +14 -14
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/StackController.java +29 -29
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/StackControllerBuilder.java +3 -3
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/StackPresenter.java +29 -28
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/topbar/TopBarAnimator.kt +1 -0
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/topbar/TopBarBackgroundViewController.java +0 -1
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/topbar/TopBarController.kt +1 -1
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/topbar/button/BackButtonHelper.java +2 -2
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/topbar/button/ButtonPresenter.kt +1 -1
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/topbar/button/ButtonSpan.kt +0 -1
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/topbar/button/IconResolver.java +0 -1
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/toptabs/TopTabsAdapter.java +5 -4
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/toptabs/TopTabsController.java +8 -8
- package/lib/android/app/src/main/java/com/reactnativenavigation/views/bottomtabs/BottomTabsContainer.kt +1 -4
- package/lib/android/app/src/main/java/com/reactnativenavigation/views/bottomtabs/BottomTabsLayout.java +0 -1
- package/lib/android/app/src/main/java/com/reactnativenavigation/views/element/animators/PropertyAnimatorCreator.kt +2 -0
- package/lib/android/app/src/main/java/com/reactnativenavigation/views/element/animators/ReactImageBoundsAnimator.kt +0 -1
- package/lib/android/app/src/main/java/com/reactnativenavigation/views/element/animators/ReactImageMatrixAnimator.kt +2 -2
- package/lib/android/app/src/main/java/com/reactnativenavigation/views/element/animators/ReactViewRotationAnimator.kt +0 -5
- package/lib/android/app/src/main/java/com/reactnativenavigation/views/toptabs/TopTabsLayoutCreator.java +2 -2
- package/lib/android/app/src/main/java/com/reactnativenavigation/views/toptabs/TopTabsViewPager.java +6 -6
- package/lib/android/app/src/reactNative63/java/com/reactnativenavigation/react/NavigationReactNativeHost.java +0 -1
- package/lib/android/app/src/test/java/com/reactnativenavigation/BaseTest.java +23 -28
- package/lib/android/app/src/test/java/com/reactnativenavigation/TestUtils.java +4 -2
- package/lib/android/app/src/test/java/com/reactnativenavigation/mocks/TestComponentLayout.java +3 -1
- package/lib/android/app/src/test/java/com/reactnativenavigation/options/OptionsTest.java +9 -1
- package/lib/android/app/src/test/java/com/reactnativenavigation/options/TopBarButtonsTest.kt +70 -0
- package/lib/android/app/src/test/java/com/reactnativenavigation/options/parsers/ColorParseTest.java +0 -3
- package/lib/android/app/src/test/java/com/reactnativenavigation/presentation/RenderCheckerTest.java +6 -6
- package/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/bottomtabs/BottomTabPresenterTest.java +3 -4
- package/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/bottomtabs/BottomTabsAttacherTest.java +1 -1
- package/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/bottomtabs/BottomTabsControllerTest.java +13 -15
- package/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/bottomtabs/attacher/modes/AttachModeTest.java +5 -5
- package/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/child/ChildControllerTest.java +2 -2
- package/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/child/ChildControllersRegistryTest.java +2 -2
- package/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/modal/ModalPresenterTest.java +4 -4
- package/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/modal/ModalStackTest.java +10 -10
- package/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/navigator/NavigatorTest.java +25 -26
- package/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/navigator/RootPresenterTest.kt +2 -2
- package/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/parent/ParentControllerTest.java +15 -15
- package/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/sidemenu/SideMenuControllerTest.java +11 -11
- package/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/stack/BackButtonHelperTest.java +2 -2
- package/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/stack/StackAnimatorTest.kt +0 -4
- package/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/stack/StackControllerTest.kt +15 -15
- package/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/stack/StackPresenterTest.kt +17 -17
- package/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/stack/TopBarControllerTest.kt +3 -3
- package/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/toptabs/TopTabsViewControllerTest.java +9 -9
- package/lib/dist/Navigation.d.ts +1 -1
- package/lib/dist/Navigation.js +2 -2
- package/lib/dist/NavigationDelegate.d.ts +1 -1
- package/lib/dist/NavigationDelegate.js +2 -2
- package/lib/dist/adapters/TouchablePreview.js +1 -0
- package/lib/dist/commands/Commands.d.ts +1 -1
- package/lib/dist/commands/Commands.js +2 -2
- package/lib/dist/commands/OptionsProcessor.js +12 -6
- package/lib/dist/components/ComponentWrapper.d.ts +1 -1
- package/lib/dist/components/ComponentWrapper.js +2 -2
- package/lib/dist/components/Modal.d.ts +20 -0
- package/lib/dist/components/Modal.js +93 -0
- package/lib/dist/components/Store.d.ts +1 -1
- package/lib/dist/components/Store.js +2 -2
- package/lib/dist/index.d.ts +1 -0
- package/lib/dist/index.js +1 -0
- package/lib/dist/interfaces/Options.d.ts +15 -0
- package/lib/ios/BottomTabPresenter.h +4 -1
- package/lib/ios/BottomTabPresenter.m +11 -3
- package/lib/ios/BottomTabPresenterCreator.m +11 -4
- package/lib/ios/BottomTabsAppearancePresenter.m +29 -4
- package/lib/ios/RNNBackButtonOptions.h +1 -0
- package/lib/ios/RNNBackButtonOptions.m +4 -1
- package/lib/ios/RNNBottomTabOptions.h +2 -0
- package/lib/ios/RNNBottomTabOptions.m +7 -1
- package/lib/ios/RNNBottomTabsController.m +5 -0
- package/lib/ios/RNNDotIndicatorPresenter.m +12 -6
- package/lib/ios/RNNSegmentedControl.h +1 -1
- package/lib/ios/RNNTabBarItemCreator.h +4 -4
- package/lib/ios/RNNTabBarItemCreator.m +17 -7
- package/lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj +8 -24
- package/lib/ios/TabBarItemAppearanceCreator.m +3 -3
- package/lib/ios/TabBarItemIOS15Creator.h +6 -0
- package/lib/ios/TabBarItemIOS15Creator.m +37 -0
- package/lib/ios/TopBarPresenter.m +13 -3
- package/lib/ios/UIViewController+RNNOptions.m +7 -0
- package/lib/src/Navigation.ts +2 -2
- package/lib/src/NavigationDelegate.ts +2 -2
- package/lib/src/adapters/TouchablePreview.tsx +1 -1
- package/lib/src/commands/Commands.ts +2 -2
- package/lib/src/commands/OptionsProcessor.ts +12 -7
- package/lib/src/components/ComponentWrapper.tsx +11 -8
- package/lib/src/components/Modal.tsx +109 -0
- package/lib/src/components/Store.ts +2 -2
- package/lib/src/index.ts +1 -1
- package/lib/src/interfaces/Options.ts +15 -0
- package/package.json +1 -1
- package/lib/android/app/src/main/java/com/reactnativenavigation/react/NavigationPackage.java +0 -41
- package/lib/ios/BottomTabAppearancePresenter.h +0 -6
- package/lib/ios/BottomTabAppearancePresenter.m +0 -12
- package/lib/ios/HMSegmentedControl.h +0 -287
- package/lib/ios/HMSegmentedControl.m +0 -1063
|
@@ -1,1063 +0,0 @@
|
|
|
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 <QuartzCore/QuartzCore.h>
|
|
11
|
-
#import <math.h>
|
|
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<NSNumber *> *segmentWidthsArray;
|
|
23
|
-
@property(nonatomic, strong) HMScrollView *scrollView;
|
|
24
|
-
|
|
25
|
-
@end
|
|
26
|
-
|
|
27
|
-
@implementation HMScrollView
|
|
28
|
-
|
|
29
|
-
- (void)touchesBegan:(NSSet<UITouch *> *)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<UITouch *> *)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<UITouch *> *)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<NSString *> *)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<UIImage *> *)sectionImages
|
|
88
|
-
sectionSelectedImages:(NSArray<UIImage *> *)sectionSelectedImages {
|
|
89
|
-
self = [super initWithFrame:CGRectZero];
|
|
90
|
-
|
|
91
|
-
if (self) {
|
|
92
|
-
[self commonInit];
|
|
93
|
-
self.sectionImages = sectionImages;
|
|
94
|
-
self.sectionSelectedImages = sectionSelectedImages;
|
|
95
|
-
self.type = HMSegmentedControlTypeImages;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return self;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
- (instancetype)initWithSectionImages:(NSArray<UIImage *> *)sectionImages
|
|
102
|
-
sectionSelectedImages:(NSArray<UIImage *> *)sectionSelectedImages
|
|
103
|
-
titlesForSections:(NSArray<NSString *> *)sectiontitles {
|
|
104
|
-
self = [super initWithFrame:CGRectZero];
|
|
105
|
-
|
|
106
|
-
if (self) {
|
|
107
|
-
[self commonInit];
|
|
108
|
-
|
|
109
|
-
if (sectionImages.count != sectiontitles.count) {
|
|
110
|
-
[NSException raise:NSRangeException
|
|
111
|
-
format:@"***%s: Images bounds (%ld) Don't match Title bounds "
|
|
112
|
-
@"(%ld)",
|
|
113
|
-
sel_getName(_cmd), (unsigned long)sectionImages.count,
|
|
114
|
-
(unsigned long)sectiontitles.count];
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
self.sectionImages = sectionImages;
|
|
118
|
-
self.sectionSelectedImages = sectionSelectedImages;
|
|
119
|
-
self.sectionTitles = sectiontitles;
|
|
120
|
-
self.type = HMSegmentedControlTypeTextImages;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
return self;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
- (void)awakeFromNib {
|
|
127
|
-
[super awakeFromNib];
|
|
128
|
-
|
|
129
|
-
self.segmentWidth = 0.0f;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
- (void)commonInit {
|
|
133
|
-
self.scrollView = [[HMScrollView alloc] init];
|
|
134
|
-
self.scrollView.scrollsToTop = NO;
|
|
135
|
-
self.scrollView.showsVerticalScrollIndicator = NO;
|
|
136
|
-
self.scrollView.showsHorizontalScrollIndicator = NO;
|
|
137
|
-
[self addSubview:self.scrollView];
|
|
138
|
-
|
|
139
|
-
_backgroundColor = [UIColor whiteColor];
|
|
140
|
-
self.opaque = NO;
|
|
141
|
-
_selectionIndicatorColor = [UIColor colorWithRed:52.0f / 255.0f
|
|
142
|
-
green:181.0f / 255.0f
|
|
143
|
-
blue:229.0f / 255.0f
|
|
144
|
-
alpha:1.0f];
|
|
145
|
-
_selectionIndicatorBoxColor = _selectionIndicatorColor;
|
|
146
|
-
|
|
147
|
-
self.selectedSegmentIndex = 0;
|
|
148
|
-
self.segmentEdgeInset = UIEdgeInsetsMake(0, 5, 0, 5);
|
|
149
|
-
self.selectionIndicatorHeight = 5.0f;
|
|
150
|
-
self.selectionIndicatorEdgeInsets = UIEdgeInsetsMake(0.0f, 0.0f, 0.0f, 0.0f);
|
|
151
|
-
self.selectionStyle = HMSegmentedControlSelectionStyleTextWidthStripe;
|
|
152
|
-
self.selectionIndicatorLocation = HMSegmentedControlSelectionIndicatorLocationUp;
|
|
153
|
-
self.segmentWidthStyle = HMSegmentedControlSegmentWidthStyleFixed;
|
|
154
|
-
self.userDraggable = YES;
|
|
155
|
-
self.touchEnabled = YES;
|
|
156
|
-
self.verticalDividerEnabled = NO;
|
|
157
|
-
self.type = HMSegmentedControlTypeText;
|
|
158
|
-
self.verticalDividerWidth = 1.0f;
|
|
159
|
-
_verticalDividerColor = [UIColor blackColor];
|
|
160
|
-
self.borderColor = [UIColor blackColor];
|
|
161
|
-
self.borderWidth = 1.0f;
|
|
162
|
-
|
|
163
|
-
self.shouldAnimateUserSelection = YES;
|
|
164
|
-
|
|
165
|
-
self.selectionIndicatorArrowLayer = [CALayer layer];
|
|
166
|
-
self.selectionIndicatorStripLayer = [CALayer layer];
|
|
167
|
-
self.selectionIndicatorBoxLayer = [CALayer layer];
|
|
168
|
-
self.selectionIndicatorBoxLayer.opacity = self.selectionIndicatorBoxOpacity;
|
|
169
|
-
self.selectionIndicatorBoxLayer.borderWidth = 1.0f;
|
|
170
|
-
self.selectionIndicatorBoxOpacity = 0.2;
|
|
171
|
-
|
|
172
|
-
self.contentMode = UIViewContentModeRedraw;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
- (void)layoutSubviews {
|
|
176
|
-
[super layoutSubviews];
|
|
177
|
-
|
|
178
|
-
[self updateSegmentsRects];
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
- (void)setFrame:(CGRect)frame {
|
|
182
|
-
[super setFrame:frame];
|
|
183
|
-
|
|
184
|
-
[self updateSegmentsRects];
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
- (void)setSectionTitles:(NSArray<NSString *> *)sectionTitles {
|
|
188
|
-
_sectionTitles = sectionTitles;
|
|
189
|
-
|
|
190
|
-
[self setNeedsLayout];
|
|
191
|
-
[self setNeedsDisplay];
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
- (void)setSectionImages:(NSArray<UIImage *> *)sectionImages {
|
|
195
|
-
_sectionImages = sectionImages;
|
|
196
|
-
|
|
197
|
-
[self setNeedsLayout];
|
|
198
|
-
[self setNeedsDisplay];
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
- (void)setSelectionIndicatorLocation:
|
|
202
|
-
(HMSegmentedControlSelectionIndicatorLocation)selectionIndicatorLocation {
|
|
203
|
-
_selectionIndicatorLocation = selectionIndicatorLocation;
|
|
204
|
-
|
|
205
|
-
if (selectionIndicatorLocation == HMSegmentedControlSelectionIndicatorLocationNone) {
|
|
206
|
-
self.selectionIndicatorHeight = 0.0f;
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
- (void)setSelectionIndicatorBoxOpacity:(CGFloat)selectionIndicatorBoxOpacity {
|
|
211
|
-
_selectionIndicatorBoxOpacity = selectionIndicatorBoxOpacity;
|
|
212
|
-
|
|
213
|
-
self.selectionIndicatorBoxLayer.opacity = _selectionIndicatorBoxOpacity;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
- (void)setSegmentWidthStyle:(HMSegmentedControlSegmentWidthStyle)segmentWidthStyle {
|
|
217
|
-
// Force HMSegmentedControlSegmentWidthStyleFixed when type is
|
|
218
|
-
// HMSegmentedControlTypeImages.
|
|
219
|
-
if (self.type == HMSegmentedControlTypeImages) {
|
|
220
|
-
_segmentWidthStyle = HMSegmentedControlSegmentWidthStyleFixed;
|
|
221
|
-
} else {
|
|
222
|
-
_segmentWidthStyle = segmentWidthStyle;
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
- (void)setBorderType:(HMSegmentedControlBorderType)borderType {
|
|
227
|
-
_borderType = borderType;
|
|
228
|
-
[self setNeedsDisplay];
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
#pragma mark - Drawing
|
|
232
|
-
|
|
233
|
-
- (CGSize)measureTitleAtIndex:(NSUInteger)index {
|
|
234
|
-
if (index >= self.sectionTitles.count) {
|
|
235
|
-
return CGSizeZero;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
id title = self.sectionTitles[index];
|
|
239
|
-
CGSize size = CGSizeZero;
|
|
240
|
-
BOOL selected = (index == self.selectedSegmentIndex) ? YES : NO;
|
|
241
|
-
if ([title isKindOfClass:[NSString class]] && !self.titleFormatter) {
|
|
242
|
-
NSDictionary *titleAttrs = selected ? [self resultingSelectedTitleTextAttributes]
|
|
243
|
-
: [self resultingTitleTextAttributes];
|
|
244
|
-
size = [(NSString *)title sizeWithAttributes:titleAttrs];
|
|
245
|
-
} else if ([title isKindOfClass:[NSString class]] && self.titleFormatter) {
|
|
246
|
-
size = [self.titleFormatter(self, title, index, selected) size];
|
|
247
|
-
} else if ([title isKindOfClass:[NSAttributedString class]]) {
|
|
248
|
-
size = [(NSAttributedString *)title size];
|
|
249
|
-
} else {
|
|
250
|
-
NSAssert(title == nil, @"Unexpected type of segment title: %@", [title class]);
|
|
251
|
-
size = CGSizeZero;
|
|
252
|
-
}
|
|
253
|
-
return CGRectIntegral((CGRect){CGPointZero, size}).size;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
- (NSAttributedString *)attributedTitleAtIndex:(NSUInteger)index {
|
|
257
|
-
id title = self.sectionTitles[index];
|
|
258
|
-
BOOL selected = (index == self.selectedSegmentIndex) ? YES : NO;
|
|
259
|
-
|
|
260
|
-
if ([title isKindOfClass:[NSAttributedString class]]) {
|
|
261
|
-
return (NSAttributedString *)title;
|
|
262
|
-
} else if (!self.titleFormatter) {
|
|
263
|
-
NSDictionary *titleAttrs = selected ? [self resultingSelectedTitleTextAttributes]
|
|
264
|
-
: [self resultingTitleTextAttributes];
|
|
265
|
-
|
|
266
|
-
// the color should be cast to CGColor in order to avoid invalid context
|
|
267
|
-
// on iOS7
|
|
268
|
-
UIColor *titleColor = titleAttrs[NSForegroundColorAttributeName];
|
|
269
|
-
|
|
270
|
-
if (titleColor) {
|
|
271
|
-
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:titleAttrs];
|
|
272
|
-
|
|
273
|
-
dict[NSForegroundColorAttributeName] = (id)titleColor.CGColor;
|
|
274
|
-
|
|
275
|
-
titleAttrs = [NSDictionary dictionaryWithDictionary:dict];
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
return [[NSAttributedString alloc] initWithString:(NSString *)title attributes:titleAttrs];
|
|
279
|
-
} else {
|
|
280
|
-
return self.titleFormatter(self, title, index, selected);
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
- (void)drawRect:(CGRect)rect {
|
|
285
|
-
[self.backgroundColor setFill];
|
|
286
|
-
UIRectFill([self bounds]);
|
|
287
|
-
|
|
288
|
-
self.selectionIndicatorArrowLayer.backgroundColor = self.selectionIndicatorColor.CGColor;
|
|
289
|
-
|
|
290
|
-
self.selectionIndicatorStripLayer.backgroundColor = self.selectionIndicatorColor.CGColor;
|
|
291
|
-
|
|
292
|
-
self.selectionIndicatorBoxLayer.backgroundColor = self.selectionIndicatorBoxColor.CGColor;
|
|
293
|
-
self.selectionIndicatorBoxLayer.borderColor = self.selectionIndicatorBoxColor.CGColor;
|
|
294
|
-
|
|
295
|
-
// Remove all sublayers to avoid drawing images over existing ones
|
|
296
|
-
self.scrollView.layer.sublayers = nil;
|
|
297
|
-
|
|
298
|
-
CGRect oldRect = rect;
|
|
299
|
-
|
|
300
|
-
if (self.type == HMSegmentedControlTypeText) {
|
|
301
|
-
[self.sectionTitles enumerateObjectsUsingBlock:^(id titleString, NSUInteger idx,
|
|
302
|
-
BOOL *stop) {
|
|
303
|
-
CGFloat stringWidth = 0;
|
|
304
|
-
CGFloat stringHeight = 0;
|
|
305
|
-
CGSize size = [self measureTitleAtIndex:idx];
|
|
306
|
-
stringWidth = size.width;
|
|
307
|
-
stringHeight = size.height;
|
|
308
|
-
CGRect rectDiv = CGRectZero;
|
|
309
|
-
CGRect fullRect = CGRectZero;
|
|
310
|
-
|
|
311
|
-
// Text inside the CATextLayer will appear blurry unless the rect
|
|
312
|
-
// values are rounded
|
|
313
|
-
BOOL locationUp =
|
|
314
|
-
(self.selectionIndicatorLocation == HMSegmentedControlSelectionIndicatorLocationUp);
|
|
315
|
-
BOOL selectionStyleNotBox = (self.selectionStyle != HMSegmentedControlSelectionStyleBox);
|
|
316
|
-
|
|
317
|
-
CGFloat y = roundf(
|
|
318
|
-
(CGRectGetHeight(self.frame) - selectionStyleNotBox * self.selectionIndicatorHeight) /
|
|
319
|
-
2 -
|
|
320
|
-
stringHeight / 2 + self.selectionIndicatorHeight * locationUp);
|
|
321
|
-
CGRect rect;
|
|
322
|
-
if (self.segmentWidthStyle == HMSegmentedControlSegmentWidthStyleFixed) {
|
|
323
|
-
rect = CGRectMake((self.segmentWidth * idx) + (self.segmentWidth - stringWidth) / 2,
|
|
324
|
-
y, stringWidth, stringHeight);
|
|
325
|
-
rectDiv = CGRectMake((self.segmentWidth * idx) - (self.verticalDividerWidth / 2),
|
|
326
|
-
self.selectionIndicatorHeight * 2, self.verticalDividerWidth,
|
|
327
|
-
self.frame.size.height - (self.selectionIndicatorHeight * 4));
|
|
328
|
-
fullRect =
|
|
329
|
-
CGRectMake(self.segmentWidth * idx, 0, self.segmentWidth, oldRect.size.height);
|
|
330
|
-
} else {
|
|
331
|
-
// When we are drawing dynamic widths, we need to loop the widths
|
|
332
|
-
// array to calculate the xOffset
|
|
333
|
-
CGFloat xOffset = 0;
|
|
334
|
-
NSInteger i = 0;
|
|
335
|
-
for (NSNumber *width in self.segmentWidthsArray) {
|
|
336
|
-
if (idx == i)
|
|
337
|
-
break;
|
|
338
|
-
xOffset = xOffset + [width floatValue];
|
|
339
|
-
i++;
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
CGFloat widthForIndex = [[self.segmentWidthsArray objectAtIndex:idx] floatValue];
|
|
343
|
-
rect = CGRectMake(xOffset, y, widthForIndex, stringHeight);
|
|
344
|
-
fullRect = CGRectMake(self.segmentWidth * idx, 0, widthForIndex, oldRect.size.height);
|
|
345
|
-
rectDiv = CGRectMake(xOffset - (self.verticalDividerWidth / 2),
|
|
346
|
-
self.selectionIndicatorHeight * 2, self.verticalDividerWidth,
|
|
347
|
-
self.frame.size.height - (self.selectionIndicatorHeight * 4));
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
// Fix rect position/size to avoid blurry labels
|
|
351
|
-
rect = CGRectMake(ceilf(rect.origin.x), ceilf(rect.origin.y), ceilf(rect.size.width),
|
|
352
|
-
ceilf(rect.size.height));
|
|
353
|
-
|
|
354
|
-
CATextLayer *titleLayer = [CATextLayer layer];
|
|
355
|
-
titleLayer.frame = rect;
|
|
356
|
-
titleLayer.alignmentMode = kCAAlignmentCenter;
|
|
357
|
-
if ([UIDevice currentDevice].systemVersion.floatValue < 10.0) {
|
|
358
|
-
titleLayer.truncationMode = kCATruncationEnd;
|
|
359
|
-
}
|
|
360
|
-
titleLayer.string = [self attributedTitleAtIndex:idx];
|
|
361
|
-
titleLayer.contentsScale = [[UIScreen mainScreen] scale];
|
|
362
|
-
|
|
363
|
-
[self.scrollView.layer addSublayer:titleLayer];
|
|
364
|
-
|
|
365
|
-
// Vertical Divider
|
|
366
|
-
if (self.isVerticalDividerEnabled && idx > 0) {
|
|
367
|
-
CALayer *verticalDividerLayer = [CALayer layer];
|
|
368
|
-
verticalDividerLayer.frame = rectDiv;
|
|
369
|
-
verticalDividerLayer.backgroundColor = self.verticalDividerColor.CGColor;
|
|
370
|
-
|
|
371
|
-
[self.scrollView.layer addSublayer:verticalDividerLayer];
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
[self addBackgroundAndBorderLayerWithRect:fullRect];
|
|
375
|
-
}];
|
|
376
|
-
} else if (self.type == HMSegmentedControlTypeImages) {
|
|
377
|
-
[self.sectionImages enumerateObjectsUsingBlock:^(id iconImage, NSUInteger idx, BOOL *stop) {
|
|
378
|
-
UIImage *icon = iconImage;
|
|
379
|
-
CGFloat imageWidth = icon.size.width;
|
|
380
|
-
CGFloat imageHeight = icon.size.height;
|
|
381
|
-
CGFloat y =
|
|
382
|
-
roundf(CGRectGetHeight(self.frame) - self.selectionIndicatorHeight) / 2 -
|
|
383
|
-
imageHeight / 2 +
|
|
384
|
-
((self.selectionIndicatorLocation == HMSegmentedControlSelectionIndicatorLocationUp)
|
|
385
|
-
? self.selectionIndicatorHeight
|
|
386
|
-
: 0);
|
|
387
|
-
CGFloat x = self.segmentWidth * idx + (self.segmentWidth - imageWidth) / 2.0f;
|
|
388
|
-
CGRect rect = CGRectMake(x, y, imageWidth, imageHeight);
|
|
389
|
-
|
|
390
|
-
CALayer *imageLayer = [CALayer layer];
|
|
391
|
-
imageLayer.frame = rect;
|
|
392
|
-
|
|
393
|
-
if (self.selectedSegmentIndex == idx) {
|
|
394
|
-
if (self.sectionSelectedImages) {
|
|
395
|
-
UIImage *highlightIcon = [self.sectionSelectedImages objectAtIndex:idx];
|
|
396
|
-
imageLayer.contents = (id)highlightIcon.CGImage;
|
|
397
|
-
} else {
|
|
398
|
-
imageLayer.contents = (id)icon.CGImage;
|
|
399
|
-
}
|
|
400
|
-
} else {
|
|
401
|
-
imageLayer.contents = (id)icon.CGImage;
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
[self.scrollView.layer addSublayer:imageLayer];
|
|
405
|
-
// Vertical Divider
|
|
406
|
-
if (self.isVerticalDividerEnabled && idx > 0) {
|
|
407
|
-
CALayer *verticalDividerLayer = [CALayer layer];
|
|
408
|
-
verticalDividerLayer.frame =
|
|
409
|
-
CGRectMake((self.segmentWidth * idx) - (self.verticalDividerWidth / 2),
|
|
410
|
-
self.selectionIndicatorHeight * 2, self.verticalDividerWidth,
|
|
411
|
-
self.frame.size.height - (self.selectionIndicatorHeight * 4));
|
|
412
|
-
verticalDividerLayer.backgroundColor = self.verticalDividerColor.CGColor;
|
|
413
|
-
|
|
414
|
-
[self.scrollView.layer addSublayer:verticalDividerLayer];
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
[self addBackgroundAndBorderLayerWithRect:rect];
|
|
418
|
-
}];
|
|
419
|
-
} else if (self.type == HMSegmentedControlTypeTextImages) {
|
|
420
|
-
[self.sectionImages enumerateObjectsUsingBlock:^(id iconImage, NSUInteger idx, BOOL *stop) {
|
|
421
|
-
UIImage *icon = iconImage;
|
|
422
|
-
CGFloat imageWidth = icon.size.width;
|
|
423
|
-
CGFloat imageHeight = icon.size.height;
|
|
424
|
-
|
|
425
|
-
CGSize stringSize = [self measureTitleAtIndex:idx];
|
|
426
|
-
CGFloat stringHeight = stringSize.height;
|
|
427
|
-
CGFloat stringWidth = stringSize.width;
|
|
428
|
-
|
|
429
|
-
CGFloat imageXOffset = self.segmentWidth * idx; // Start with edge inset
|
|
430
|
-
CGFloat textXOffset = self.segmentWidth * idx;
|
|
431
|
-
CGFloat imageYOffset =
|
|
432
|
-
ceilf((self.frame.size.height - imageHeight) / 2.0); // Start in center
|
|
433
|
-
CGFloat textYOffset = ceilf((self.frame.size.height - stringHeight) / 2.0);
|
|
434
|
-
|
|
435
|
-
if (self.segmentWidthStyle == HMSegmentedControlSegmentWidthStyleFixed) {
|
|
436
|
-
BOOL isImageInLineWidthText =
|
|
437
|
-
self.imagePosition == HMSegmentedControlImagePositionLeftOfText ||
|
|
438
|
-
self.imagePosition == HMSegmentedControlImagePositionRightOfText;
|
|
439
|
-
if (isImageInLineWidthText) {
|
|
440
|
-
CGFloat whitespace =
|
|
441
|
-
self.segmentWidth - stringSize.width - imageWidth - self.textImageSpacing;
|
|
442
|
-
if (self.imagePosition == HMSegmentedControlImagePositionLeftOfText) {
|
|
443
|
-
imageXOffset += whitespace / 2.0;
|
|
444
|
-
textXOffset = imageXOffset + imageWidth + self.textImageSpacing;
|
|
445
|
-
} else {
|
|
446
|
-
textXOffset += whitespace / 2.0;
|
|
447
|
-
imageXOffset = textXOffset + stringWidth + self.textImageSpacing;
|
|
448
|
-
}
|
|
449
|
-
} else {
|
|
450
|
-
imageXOffset = self.segmentWidth * idx +
|
|
451
|
-
(self.segmentWidth - imageWidth) / 2.0f; // Start with edge inset
|
|
452
|
-
textXOffset = self.segmentWidth * idx + (self.segmentWidth - stringWidth) / 2.0f;
|
|
453
|
-
|
|
454
|
-
CGFloat whitespace = CGRectGetHeight(self.frame) - imageHeight - stringHeight -
|
|
455
|
-
self.textImageSpacing;
|
|
456
|
-
if (self.imagePosition == HMSegmentedControlImagePositionAboveText) {
|
|
457
|
-
imageYOffset = ceilf(whitespace / 2.0);
|
|
458
|
-
textYOffset = imageYOffset + imageHeight + self.textImageSpacing;
|
|
459
|
-
} else if (self.imagePosition == HMSegmentedControlImagePositionBelowText) {
|
|
460
|
-
textYOffset = ceilf(whitespace / 2.0);
|
|
461
|
-
imageYOffset = textYOffset + stringHeight + self.textImageSpacing;
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
} else if (self.segmentWidthStyle == HMSegmentedControlSegmentWidthStyleDynamic) {
|
|
465
|
-
// When we are drawing dynamic widths, we need to loop the widths
|
|
466
|
-
// array to calculate the xOffset
|
|
467
|
-
CGFloat xOffset = 0;
|
|
468
|
-
NSInteger i = 0;
|
|
469
|
-
|
|
470
|
-
for (NSNumber *width in self.segmentWidthsArray) {
|
|
471
|
-
if (idx == i) {
|
|
472
|
-
break;
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
xOffset = xOffset + [width floatValue];
|
|
476
|
-
i++;
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
BOOL isImageInLineWidthText =
|
|
480
|
-
self.imagePosition == HMSegmentedControlImagePositionLeftOfText ||
|
|
481
|
-
self.imagePosition == HMSegmentedControlImagePositionRightOfText;
|
|
482
|
-
if (isImageInLineWidthText) {
|
|
483
|
-
if (self.imagePosition == HMSegmentedControlImagePositionLeftOfText) {
|
|
484
|
-
imageXOffset = xOffset;
|
|
485
|
-
textXOffset = imageXOffset + imageWidth + self.textImageSpacing;
|
|
486
|
-
} else {
|
|
487
|
-
textXOffset = xOffset;
|
|
488
|
-
imageXOffset = textXOffset + stringWidth + self.textImageSpacing;
|
|
489
|
-
}
|
|
490
|
-
} else {
|
|
491
|
-
imageXOffset = xOffset + ([self.segmentWidthsArray[i] floatValue] - imageWidth) /
|
|
492
|
-
2.0f; // Start with edge inset
|
|
493
|
-
textXOffset =
|
|
494
|
-
xOffset + ([self.segmentWidthsArray[i] floatValue] - stringWidth) / 2.0f;
|
|
495
|
-
|
|
496
|
-
CGFloat whitespace = CGRectGetHeight(self.frame) - imageHeight - stringHeight -
|
|
497
|
-
self.textImageSpacing;
|
|
498
|
-
if (self.imagePosition == HMSegmentedControlImagePositionAboveText) {
|
|
499
|
-
imageYOffset = ceilf(whitespace / 2.0);
|
|
500
|
-
textYOffset = imageYOffset + imageHeight + self.textImageSpacing;
|
|
501
|
-
} else if (self.imagePosition == HMSegmentedControlImagePositionBelowText) {
|
|
502
|
-
textYOffset = ceilf(whitespace / 2.0);
|
|
503
|
-
imageYOffset = textYOffset + stringHeight + self.textImageSpacing;
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
CGRect imageRect = CGRectMake(imageXOffset, imageYOffset, imageWidth, imageHeight);
|
|
509
|
-
CGRect textRect = CGRectMake(ceilf(textXOffset), ceilf(textYOffset), ceilf(stringWidth),
|
|
510
|
-
ceilf(stringHeight));
|
|
511
|
-
|
|
512
|
-
CATextLayer *titleLayer = [CATextLayer layer];
|
|
513
|
-
titleLayer.frame = textRect;
|
|
514
|
-
titleLayer.alignmentMode = kCAAlignmentCenter;
|
|
515
|
-
titleLayer.string = [self attributedTitleAtIndex:idx];
|
|
516
|
-
if ([UIDevice currentDevice].systemVersion.floatValue < 10.0) {
|
|
517
|
-
titleLayer.truncationMode = kCATruncationEnd;
|
|
518
|
-
}
|
|
519
|
-
CALayer *imageLayer = [CALayer layer];
|
|
520
|
-
imageLayer.frame = imageRect;
|
|
521
|
-
|
|
522
|
-
if (self.selectedSegmentIndex == idx) {
|
|
523
|
-
if (self.sectionSelectedImages) {
|
|
524
|
-
UIImage *highlightIcon = [self.sectionSelectedImages objectAtIndex:idx];
|
|
525
|
-
imageLayer.contents = (id)highlightIcon.CGImage;
|
|
526
|
-
} else {
|
|
527
|
-
imageLayer.contents = (id)icon.CGImage;
|
|
528
|
-
}
|
|
529
|
-
} else {
|
|
530
|
-
imageLayer.contents = (id)icon.CGImage;
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
[self.scrollView.layer addSublayer:imageLayer];
|
|
534
|
-
titleLayer.contentsScale = [[UIScreen mainScreen] scale];
|
|
535
|
-
[self.scrollView.layer addSublayer:titleLayer];
|
|
536
|
-
|
|
537
|
-
[self addBackgroundAndBorderLayerWithRect:imageRect];
|
|
538
|
-
}];
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
// Add the selection indicators
|
|
542
|
-
if (self.selectedSegmentIndex != HMSegmentedControlNoSegment) {
|
|
543
|
-
if (self.selectionStyle == HMSegmentedControlSelectionStyleArrow) {
|
|
544
|
-
if (!self.selectionIndicatorArrowLayer.superlayer) {
|
|
545
|
-
[self setArrowFrame];
|
|
546
|
-
[self.scrollView.layer addSublayer:self.selectionIndicatorArrowLayer];
|
|
547
|
-
}
|
|
548
|
-
} else {
|
|
549
|
-
if (!self.selectionIndicatorStripLayer.superlayer) {
|
|
550
|
-
self.selectionIndicatorStripLayer.frame = [self frameForSelectionIndicator];
|
|
551
|
-
[self.scrollView.layer addSublayer:self.selectionIndicatorStripLayer];
|
|
552
|
-
|
|
553
|
-
if (self.selectionStyle == HMSegmentedControlSelectionStyleBox &&
|
|
554
|
-
!self.selectionIndicatorBoxLayer.superlayer) {
|
|
555
|
-
self.selectionIndicatorBoxLayer.frame = [self frameForFillerSelectionIndicator];
|
|
556
|
-
[self.scrollView.layer insertSublayer:self.selectionIndicatorBoxLayer
|
|
557
|
-
atIndex:0];
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
- (void)addBackgroundAndBorderLayerWithRect:(CGRect)fullRect {
|
|
565
|
-
// Background layer
|
|
566
|
-
CALayer *backgroundLayer = [CALayer layer];
|
|
567
|
-
backgroundLayer.frame = fullRect;
|
|
568
|
-
[self.layer insertSublayer:backgroundLayer atIndex:0];
|
|
569
|
-
|
|
570
|
-
// Border layer
|
|
571
|
-
if (self.borderType & HMSegmentedControlBorderTypeTop) {
|
|
572
|
-
CALayer *borderLayer = [CALayer layer];
|
|
573
|
-
borderLayer.frame = CGRectMake(0, 0, fullRect.size.width, self.borderWidth);
|
|
574
|
-
borderLayer.backgroundColor = self.borderColor.CGColor;
|
|
575
|
-
[backgroundLayer addSublayer:borderLayer];
|
|
576
|
-
}
|
|
577
|
-
if (self.borderType & HMSegmentedControlBorderTypeLeft) {
|
|
578
|
-
CALayer *borderLayer = [CALayer layer];
|
|
579
|
-
borderLayer.frame = CGRectMake(0, 0, self.borderWidth, fullRect.size.height);
|
|
580
|
-
borderLayer.backgroundColor = self.borderColor.CGColor;
|
|
581
|
-
[backgroundLayer addSublayer:borderLayer];
|
|
582
|
-
}
|
|
583
|
-
if (self.borderType & HMSegmentedControlBorderTypeBottom) {
|
|
584
|
-
CALayer *borderLayer = [CALayer layer];
|
|
585
|
-
borderLayer.frame = CGRectMake(0, fullRect.size.height - self.borderWidth,
|
|
586
|
-
fullRect.size.width, self.borderWidth);
|
|
587
|
-
borderLayer.backgroundColor = self.borderColor.CGColor;
|
|
588
|
-
[backgroundLayer addSublayer:borderLayer];
|
|
589
|
-
}
|
|
590
|
-
if (self.borderType & HMSegmentedControlBorderTypeRight) {
|
|
591
|
-
CALayer *borderLayer = [CALayer layer];
|
|
592
|
-
borderLayer.frame = CGRectMake(fullRect.size.width - self.borderWidth, 0, self.borderWidth,
|
|
593
|
-
fullRect.size.height);
|
|
594
|
-
borderLayer.backgroundColor = self.borderColor.CGColor;
|
|
595
|
-
[backgroundLayer addSublayer:borderLayer];
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
- (void)setArrowFrame {
|
|
600
|
-
self.selectionIndicatorArrowLayer.frame = [self frameForSelectionIndicator];
|
|
601
|
-
|
|
602
|
-
self.selectionIndicatorArrowLayer.mask = nil;
|
|
603
|
-
|
|
604
|
-
UIBezierPath *arrowPath = [UIBezierPath bezierPath];
|
|
605
|
-
|
|
606
|
-
CGPoint p1 = CGPointZero;
|
|
607
|
-
CGPoint p2 = CGPointZero;
|
|
608
|
-
CGPoint p3 = CGPointZero;
|
|
609
|
-
|
|
610
|
-
if (self.selectionIndicatorLocation == HMSegmentedControlSelectionIndicatorLocationDown) {
|
|
611
|
-
p1 = CGPointMake(self.selectionIndicatorArrowLayer.bounds.size.width / 2, 0);
|
|
612
|
-
p2 = CGPointMake(0, self.selectionIndicatorArrowLayer.bounds.size.height);
|
|
613
|
-
p3 = CGPointMake(self.selectionIndicatorArrowLayer.bounds.size.width,
|
|
614
|
-
self.selectionIndicatorArrowLayer.bounds.size.height);
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
if (self.selectionIndicatorLocation == HMSegmentedControlSelectionIndicatorLocationUp) {
|
|
618
|
-
p1 = CGPointMake(self.selectionIndicatorArrowLayer.bounds.size.width / 2,
|
|
619
|
-
self.selectionIndicatorArrowLayer.bounds.size.height);
|
|
620
|
-
p2 = CGPointMake(self.selectionIndicatorArrowLayer.bounds.size.width, 0);
|
|
621
|
-
p3 = CGPointMake(0, 0);
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
[arrowPath moveToPoint:p1];
|
|
625
|
-
[arrowPath addLineToPoint:p2];
|
|
626
|
-
[arrowPath addLineToPoint:p3];
|
|
627
|
-
[arrowPath closePath];
|
|
628
|
-
|
|
629
|
-
CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
|
|
630
|
-
maskLayer.frame = self.selectionIndicatorArrowLayer.bounds;
|
|
631
|
-
maskLayer.path = arrowPath.CGPath;
|
|
632
|
-
self.selectionIndicatorArrowLayer.mask = maskLayer;
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
- (CGRect)frameForSelectionIndicator {
|
|
636
|
-
CGFloat indicatorYOffset = 0.0f;
|
|
637
|
-
|
|
638
|
-
if (self.selectionIndicatorLocation == HMSegmentedControlSelectionIndicatorLocationDown) {
|
|
639
|
-
indicatorYOffset = self.bounds.size.height - self.selectionIndicatorHeight +
|
|
640
|
-
self.selectionIndicatorEdgeInsets.bottom;
|
|
641
|
-
}
|
|
642
|
-
|
|
643
|
-
if (self.selectionIndicatorLocation == HMSegmentedControlSelectionIndicatorLocationUp) {
|
|
644
|
-
indicatorYOffset = self.selectionIndicatorEdgeInsets.top;
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
CGFloat sectionWidth = 0.0f;
|
|
648
|
-
|
|
649
|
-
if (self.type == HMSegmentedControlTypeText) {
|
|
650
|
-
CGFloat stringWidth = [self measureTitleAtIndex:self.selectedSegmentIndex].width;
|
|
651
|
-
sectionWidth = stringWidth;
|
|
652
|
-
} else if (self.type == HMSegmentedControlTypeImages) {
|
|
653
|
-
UIImage *sectionImage = [self.sectionImages objectAtIndex:self.selectedSegmentIndex];
|
|
654
|
-
CGFloat imageWidth = sectionImage.size.width;
|
|
655
|
-
sectionWidth = imageWidth;
|
|
656
|
-
} else if (self.type == HMSegmentedControlTypeTextImages) {
|
|
657
|
-
CGFloat stringWidth = [self measureTitleAtIndex:self.selectedSegmentIndex].width;
|
|
658
|
-
UIImage *sectionImage = [self.sectionImages objectAtIndex:self.selectedSegmentIndex];
|
|
659
|
-
CGFloat imageWidth = sectionImage.size.width;
|
|
660
|
-
sectionWidth = MAX(stringWidth, imageWidth);
|
|
661
|
-
}
|
|
662
|
-
|
|
663
|
-
if (self.selectionStyle == HMSegmentedControlSelectionStyleArrow) {
|
|
664
|
-
CGFloat widthToEndOfSelectedSegment =
|
|
665
|
-
(self.segmentWidth * self.selectedSegmentIndex) + self.segmentWidth;
|
|
666
|
-
CGFloat widthToStartOfSelectedIndex = (self.segmentWidth * self.selectedSegmentIndex);
|
|
667
|
-
|
|
668
|
-
CGFloat x = widthToStartOfSelectedIndex +
|
|
669
|
-
((widthToEndOfSelectedSegment - widthToStartOfSelectedIndex) / 2) -
|
|
670
|
-
(self.selectionIndicatorHeight / 2);
|
|
671
|
-
return CGRectMake(x - (self.selectionIndicatorHeight / 2), indicatorYOffset,
|
|
672
|
-
self.selectionIndicatorHeight * 2, self.selectionIndicatorHeight);
|
|
673
|
-
} else {
|
|
674
|
-
if (self.selectionStyle == HMSegmentedControlSelectionStyleTextWidthStripe &&
|
|
675
|
-
sectionWidth <= self.segmentWidth &&
|
|
676
|
-
self.segmentWidthStyle != HMSegmentedControlSegmentWidthStyleDynamic) {
|
|
677
|
-
CGFloat widthToEndOfSelectedSegment =
|
|
678
|
-
(self.segmentWidth * self.selectedSegmentIndex) + self.segmentWidth;
|
|
679
|
-
CGFloat widthToStartOfSelectedIndex = (self.segmentWidth * self.selectedSegmentIndex);
|
|
680
|
-
|
|
681
|
-
CGFloat x = ((widthToEndOfSelectedSegment - widthToStartOfSelectedIndex) / 2) +
|
|
682
|
-
(widthToStartOfSelectedIndex - sectionWidth / 2);
|
|
683
|
-
return CGRectMake(x + self.selectionIndicatorEdgeInsets.left, indicatorYOffset,
|
|
684
|
-
sectionWidth - self.selectionIndicatorEdgeInsets.right,
|
|
685
|
-
self.selectionIndicatorHeight);
|
|
686
|
-
} else {
|
|
687
|
-
if (self.segmentWidthStyle == HMSegmentedControlSegmentWidthStyleDynamic) {
|
|
688
|
-
CGFloat selectedSegmentOffset = 0.0f;
|
|
689
|
-
|
|
690
|
-
NSInteger i = 0;
|
|
691
|
-
for (NSNumber *width in self.segmentWidthsArray) {
|
|
692
|
-
if (self.selectedSegmentIndex == i)
|
|
693
|
-
break;
|
|
694
|
-
selectedSegmentOffset = selectedSegmentOffset + [width floatValue];
|
|
695
|
-
i++;
|
|
696
|
-
}
|
|
697
|
-
return CGRectMake(
|
|
698
|
-
selectedSegmentOffset + self.selectionIndicatorEdgeInsets.left,
|
|
699
|
-
indicatorYOffset,
|
|
700
|
-
[[self.segmentWidthsArray objectAtIndex:self.selectedSegmentIndex] floatValue] -
|
|
701
|
-
self.selectionIndicatorEdgeInsets.right,
|
|
702
|
-
self.selectionIndicatorHeight + self.selectionIndicatorEdgeInsets.bottom);
|
|
703
|
-
}
|
|
704
|
-
|
|
705
|
-
return CGRectMake((self.segmentWidth + self.selectionIndicatorEdgeInsets.left) *
|
|
706
|
-
self.selectedSegmentIndex,
|
|
707
|
-
indicatorYOffset,
|
|
708
|
-
self.segmentWidth - self.selectionIndicatorEdgeInsets.right,
|
|
709
|
-
self.selectionIndicatorHeight);
|
|
710
|
-
}
|
|
711
|
-
}
|
|
712
|
-
}
|
|
713
|
-
|
|
714
|
-
- (CGRect)frameForFillerSelectionIndicator {
|
|
715
|
-
if (self.segmentWidthStyle == HMSegmentedControlSegmentWidthStyleDynamic) {
|
|
716
|
-
CGFloat selectedSegmentOffset = 0.0f;
|
|
717
|
-
|
|
718
|
-
NSInteger i = 0;
|
|
719
|
-
for (NSNumber *width in self.segmentWidthsArray) {
|
|
720
|
-
if (self.selectedSegmentIndex == i) {
|
|
721
|
-
break;
|
|
722
|
-
}
|
|
723
|
-
selectedSegmentOffset = selectedSegmentOffset + [width floatValue];
|
|
724
|
-
|
|
725
|
-
i++;
|
|
726
|
-
}
|
|
727
|
-
|
|
728
|
-
return CGRectMake(
|
|
729
|
-
selectedSegmentOffset, 0,
|
|
730
|
-
[[self.segmentWidthsArray objectAtIndex:self.selectedSegmentIndex] floatValue],
|
|
731
|
-
CGRectGetHeight(self.frame));
|
|
732
|
-
}
|
|
733
|
-
return CGRectMake(self.segmentWidth * self.selectedSegmentIndex, 0, self.segmentWidth,
|
|
734
|
-
CGRectGetHeight(self.frame));
|
|
735
|
-
}
|
|
736
|
-
|
|
737
|
-
- (void)updateSegmentsRects {
|
|
738
|
-
self.scrollView.contentInset = UIEdgeInsetsZero;
|
|
739
|
-
self.scrollView.frame =
|
|
740
|
-
CGRectMake(0, 0, CGRectGetWidth(self.frame), CGRectGetHeight(self.frame));
|
|
741
|
-
|
|
742
|
-
if ([self sectionCount] > 0) {
|
|
743
|
-
self.segmentWidth = self.frame.size.width / [self sectionCount];
|
|
744
|
-
}
|
|
745
|
-
|
|
746
|
-
if (self.type == HMSegmentedControlTypeText &&
|
|
747
|
-
self.segmentWidthStyle == HMSegmentedControlSegmentWidthStyleFixed) {
|
|
748
|
-
[self.sectionTitles
|
|
749
|
-
enumerateObjectsUsingBlock:^(id titleString, NSUInteger idx, BOOL *stop) {
|
|
750
|
-
CGFloat stringWidth = [self measureTitleAtIndex:idx].width +
|
|
751
|
-
self.segmentEdgeInset.left + self.segmentEdgeInset.right;
|
|
752
|
-
self.segmentWidth = MAX(stringWidth, self.segmentWidth);
|
|
753
|
-
}];
|
|
754
|
-
} else if (self.type == HMSegmentedControlTypeText &&
|
|
755
|
-
self.segmentWidthStyle == HMSegmentedControlSegmentWidthStyleDynamic) {
|
|
756
|
-
NSMutableArray *mutableSegmentWidths = [NSMutableArray array];
|
|
757
|
-
|
|
758
|
-
[self.sectionTitles
|
|
759
|
-
enumerateObjectsUsingBlock:^(id titleString, NSUInteger idx, BOOL *stop) {
|
|
760
|
-
CGFloat stringWidth = [self measureTitleAtIndex:idx].width +
|
|
761
|
-
self.segmentEdgeInset.left + self.segmentEdgeInset.right;
|
|
762
|
-
[mutableSegmentWidths addObject:[NSNumber numberWithFloat:stringWidth]];
|
|
763
|
-
}];
|
|
764
|
-
self.segmentWidthsArray = [mutableSegmentWidths copy];
|
|
765
|
-
} else if (self.type == HMSegmentedControlTypeImages) {
|
|
766
|
-
for (UIImage *sectionImage in self.sectionImages) {
|
|
767
|
-
CGFloat imageWidth =
|
|
768
|
-
sectionImage.size.width + self.segmentEdgeInset.left + self.segmentEdgeInset.right;
|
|
769
|
-
self.segmentWidth = MAX(imageWidth, self.segmentWidth);
|
|
770
|
-
}
|
|
771
|
-
} else if (self.type == HMSegmentedControlTypeTextImages &&
|
|
772
|
-
self.segmentWidthStyle == HMSegmentedControlSegmentWidthStyleFixed) {
|
|
773
|
-
// lets just use the title.. we will assume it is wider then images...
|
|
774
|
-
[self.sectionTitles
|
|
775
|
-
enumerateObjectsUsingBlock:^(id titleString, NSUInteger idx, BOOL *stop) {
|
|
776
|
-
CGFloat stringWidth = [self measureTitleAtIndex:idx].width +
|
|
777
|
-
self.segmentEdgeInset.left + self.segmentEdgeInset.right;
|
|
778
|
-
self.segmentWidth = MAX(stringWidth, self.segmentWidth);
|
|
779
|
-
}];
|
|
780
|
-
} else if (self.type == HMSegmentedControlTypeTextImages &&
|
|
781
|
-
self.segmentWidthStyle == HMSegmentedControlSegmentWidthStyleDynamic) {
|
|
782
|
-
NSMutableArray *mutableSegmentWidths = [NSMutableArray array];
|
|
783
|
-
__block CGFloat totalWidth = 0.0;
|
|
784
|
-
|
|
785
|
-
int i = 0;
|
|
786
|
-
[self.sectionTitles enumerateObjectsUsingBlock:^(id titleString, NSUInteger idx,
|
|
787
|
-
BOOL *stop) {
|
|
788
|
-
CGFloat stringWidth = [self measureTitleAtIndex:idx].width + self.segmentEdgeInset.right;
|
|
789
|
-
UIImage *sectionImage = [self.sectionImages objectAtIndex:i];
|
|
790
|
-
CGFloat imageWidth = sectionImage.size.width + self.segmentEdgeInset.left;
|
|
791
|
-
|
|
792
|
-
CGFloat combinedWidth = 0.0;
|
|
793
|
-
if (self.imagePosition == HMSegmentedControlImagePositionLeftOfText ||
|
|
794
|
-
self.imagePosition == HMSegmentedControlImagePositionRightOfText) {
|
|
795
|
-
combinedWidth = imageWidth + stringWidth + self.textImageSpacing;
|
|
796
|
-
} else {
|
|
797
|
-
combinedWidth = MAX(imageWidth, stringWidth);
|
|
798
|
-
}
|
|
799
|
-
|
|
800
|
-
totalWidth += combinedWidth;
|
|
801
|
-
|
|
802
|
-
[mutableSegmentWidths addObject:[NSNumber numberWithFloat:combinedWidth]];
|
|
803
|
-
}];
|
|
804
|
-
|
|
805
|
-
if (self.shouldStretchSegmentsToScreenSize && totalWidth < self.bounds.size.width) {
|
|
806
|
-
CGFloat whitespace = self.bounds.size.width - totalWidth;
|
|
807
|
-
CGFloat whitespaceForSegment = whitespace / [mutableSegmentWidths count];
|
|
808
|
-
[mutableSegmentWidths enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx,
|
|
809
|
-
BOOL *_Nonnull stop) {
|
|
810
|
-
CGFloat extendedWidth = whitespaceForSegment + [obj floatValue];
|
|
811
|
-
[mutableSegmentWidths replaceObjectAtIndex:idx
|
|
812
|
-
withObject:[NSNumber numberWithFloat:extendedWidth]];
|
|
813
|
-
}];
|
|
814
|
-
}
|
|
815
|
-
|
|
816
|
-
self.segmentWidthsArray = [mutableSegmentWidths copy];
|
|
817
|
-
}
|
|
818
|
-
|
|
819
|
-
self.scrollView.scrollEnabled = self.isUserDraggable;
|
|
820
|
-
self.scrollView.contentSize =
|
|
821
|
-
CGSizeMake([self totalSegmentedControlWidth], self.frame.size.height);
|
|
822
|
-
}
|
|
823
|
-
|
|
824
|
-
- (NSUInteger)sectionCount {
|
|
825
|
-
if (self.type == HMSegmentedControlTypeText) {
|
|
826
|
-
return self.sectionTitles.count;
|
|
827
|
-
} else if (self.type == HMSegmentedControlTypeImages ||
|
|
828
|
-
self.type == HMSegmentedControlTypeTextImages) {
|
|
829
|
-
return self.sectionImages.count;
|
|
830
|
-
}
|
|
831
|
-
|
|
832
|
-
return 0;
|
|
833
|
-
}
|
|
834
|
-
|
|
835
|
-
- (void)willMoveToSuperview:(UIView *)newSuperview {
|
|
836
|
-
// Control is being removed
|
|
837
|
-
if (newSuperview == nil)
|
|
838
|
-
return;
|
|
839
|
-
|
|
840
|
-
if (self.sectionTitles || self.sectionImages) {
|
|
841
|
-
[self updateSegmentsRects];
|
|
842
|
-
}
|
|
843
|
-
}
|
|
844
|
-
|
|
845
|
-
#pragma mark - Touch
|
|
846
|
-
|
|
847
|
-
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
|
|
848
|
-
UITouch *touch = [touches anyObject];
|
|
849
|
-
CGPoint touchLocation = [touch locationInView:self];
|
|
850
|
-
|
|
851
|
-
CGRect enlargeRect = CGRectMake(
|
|
852
|
-
self.bounds.origin.x - self.enlargeEdgeInset.left,
|
|
853
|
-
self.bounds.origin.y - self.enlargeEdgeInset.top,
|
|
854
|
-
self.bounds.size.width + self.enlargeEdgeInset.left + self.enlargeEdgeInset.right,
|
|
855
|
-
self.bounds.size.height + self.enlargeEdgeInset.top + self.enlargeEdgeInset.bottom);
|
|
856
|
-
|
|
857
|
-
if (CGRectContainsPoint(enlargeRect, touchLocation)) {
|
|
858
|
-
NSInteger segment = 0;
|
|
859
|
-
if (self.segmentWidthStyle == HMSegmentedControlSegmentWidthStyleFixed) {
|
|
860
|
-
segment = (touchLocation.x + self.scrollView.contentOffset.x) / self.segmentWidth;
|
|
861
|
-
} else if (self.segmentWidthStyle == HMSegmentedControlSegmentWidthStyleDynamic) {
|
|
862
|
-
// To know which segment the user touched, we need to loop over the
|
|
863
|
-
// widths and substract it from the x position.
|
|
864
|
-
CGFloat widthLeft = (touchLocation.x + self.scrollView.contentOffset.x);
|
|
865
|
-
for (NSNumber *width in self.segmentWidthsArray) {
|
|
866
|
-
widthLeft = widthLeft - [width floatValue];
|
|
867
|
-
|
|
868
|
-
// When we don't have any width left to substract, we have the
|
|
869
|
-
// segment index.
|
|
870
|
-
if (widthLeft <= 0)
|
|
871
|
-
break;
|
|
872
|
-
|
|
873
|
-
segment++;
|
|
874
|
-
}
|
|
875
|
-
}
|
|
876
|
-
|
|
877
|
-
NSUInteger sectionsCount = 0;
|
|
878
|
-
|
|
879
|
-
if (self.type == HMSegmentedControlTypeImages) {
|
|
880
|
-
sectionsCount = [self.sectionImages count];
|
|
881
|
-
} else if (self.type == HMSegmentedControlTypeTextImages ||
|
|
882
|
-
self.type == HMSegmentedControlTypeText) {
|
|
883
|
-
sectionsCount = [self.sectionTitles count];
|
|
884
|
-
}
|
|
885
|
-
|
|
886
|
-
if (segment != self.selectedSegmentIndex && segment < sectionsCount) {
|
|
887
|
-
// Check if we have to do anything with the touch event
|
|
888
|
-
if (self.isTouchEnabled)
|
|
889
|
-
[self setSelectedSegmentIndex:segment
|
|
890
|
-
animated:self.shouldAnimateUserSelection
|
|
891
|
-
notify:YES];
|
|
892
|
-
}
|
|
893
|
-
}
|
|
894
|
-
}
|
|
895
|
-
|
|
896
|
-
#pragma mark - Scrolling
|
|
897
|
-
|
|
898
|
-
- (CGFloat)totalSegmentedControlWidth {
|
|
899
|
-
if (self.type == HMSegmentedControlTypeText &&
|
|
900
|
-
self.segmentWidthStyle == HMSegmentedControlSegmentWidthStyleFixed) {
|
|
901
|
-
return self.sectionTitles.count * self.segmentWidth;
|
|
902
|
-
} else if (self.segmentWidthStyle == HMSegmentedControlSegmentWidthStyleDynamic) {
|
|
903
|
-
return [[self.segmentWidthsArray valueForKeyPath:@"@sum.self"] floatValue];
|
|
904
|
-
} else {
|
|
905
|
-
return self.sectionImages.count * self.segmentWidth;
|
|
906
|
-
}
|
|
907
|
-
}
|
|
908
|
-
|
|
909
|
-
- (void)scrollToSelectedSegmentIndex:(BOOL)animated {
|
|
910
|
-
CGRect rectForSelectedIndex = CGRectZero;
|
|
911
|
-
CGFloat selectedSegmentOffset = 0;
|
|
912
|
-
if (self.segmentWidthStyle == HMSegmentedControlSegmentWidthStyleFixed) {
|
|
913
|
-
rectForSelectedIndex = CGRectMake(self.segmentWidth * self.selectedSegmentIndex, 0,
|
|
914
|
-
self.segmentWidth, self.frame.size.height);
|
|
915
|
-
|
|
916
|
-
selectedSegmentOffset = (CGRectGetWidth(self.frame) / 2) - (self.segmentWidth / 2);
|
|
917
|
-
} else {
|
|
918
|
-
NSInteger i = 0;
|
|
919
|
-
CGFloat offsetter = 0;
|
|
920
|
-
for (NSNumber *width in self.segmentWidthsArray) {
|
|
921
|
-
if (self.selectedSegmentIndex == i)
|
|
922
|
-
break;
|
|
923
|
-
offsetter = offsetter + [width floatValue];
|
|
924
|
-
i++;
|
|
925
|
-
}
|
|
926
|
-
|
|
927
|
-
rectForSelectedIndex = CGRectMake(
|
|
928
|
-
offsetter, 0,
|
|
929
|
-
[[self.segmentWidthsArray objectAtIndex:self.selectedSegmentIndex] floatValue],
|
|
930
|
-
self.frame.size.height);
|
|
931
|
-
|
|
932
|
-
selectedSegmentOffset =
|
|
933
|
-
(CGRectGetWidth(self.frame) / 2) -
|
|
934
|
-
([[self.segmentWidthsArray objectAtIndex:self.selectedSegmentIndex] floatValue] / 2);
|
|
935
|
-
}
|
|
936
|
-
|
|
937
|
-
CGRect rectToScrollTo = rectForSelectedIndex;
|
|
938
|
-
rectToScrollTo.origin.x -= selectedSegmentOffset;
|
|
939
|
-
rectToScrollTo.size.width += selectedSegmentOffset * 2;
|
|
940
|
-
[self.scrollView scrollRectToVisible:rectToScrollTo animated:animated];
|
|
941
|
-
}
|
|
942
|
-
|
|
943
|
-
#pragma mark - Index Change
|
|
944
|
-
|
|
945
|
-
- (void)setSelectedSegmentIndex:(NSInteger)index {
|
|
946
|
-
[self setSelectedSegmentIndex:index animated:NO notify:NO];
|
|
947
|
-
}
|
|
948
|
-
|
|
949
|
-
- (void)setSelectedSegmentIndex:(NSUInteger)index animated:(BOOL)animated {
|
|
950
|
-
[self setSelectedSegmentIndex:index animated:animated notify:NO];
|
|
951
|
-
}
|
|
952
|
-
|
|
953
|
-
- (void)setSelectedSegmentIndex:(NSUInteger)index animated:(BOOL)animated notify:(BOOL)notify {
|
|
954
|
-
_selectedSegmentIndex = index;
|
|
955
|
-
[self setNeedsDisplay];
|
|
956
|
-
|
|
957
|
-
if (index == HMSegmentedControlNoSegment) {
|
|
958
|
-
[self.selectionIndicatorArrowLayer removeFromSuperlayer];
|
|
959
|
-
[self.selectionIndicatorStripLayer removeFromSuperlayer];
|
|
960
|
-
[self.selectionIndicatorBoxLayer removeFromSuperlayer];
|
|
961
|
-
} else {
|
|
962
|
-
[self scrollToSelectedSegmentIndex:animated];
|
|
963
|
-
|
|
964
|
-
if (animated) {
|
|
965
|
-
// If the selected segment layer is not added to the super layer,
|
|
966
|
-
// that means no index is currently selected, so add the layer then
|
|
967
|
-
// move it to the new segment index without animating.
|
|
968
|
-
if (self.selectionStyle == HMSegmentedControlSelectionStyleArrow) {
|
|
969
|
-
if ([self.selectionIndicatorArrowLayer superlayer] == nil) {
|
|
970
|
-
[self.scrollView.layer addSublayer:self.selectionIndicatorArrowLayer];
|
|
971
|
-
|
|
972
|
-
[self setSelectedSegmentIndex:index animated:NO notify:YES];
|
|
973
|
-
return;
|
|
974
|
-
}
|
|
975
|
-
} else {
|
|
976
|
-
if ([self.selectionIndicatorStripLayer superlayer] == nil) {
|
|
977
|
-
[self.scrollView.layer addSublayer:self.selectionIndicatorStripLayer];
|
|
978
|
-
|
|
979
|
-
if (self.selectionStyle == HMSegmentedControlSelectionStyleBox &&
|
|
980
|
-
[self.selectionIndicatorBoxLayer superlayer] == nil)
|
|
981
|
-
[self.scrollView.layer insertSublayer:self.selectionIndicatorBoxLayer
|
|
982
|
-
atIndex:0];
|
|
983
|
-
|
|
984
|
-
[self setSelectedSegmentIndex:index animated:NO notify:YES];
|
|
985
|
-
return;
|
|
986
|
-
}
|
|
987
|
-
}
|
|
988
|
-
|
|
989
|
-
if (notify)
|
|
990
|
-
[self notifyForSegmentChangeToIndex:index];
|
|
991
|
-
|
|
992
|
-
// Restore CALayer animations
|
|
993
|
-
self.selectionIndicatorArrowLayer.actions = nil;
|
|
994
|
-
self.selectionIndicatorStripLayer.actions = nil;
|
|
995
|
-
self.selectionIndicatorBoxLayer.actions = nil;
|
|
996
|
-
|
|
997
|
-
// Animate to new position
|
|
998
|
-
[CATransaction begin];
|
|
999
|
-
[CATransaction setAnimationDuration:0.15f];
|
|
1000
|
-
[CATransaction
|
|
1001
|
-
setAnimationTimingFunction:[CAMediaTimingFunction
|
|
1002
|
-
functionWithName:kCAMediaTimingFunctionLinear]];
|
|
1003
|
-
[self setArrowFrame];
|
|
1004
|
-
self.selectionIndicatorBoxLayer.frame = [self frameForSelectionIndicator];
|
|
1005
|
-
self.selectionIndicatorStripLayer.frame = [self frameForSelectionIndicator];
|
|
1006
|
-
self.selectionIndicatorBoxLayer.frame = [self frameForFillerSelectionIndicator];
|
|
1007
|
-
[CATransaction commit];
|
|
1008
|
-
} else {
|
|
1009
|
-
// Disable CALayer animations
|
|
1010
|
-
NSMutableDictionary *newActions = [[NSMutableDictionary alloc]
|
|
1011
|
-
initWithObjectsAndKeys:[NSNull null], @"position", [NSNull null], @"bounds", nil];
|
|
1012
|
-
self.selectionIndicatorArrowLayer.actions = newActions;
|
|
1013
|
-
[self setArrowFrame];
|
|
1014
|
-
|
|
1015
|
-
self.selectionIndicatorStripLayer.actions = newActions;
|
|
1016
|
-
self.selectionIndicatorStripLayer.frame = [self frameForSelectionIndicator];
|
|
1017
|
-
|
|
1018
|
-
self.selectionIndicatorBoxLayer.actions = newActions;
|
|
1019
|
-
self.selectionIndicatorBoxLayer.frame = [self frameForFillerSelectionIndicator];
|
|
1020
|
-
|
|
1021
|
-
if (notify)
|
|
1022
|
-
[self notifyForSegmentChangeToIndex:index];
|
|
1023
|
-
}
|
|
1024
|
-
}
|
|
1025
|
-
}
|
|
1026
|
-
|
|
1027
|
-
- (void)notifyForSegmentChangeToIndex:(NSInteger)index {
|
|
1028
|
-
if (self.superview)
|
|
1029
|
-
[self sendActionsForControlEvents:UIControlEventValueChanged];
|
|
1030
|
-
|
|
1031
|
-
if (self.indexChangeBlock)
|
|
1032
|
-
self.indexChangeBlock(index);
|
|
1033
|
-
}
|
|
1034
|
-
|
|
1035
|
-
#pragma mark - Styling Support
|
|
1036
|
-
|
|
1037
|
-
- (NSDictionary *)resultingTitleTextAttributes {
|
|
1038
|
-
NSDictionary *defaults = @{
|
|
1039
|
-
NSFontAttributeName : [UIFont systemFontOfSize:19.0f],
|
|
1040
|
-
NSForegroundColorAttributeName : [UIColor blackColor],
|
|
1041
|
-
};
|
|
1042
|
-
|
|
1043
|
-
NSMutableDictionary *resultingAttrs = [NSMutableDictionary dictionaryWithDictionary:defaults];
|
|
1044
|
-
|
|
1045
|
-
if (self.titleTextAttributes) {
|
|
1046
|
-
[resultingAttrs addEntriesFromDictionary:self.titleTextAttributes];
|
|
1047
|
-
}
|
|
1048
|
-
|
|
1049
|
-
return [resultingAttrs copy];
|
|
1050
|
-
}
|
|
1051
|
-
|
|
1052
|
-
- (NSDictionary *)resultingSelectedTitleTextAttributes {
|
|
1053
|
-
NSMutableDictionary *resultingAttrs =
|
|
1054
|
-
[NSMutableDictionary dictionaryWithDictionary:[self resultingTitleTextAttributes]];
|
|
1055
|
-
|
|
1056
|
-
if (self.selectedTitleTextAttributes) {
|
|
1057
|
-
[resultingAttrs addEntriesFromDictionary:self.selectedTitleTextAttributes];
|
|
1058
|
-
}
|
|
1059
|
-
|
|
1060
|
-
return [resultingAttrs copy];
|
|
1061
|
-
}
|
|
1062
|
-
|
|
1063
|
-
@end
|