|
@@ -7,6 +7,7 @@
|
7
|
7
|
#import "UIImage+insets.h"
|
8
|
8
|
#import "UIViewController+LayoutProtocol.h"
|
9
|
9
|
#import "RNNFontAttributesCreator.h"
|
|
10
|
+#import "NSArray+utils.h"
|
10
|
11
|
|
11
|
12
|
@interface RNNNavigationButtons()
|
12
|
13
|
|
|
@@ -19,167 +20,180 @@
|
19
|
20
|
@implementation RNNNavigationButtons
|
20
|
21
|
|
21
|
22
|
-(instancetype)initWithViewController:(UIViewController<RNNLayoutProtocol>*)viewController componentRegistry:(id)componentRegistry {
|
22
|
|
- self = [super init];
|
23
|
|
-
|
24
|
|
- self.viewController = viewController;
|
25
|
|
- self.componentRegistry = componentRegistry;
|
26
|
|
-
|
27
|
|
- return self;
|
|
23
|
+ self = [super init];
|
|
24
|
+
|
|
25
|
+ self.viewController = viewController;
|
|
26
|
+ self.componentRegistry = componentRegistry;
|
|
27
|
+
|
|
28
|
+ return self;
|
28
|
29
|
}
|
29
|
30
|
|
30
|
31
|
- (void)applyLeftButtons:(NSArray *)leftButtons rightButtons:(NSArray *)rightButtons defaultLeftButtonStyle:(RNNButtonOptions *)defaultLeftButtonStyle defaultRightButtonStyle:(RNNButtonOptions *)defaultRightButtonStyle {
|
31
|
|
- _defaultLeftButtonStyle = defaultLeftButtonStyle;
|
32
|
|
- _defaultRightButtonStyle = defaultRightButtonStyle;
|
33
|
|
- if (leftButtons) {
|
34
|
|
- [self setButtons:leftButtons side:@"left" animated:NO defaultStyle:_defaultLeftButtonStyle insets:[self leftButtonInsets:_defaultLeftButtonStyle.iconInsets]];
|
35
|
|
- }
|
36
|
|
-
|
37
|
|
- if (rightButtons) {
|
38
|
|
- [self setButtons:rightButtons side:@"right" animated:NO defaultStyle:_defaultRightButtonStyle insets:[self rightButtonInsets:_defaultRightButtonStyle.iconInsets]];
|
39
|
|
- }
|
|
32
|
+ _defaultLeftButtonStyle = defaultLeftButtonStyle;
|
|
33
|
+ _defaultRightButtonStyle = defaultRightButtonStyle;
|
|
34
|
+ if (leftButtons) {
|
|
35
|
+ [self setButtons:leftButtons side:@"left" animated:NO defaultStyle:_defaultLeftButtonStyle insets:[self leftButtonInsets:_defaultLeftButtonStyle.iconInsets]];
|
|
36
|
+ }
|
|
37
|
+
|
|
38
|
+ if (rightButtons) {
|
|
39
|
+ [self setButtons:rightButtons side:@"right" animated:NO defaultStyle:_defaultRightButtonStyle insets:[self rightButtonInsets:_defaultRightButtonStyle.iconInsets]];
|
|
40
|
+ }
|
40
|
41
|
}
|
41
|
42
|
|
42
|
43
|
-(void)setButtons:(NSArray*)buttons side:(NSString*)side animated:(BOOL)animated defaultStyle:(RNNButtonOptions *)defaultStyle insets:(UIEdgeInsets)insets {
|
43
|
|
- NSMutableArray *barButtonItems = [NSMutableArray new];
|
44
|
|
- NSArray* resolvedButtons = [self resolveButtons:buttons];
|
45
|
|
- for (NSDictionary *button in resolvedButtons) {
|
46
|
|
- RNNUIBarButtonItem* barButtonItem = [self buildButton:button defaultStyle:defaultStyle insets:insets];
|
47
|
|
- if(barButtonItem) {
|
48
|
|
- [barButtonItems addObject:barButtonItem];
|
49
|
|
- }
|
50
|
|
- UIColor* color = [self color:[RCTConvert UIColor:button[@"color"]] defaultColor:[defaultStyle.color getWithDefaultValue:nil]];
|
51
|
|
- if (color) {
|
52
|
|
- self.viewController.navigationController.navigationBar.tintColor = color;
|
53
|
|
- }
|
54
|
|
- }
|
55
|
|
-
|
56
|
|
- if ([side isEqualToString:@"left"]) {
|
57
|
|
- [self.viewController.navigationItem setLeftBarButtonItems:barButtonItems animated:animated];
|
58
|
|
- }
|
59
|
|
-
|
60
|
|
- if ([side isEqualToString:@"right"]) {
|
61
|
|
- [self.viewController.navigationItem setRightBarButtonItems:barButtonItems animated:animated];
|
62
|
|
- }
|
|
44
|
+ NSMutableArray *barButtonItems = [NSMutableArray new];
|
|
45
|
+ NSArray* resolvedButtons = [self resolveButtons:buttons];
|
|
46
|
+ for (NSDictionary *button in resolvedButtons) {
|
|
47
|
+ RNNUIBarButtonItem* barButtonItem = [self buildButton:button defaultStyle:defaultStyle insets:insets];
|
|
48
|
+ if(barButtonItem) {
|
|
49
|
+ [barButtonItems addObject:barButtonItem];
|
|
50
|
+ }
|
|
51
|
+ UIColor* color = [self color:[RCTConvert UIColor:button[@"color"]] defaultColor:[defaultStyle.color getWithDefaultValue:nil]];
|
|
52
|
+ if (color) {
|
|
53
|
+ self.viewController.navigationController.navigationBar.tintColor = color;
|
|
54
|
+ }
|
|
55
|
+ }
|
|
56
|
+
|
|
57
|
+ if ([side isEqualToString:@"left"]) {
|
|
58
|
+ [self clearPreviousButtonViews:barButtonItems oldButtons:self.viewController.navigationItem.leftBarButtonItems];
|
|
59
|
+ [self.viewController.navigationItem setLeftBarButtonItems:barButtonItems animated:animated];
|
|
60
|
+ }
|
|
61
|
+
|
|
62
|
+ if ([side isEqualToString:@"right"]) {
|
|
63
|
+ [self clearPreviousButtonViews:barButtonItems oldButtons:self.viewController.navigationItem.rightBarButtonItems];
|
|
64
|
+ [self.viewController.navigationItem setRightBarButtonItems:barButtonItems animated:animated];
|
|
65
|
+ }
|
|
66
|
+}
|
|
67
|
+
|
|
68
|
+- (void)clearPreviousButtonViews:(NSArray<UIBarButtonItem *> *)newButtons oldButtons:(NSArray<UIBarButtonItem *> *)oldButtons {
|
|
69
|
+ NSArray<UIBarButtonItem *>* removedButtons = [oldButtons difference:newButtons withPropertyName:@"customView"];
|
|
70
|
+
|
|
71
|
+ for (UIBarButtonItem* buttonItem in removedButtons) {
|
|
72
|
+ RNNReactView* reactView = buttonItem.customView;
|
|
73
|
+ if ([reactView isKindOfClass:[RNNReactView class]]) {
|
|
74
|
+ [_componentRegistry removeChildComponent:reactView.componentId];
|
|
75
|
+ }
|
|
76
|
+ }
|
63
|
77
|
}
|
64
|
78
|
|
65
|
79
|
- (NSArray *)resolveButtons:(id)buttons {
|
66
|
|
- if ([buttons isKindOfClass:[NSArray class]]) {
|
67
|
|
- return buttons;
|
68
|
|
- } else {
|
69
|
|
- return @[buttons];
|
70
|
|
- }
|
|
80
|
+ if ([buttons isKindOfClass:[NSArray class]]) {
|
|
81
|
+ return buttons;
|
|
82
|
+ } else {
|
|
83
|
+ return @[buttons];
|
|
84
|
+ }
|
71
|
85
|
}
|
72
|
86
|
|
73
|
87
|
-(RNNUIBarButtonItem*)buildButton: (NSDictionary*)dictionary defaultStyle:(RNNButtonOptions *)defaultStyle insets:(UIEdgeInsets)insets {
|
74
|
|
- NSString* buttonId = dictionary[@"id"];
|
75
|
|
- NSString* title = [self getValue:dictionary[@"text"] withDefault:[defaultStyle.text getWithDefaultValue:nil]];
|
76
|
|
- NSDictionary* component = dictionary[@"component"];
|
77
|
|
- NSString* systemItemName = dictionary[@"systemItem"];
|
78
|
|
-
|
79
|
|
- UIColor* color = [self color:[RCTConvert UIColor:dictionary[@"color"]] defaultColor:[defaultStyle.color getWithDefaultValue:nil]];
|
80
|
|
- UIColor* disabledColor = [self color:[RCTConvert UIColor:dictionary[@"disabledColor"]] defaultColor:[defaultStyle.disabledColor getWithDefaultValue:nil]];
|
81
|
|
-
|
82
|
|
- if (!buttonId) {
|
83
|
|
- @throw [NSException exceptionWithName:@"NSInvalidArgumentException" reason:[@"button id is not specified " stringByAppendingString:title] userInfo:nil];
|
84
|
|
- }
|
85
|
|
-
|
86
|
|
- UIImage* defaultIcon = [defaultStyle.icon getWithDefaultValue:nil];
|
87
|
|
- UIImage* iconImage = [self getValue:dictionary[@"icon"] withDefault:defaultIcon];
|
88
|
|
- if (![iconImage isKindOfClass:[UIImage class]]) {
|
89
|
|
- iconImage = [RCTConvert UIImage:iconImage];
|
90
|
|
- }
|
91
|
|
-
|
92
|
|
- if (iconImage) {
|
93
|
|
- iconImage = [iconImage imageWithInsets:insets];
|
94
|
|
- if (color) {
|
95
|
|
- iconImage = [iconImage withTintColor:color];
|
96
|
|
- }
|
97
|
|
- }
|
98
|
|
-
|
99
|
|
-
|
100
|
|
- RNNUIBarButtonItem *barButtonItem;
|
101
|
|
- if (component) {
|
102
|
|
- RNNComponentOptions* componentOptions = [RNNComponentOptions new];
|
103
|
|
- componentOptions.componentId = [[Text alloc] initWithValue:component[@"componentId"]];
|
104
|
|
- componentOptions.name = [[Text alloc] initWithValue:component[@"name"]];
|
105
|
|
-
|
106
|
|
- RNNReactView *view = [_componentRegistry createComponentIfNotExists:componentOptions parentComponentId:self.viewController.layoutInfo.componentId reactViewReadyBlock:nil];
|
107
|
|
- barButtonItem = [[RNNUIBarButtonItem alloc] init:buttonId withCustomView:view componentRegistry:_componentRegistry];
|
108
|
|
- } else if (iconImage) {
|
109
|
|
- barButtonItem = [[RNNUIBarButtonItem alloc] init:buttonId withIcon:iconImage];
|
110
|
|
- } else if (title) {
|
111
|
|
- barButtonItem = [[RNNUIBarButtonItem alloc] init:buttonId withTitle:title];
|
112
|
|
-
|
113
|
|
- NSMutableDictionary *buttonTextAttributes = [RCTHelpers textAttributesFromDictionary:dictionary withPrefix:@"button"];
|
114
|
|
- if (buttonTextAttributes.allKeys.count > 0) {
|
115
|
|
- [barButtonItem setTitleTextAttributes:buttonTextAttributes forState:UIControlStateNormal];
|
116
|
|
- }
|
117
|
|
- } else if (systemItemName) {
|
118
|
|
- barButtonItem = [[RNNUIBarButtonItem alloc] init:buttonId withSystemItem:systemItemName];
|
119
|
|
- } else {
|
120
|
|
- return nil;
|
121
|
|
- }
|
122
|
|
-
|
123
|
|
- barButtonItem.target = self.viewController;
|
124
|
|
- barButtonItem.action = @selector(onButtonPress:);
|
125
|
|
-
|
126
|
|
- NSNumber *enabled = [self getValue:dictionary[@"enabled"] withDefault:defaultStyle.enabled.getValue];
|
127
|
|
- BOOL enabledBool = enabled ? [enabled boolValue] : YES;
|
128
|
|
- [barButtonItem setEnabled:enabledBool];
|
129
|
|
-
|
130
|
|
- NSMutableDictionary* textAttributes = [NSMutableDictionary dictionaryWithDictionary:[RNNFontAttributesCreator createWithFontFamily:dictionary[@"fontFamily"] ?: [defaultStyle.fontFamily getWithDefaultValue:nil] fontSize:dictionary[@"fontSize"] defaultFontSize:[defaultStyle.fontSize getWithDefaultValue:@(17)] fontWeight:dictionary[@"fontWeight"] color:nil defaultColor:nil]];
|
131
|
|
- NSMutableDictionary* disabledTextAttributes = [NSMutableDictionary dictionaryWithDictionary:[RNNFontAttributesCreator createWithFontFamily:dictionary[@"fontFamily"] ?: [defaultStyle.fontFamily getWithDefaultValue:nil] fontSize:dictionary[@"fontSize"] defaultFontSize:[defaultStyle.fontSize getWithDefaultValue:@(17)] fontWeight:dictionary[@"fontWeight"] color:nil defaultColor:nil]];
|
132
|
|
-
|
133
|
|
- if (!enabledBool && disabledColor) {
|
134
|
|
- color = disabledColor;
|
135
|
|
- [disabledTextAttributes setObject:disabledColor forKey:NSForegroundColorAttributeName];
|
136
|
|
- }
|
137
|
|
-
|
138
|
|
- if (color) {
|
139
|
|
- [textAttributes setObject:color forKey:NSForegroundColorAttributeName];
|
140
|
|
- [barButtonItem setImage:[[iconImage withTintColor:color] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]];
|
141
|
|
- barButtonItem.tintColor = color;
|
142
|
|
- }
|
143
|
|
-
|
144
|
|
- [barButtonItem setTitleTextAttributes:textAttributes forState:UIControlStateNormal];
|
145
|
|
- [barButtonItem setTitleTextAttributes:textAttributes forState:UIControlStateHighlighted];
|
146
|
|
- [barButtonItem setTitleTextAttributes:disabledTextAttributes forState:UIControlStateDisabled];
|
147
|
|
-
|
148
|
|
- NSString *testID = dictionary[@"testID"];
|
149
|
|
- if (testID)
|
150
|
|
- {
|
151
|
|
- barButtonItem.accessibilityIdentifier = testID;
|
152
|
|
- }
|
153
|
|
-
|
154
|
|
- return barButtonItem;
|
|
88
|
+ NSString* buttonId = dictionary[@"id"];
|
|
89
|
+ NSString* title = [self getValue:dictionary[@"text"] withDefault:[defaultStyle.text getWithDefaultValue:nil]];
|
|
90
|
+ NSDictionary* component = dictionary[@"component"];
|
|
91
|
+ NSString* systemItemName = dictionary[@"systemItem"];
|
|
92
|
+
|
|
93
|
+ UIColor* color = [self color:[RCTConvert UIColor:dictionary[@"color"]] defaultColor:[defaultStyle.color getWithDefaultValue:nil]];
|
|
94
|
+ UIColor* disabledColor = [self color:[RCTConvert UIColor:dictionary[@"disabledColor"]] defaultColor:[defaultStyle.disabledColor getWithDefaultValue:nil]];
|
|
95
|
+
|
|
96
|
+ if (!buttonId) {
|
|
97
|
+ @throw [NSException exceptionWithName:@"NSInvalidArgumentException" reason:[@"button id is not specified " stringByAppendingString:title] userInfo:nil];
|
|
98
|
+ }
|
|
99
|
+
|
|
100
|
+ UIImage* defaultIcon = [defaultStyle.icon getWithDefaultValue:nil];
|
|
101
|
+ UIImage* iconImage = [self getValue:dictionary[@"icon"] withDefault:defaultIcon];
|
|
102
|
+ if (![iconImage isKindOfClass:[UIImage class]]) {
|
|
103
|
+ iconImage = [RCTConvert UIImage:iconImage];
|
|
104
|
+ }
|
|
105
|
+
|
|
106
|
+ if (iconImage) {
|
|
107
|
+ iconImage = [iconImage imageWithInsets:insets];
|
|
108
|
+ if (color) {
|
|
109
|
+ iconImage = [iconImage withTintColor:color];
|
|
110
|
+ }
|
|
111
|
+ }
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+ RNNUIBarButtonItem *barButtonItem;
|
|
115
|
+ if (component) {
|
|
116
|
+ RNNComponentOptions* componentOptions = [RNNComponentOptions new];
|
|
117
|
+ componentOptions.componentId = [[Text alloc] initWithValue:component[@"componentId"]];
|
|
118
|
+ componentOptions.name = [[Text alloc] initWithValue:component[@"name"]];
|
|
119
|
+
|
|
120
|
+ RNNReactView *view = [_componentRegistry createComponentIfNotExists:componentOptions parentComponentId:self.viewController.layoutInfo.componentId reactViewReadyBlock:nil];
|
|
121
|
+ barButtonItem = [[RNNUIBarButtonItem alloc] init:buttonId withCustomView:view];
|
|
122
|
+ } else if (iconImage) {
|
|
123
|
+ barButtonItem = [[RNNUIBarButtonItem alloc] init:buttonId withIcon:iconImage];
|
|
124
|
+ } else if (title) {
|
|
125
|
+ barButtonItem = [[RNNUIBarButtonItem alloc] init:buttonId withTitle:title];
|
|
126
|
+
|
|
127
|
+ NSMutableDictionary *buttonTextAttributes = [RCTHelpers textAttributesFromDictionary:dictionary withPrefix:@"button"];
|
|
128
|
+ if (buttonTextAttributes.allKeys.count > 0) {
|
|
129
|
+ [barButtonItem setTitleTextAttributes:buttonTextAttributes forState:UIControlStateNormal];
|
|
130
|
+ }
|
|
131
|
+ } else if (systemItemName) {
|
|
132
|
+ barButtonItem = [[RNNUIBarButtonItem alloc] init:buttonId withSystemItem:systemItemName];
|
|
133
|
+ } else {
|
|
134
|
+ return nil;
|
|
135
|
+ }
|
|
136
|
+
|
|
137
|
+ barButtonItem.target = self.viewController;
|
|
138
|
+ barButtonItem.action = @selector(onButtonPress:);
|
|
139
|
+
|
|
140
|
+ NSNumber *enabled = [self getValue:dictionary[@"enabled"] withDefault:defaultStyle.enabled.getValue];
|
|
141
|
+ BOOL enabledBool = enabled ? [enabled boolValue] : YES;
|
|
142
|
+ [barButtonItem setEnabled:enabledBool];
|
|
143
|
+
|
|
144
|
+ NSMutableDictionary* textAttributes = [NSMutableDictionary dictionaryWithDictionary:[RNNFontAttributesCreator createWithFontFamily:dictionary[@"fontFamily"] ?: [defaultStyle.fontFamily getWithDefaultValue:nil] fontSize:dictionary[@"fontSize"] defaultFontSize:[defaultStyle.fontSize getWithDefaultValue:@(17)] fontWeight:dictionary[@"fontWeight"] color:nil defaultColor:nil]];
|
|
145
|
+ NSMutableDictionary* disabledTextAttributes = [NSMutableDictionary dictionaryWithDictionary:[RNNFontAttributesCreator createWithFontFamily:dictionary[@"fontFamily"] ?: [defaultStyle.fontFamily getWithDefaultValue:nil] fontSize:dictionary[@"fontSize"] defaultFontSize:[defaultStyle.fontSize getWithDefaultValue:@(17)] fontWeight:dictionary[@"fontWeight"] color:nil defaultColor:nil]];
|
|
146
|
+
|
|
147
|
+ if (!enabledBool && disabledColor) {
|
|
148
|
+ color = disabledColor;
|
|
149
|
+ [disabledTextAttributes setObject:disabledColor forKey:NSForegroundColorAttributeName];
|
|
150
|
+ }
|
|
151
|
+
|
|
152
|
+ if (color) {
|
|
153
|
+ [textAttributes setObject:color forKey:NSForegroundColorAttributeName];
|
|
154
|
+ [barButtonItem setImage:[[iconImage withTintColor:color] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]];
|
|
155
|
+ barButtonItem.tintColor = color;
|
|
156
|
+ }
|
|
157
|
+
|
|
158
|
+ [barButtonItem setTitleTextAttributes:textAttributes forState:UIControlStateNormal];
|
|
159
|
+ [barButtonItem setTitleTextAttributes:textAttributes forState:UIControlStateHighlighted];
|
|
160
|
+ [barButtonItem setTitleTextAttributes:disabledTextAttributes forState:UIControlStateDisabled];
|
|
161
|
+
|
|
162
|
+ NSString *testID = dictionary[@"testID"];
|
|
163
|
+ if (testID)
|
|
164
|
+ {
|
|
165
|
+ barButtonItem.accessibilityIdentifier = testID;
|
|
166
|
+ }
|
|
167
|
+
|
|
168
|
+ return barButtonItem;
|
155
|
169
|
}
|
156
|
170
|
|
157
|
171
|
- (UIColor *)color:(UIColor *)color defaultColor:(UIColor *)defaultColor {
|
158
|
|
- if (color) {
|
159
|
|
- return color;
|
160
|
|
- } else if (defaultColor) {
|
161
|
|
- return defaultColor;
|
162
|
|
- }
|
163
|
|
-
|
164
|
|
- return nil;
|
|
172
|
+ if (color) {
|
|
173
|
+ return color;
|
|
174
|
+ } else if (defaultColor) {
|
|
175
|
+ return defaultColor;
|
|
176
|
+ }
|
|
177
|
+
|
|
178
|
+ return nil;
|
165
|
179
|
}
|
166
|
180
|
|
167
|
181
|
- (id)getValue:(id)value withDefault:(id)defaultValue {
|
168
|
|
- return value ? value : defaultValue;
|
|
182
|
+ return value ? value : defaultValue;
|
169
|
183
|
}
|
170
|
184
|
|
171
|
185
|
- (UIEdgeInsets)leftButtonInsets:(RNNInsetsOptions *)defaultInsets {
|
172
|
|
- return UIEdgeInsetsMake([defaultInsets.top getWithDefaultValue:0],
|
173
|
|
- [defaultInsets.left getWithDefaultValue:0],
|
174
|
|
- [defaultInsets.bottom getWithDefaultValue:0],
|
175
|
|
- [defaultInsets.right getWithDefaultValue:15]);
|
|
186
|
+ return UIEdgeInsetsMake([defaultInsets.top getWithDefaultValue:0],
|
|
187
|
+ [defaultInsets.left getWithDefaultValue:0],
|
|
188
|
+ [defaultInsets.bottom getWithDefaultValue:0],
|
|
189
|
+ [defaultInsets.right getWithDefaultValue:15]);
|
176
|
190
|
}
|
177
|
191
|
|
178
|
192
|
- (UIEdgeInsets)rightButtonInsets:(RNNInsetsOptions *)defaultInsets {
|
179
|
|
- return UIEdgeInsetsMake([defaultInsets.top getWithDefaultValue:0],
|
180
|
|
- [defaultInsets.left getWithDefaultValue:15],
|
181
|
|
- [defaultInsets.bottom getWithDefaultValue:0],
|
182
|
|
- [defaultInsets.right getWithDefaultValue:0]);
|
|
193
|
+ return UIEdgeInsetsMake([defaultInsets.top getWithDefaultValue:0],
|
|
194
|
+ [defaultInsets.left getWithDefaultValue:15],
|
|
195
|
+ [defaultInsets.bottom getWithDefaultValue:0],
|
|
196
|
+ [defaultInsets.right getWithDefaultValue:0]);
|
183
|
197
|
}
|
184
|
198
|
|
185
|
199
|
@end
|