Przeglądaj źródła

Move all topBar.title options to topBarTitlePresenter (#5883)

Fix TopBar title animation. This commit changes how RNN handles title and subtitle.
Until now, RNN created a custom view for title and subtitle which interfered with the way the system animated the TopBar title.
With this commit the custom view is created only when both subtitle and title are declared, otherwise RNN uses the system behavior.
Yogev Ben David 5 lat temu
rodzic
commit
c5bd577b41
No account linked to committer's email address

+ 6
- 1
lib/ios/RNNBasePresenter.h Wyświetl plik

1
 #import "RNNNavigationOptions.h"
1
 #import "RNNNavigationOptions.h"
2
+#import "RNNReactComponentRegistry.h"
2
 
3
 
3
 typedef void (^RNNReactViewReadyCompletionBlock)(void);
4
 typedef void (^RNNReactViewReadyCompletionBlock)(void);
4
 
5
 
8
 
9
 
9
 @property(nonatomic, strong) NSString *boundComponentId;
10
 @property(nonatomic, strong) NSString *boundComponentId;
10
 
11
 
11
-@property(nonatomic, strong) RNNNavigationOptions * defaultOptions;
12
+@property(nonatomic, strong) RNNNavigationOptions* defaultOptions;
13
+
14
+@property(nonatomic, strong) RNNReactComponentRegistry* componentRegistry;
12
 
15
 
13
 - (instancetype)initWithDefaultOptions:(RNNNavigationOptions *)defaultOptions;
16
 - (instancetype)initWithDefaultOptions:(RNNNavigationOptions *)defaultOptions;
14
 
17
 
18
+- (instancetype)initWithComponentRegistry:(RNNReactComponentRegistry *)componentRegistry defaultOptions:(RNNNavigationOptions *)defaultOptions;
19
+
15
 - (void)setDefaultOptions:(RNNNavigationOptions *)defaultOptions;
20
 - (void)setDefaultOptions:(RNNNavigationOptions *)defaultOptions;
16
 
21
 
17
 - (void)applyOptionsOnInit:(RNNNavigationOptions *)initialOptions;
22
 - (void)applyOptionsOnInit:(RNNNavigationOptions *)initialOptions;

+ 7
- 1
lib/ios/RNNBasePresenter.m Wyświetl plik

12
 @end
12
 @end
13
 @implementation RNNBasePresenter
13
 @implementation RNNBasePresenter
14
 
14
 
15
--(instancetype)initWithDefaultOptions:(RNNNavigationOptions *)defaultOptions {
15
+- (instancetype)initWithDefaultOptions:(RNNNavigationOptions *)defaultOptions {
16
     self = [super init];
16
     self = [super init];
17
     _defaultOptions = defaultOptions;
17
     _defaultOptions = defaultOptions;
18
     self.dotIndicatorPresenter = [[RNNDotIndicatorPresenter alloc] initWithDefaultOptions:_defaultOptions];
18
     self.dotIndicatorPresenter = [[RNNDotIndicatorPresenter alloc] initWithDefaultOptions:_defaultOptions];
19
     return self;
19
     return self;
20
 }
20
 }
21
 
21
 
22
+- (instancetype)initWithComponentRegistry:(RNNReactComponentRegistry *)componentRegistry defaultOptions:(RNNNavigationOptions *)defaultOptions {
23
+    self = [self initWithDefaultOptions:defaultOptions];
24
+    _componentRegistry = componentRegistry;
25
+    return self;
26
+}
27
+
22
 - (void)bindViewController:(UIViewController *)boundViewController {
28
 - (void)bindViewController:(UIViewController *)boundViewController {
23
     self.boundComponentId = boundViewController.layoutInfo.componentId;
29
     self.boundComponentId = boundViewController.layoutInfo.componentId;
24
     _boundViewController = boundViewController;
30
     _boundViewController = boundViewController;

+ 0
- 2
lib/ios/RNNComponentPresenter.h Wyświetl plik

4
 
4
 
5
 @interface RNNComponentPresenter : RNNBasePresenter
5
 @interface RNNComponentPresenter : RNNBasePresenter
6
 
6
 
7
-- (instancetype)initWithComponentRegistry:(RNNReactComponentRegistry *)componentRegistry:(RNNNavigationOptions *)defaultOptions;
8
-
9
 - (void)renderComponents:(RNNNavigationOptions *)options perform:(RNNReactViewReadyCompletionBlock)readyBlock;
7
 - (void)renderComponents:(RNNNavigationOptions *)options perform:(RNNReactViewReadyCompletionBlock)readyBlock;
10
 
8
 
11
 @property (nonatomic, strong) RNNNavigationButtons* navigationButtons;
9
 @property (nonatomic, strong) RNNNavigationButtons* navigationButtons;

+ 17
- 77
lib/ios/RNNComponentPresenter.m Wyświetl plik

5
 #import "RNNTitleViewHelper.h"
5
 #import "RNNTitleViewHelper.h"
6
 #import "UIViewController+LayoutProtocol.h"
6
 #import "UIViewController+LayoutProtocol.h"
7
 #import "RNNReactTitleView.h"
7
 #import "RNNReactTitleView.h"
8
+#import "TopBarTitlePresenter.h"
8
 
9
 
9
-@interface RNNComponentPresenter() {
10
-	RNNReactTitleView* _customTitleView;
11
-	RNNTitleViewHelper* _titleViewHelper;
12
-	RNNReactComponentRegistry* _componentRegistry;
13
-}
14
-
15
-@end
16
 
10
 
17
-@implementation RNNComponentPresenter
11
+@implementation RNNComponentPresenter {
12
+    TopBarTitlePresenter* _topBarTitlePresenter;
13
+}
18
 
14
 
19
-- (instancetype)initWithComponentRegistry:(RNNReactComponentRegistry *)componentRegistry:(RNNNavigationOptions *)defaultOptions {
20
-	self = [self initWithDefaultOptions:defaultOptions];
21
-	_componentRegistry = componentRegistry;
15
+- (instancetype)initWithComponentRegistry:(RNNReactComponentRegistry *)componentRegistry defaultOptions:(RNNNavigationOptions *)defaultOptions {
16
+	self = [super initWithComponentRegistry:componentRegistry defaultOptions:defaultOptions];
17
+	_topBarTitlePresenter = [[TopBarTitlePresenter alloc] initWithComponentRegistry:componentRegistry defaultOptions:defaultOptions];
22
 	return self;
18
 	return self;
23
 }
19
 }
24
 
20
 
25
 - (void)bindViewController:(id)boundViewController {
21
 - (void)bindViewController:(id)boundViewController {
26
 	[super bindViewController:boundViewController];
22
 	[super bindViewController:boundViewController];
27
-	_navigationButtons = [[RNNNavigationButtons alloc] initWithViewController:self.boundViewController componentRegistry:_componentRegistry];
23
+	[_topBarTitlePresenter bindViewController:boundViewController];
24
+	_navigationButtons = [[RNNNavigationButtons alloc] initWithViewController:boundViewController componentRegistry:self.componentRegistry];
28
 }
25
 }
29
 
26
 
30
 - (void)componentDidAppear {
27
 - (void)componentDidAppear {
32
     if ([component respondsToSelector:@selector(componentDidAppear)]) {
29
     if ([component respondsToSelector:@selector(componentDidAppear)]) {
33
         [component componentDidAppear];
30
         [component componentDidAppear];
34
     }
31
     }
35
-    [_customTitleView componentDidAppear];
32
+    [_topBarTitlePresenter componentDidAppear];
36
     [_navigationButtons componentDidAppear];
33
     [_navigationButtons componentDidAppear];
37
 }
34
 }
38
 
35
 
42
         [component componentDidDisappear];
39
         [component componentDidDisappear];
43
     }
40
     }
44
     
41
     
45
-    [_customTitleView componentDidDisappear];
42
+    [_topBarTitlePresenter componentDidDisappear];
46
     [_navigationButtons componentDidDisappear];
43
     [_navigationButtons componentDidDisappear];
47
 }
44
 }
48
 
45
 
56
 	UIViewController* viewController = self.boundViewController;
53
 	UIViewController* viewController = self.boundViewController;
57
 	RNNNavigationOptions *withDefault = [options withDefault:[self defaultOptions]];
54
 	RNNNavigationOptions *withDefault = [options withDefault:[self defaultOptions]];
58
 	[viewController setBackgroundImage:[withDefault.backgroundImage getWithDefaultValue:nil]];
55
 	[viewController setBackgroundImage:[withDefault.backgroundImage getWithDefaultValue:nil]];
59
-	[viewController setNavigationItemTitle:[withDefault.topBar.title.text getWithDefaultValue:nil]];
60
 	[viewController setTopBarPrefersLargeTitle:[withDefault.topBar.largeTitle.visible getWithDefaultValue:NO]];
56
 	[viewController setTopBarPrefersLargeTitle:[withDefault.topBar.largeTitle.visible getWithDefaultValue:NO]];
61
 	[viewController setTabBarItemBadgeColor:[withDefault.bottomTab.badgeColor getWithDefaultValue:nil]];
57
 	[viewController setTabBarItemBadgeColor:[withDefault.bottomTab.badgeColor getWithDefaultValue:nil]];
62
 	[viewController setStatusBarBlur:[withDefault.statusBar.blur getWithDefaultValue:NO]];
58
 	[viewController setStatusBarBlur:[withDefault.statusBar.blur getWithDefaultValue:NO]];
75
 		}
71
 		}
76
 		[viewController setSearchBarWithPlaceholder:[withDefault.topBar.searchBarPlaceholder getWithDefaultValue:@""] hideNavBarOnFocusSearchBar:hideNavBarOnFocusSearchBar];
72
 		[viewController setSearchBarWithPlaceholder:[withDefault.topBar.searchBarPlaceholder getWithDefaultValue:@""] hideNavBarOnFocusSearchBar:hideNavBarOnFocusSearchBar];
77
 	}
73
 	}
78
-
79
-	[self setTitleViewWithSubtitle:withDefault];
74
+	
75
+	[_topBarTitlePresenter applyOptions:withDefault.topBar];
80
 }
76
 }
81
 
77
 
82
 - (void)applyOptionsOnInit:(RNNNavigationOptions *)options {
78
 - (void)applyOptionsOnInit:(RNNNavigationOptions *)options {
96
     [super mergeOptions:options resolvedOptions:currentOptions];
92
     [super mergeOptions:options resolvedOptions:currentOptions];
97
 	RNNNavigationOptions * withDefault	= (RNNNavigationOptions *) [[currentOptions overrideOptions:options] withDefault:[self defaultOptions]];
93
 	RNNNavigationOptions * withDefault	= (RNNNavigationOptions *) [[currentOptions overrideOptions:options] withDefault:[self defaultOptions]];
98
 	UIViewController* viewController = self.boundViewController;
94
 	UIViewController* viewController = self.boundViewController;
99
-	[self removeTitleComponentIfNeeded:options];
100
 
95
 
101
 	if (options.backgroundImage.hasValue) {
96
 	if (options.backgroundImage.hasValue) {
102
 		[viewController setBackgroundImage:options.backgroundImage.get];
97
 		[viewController setBackgroundImage:options.backgroundImage.get];
122
 		[viewController setDrawBehindTopBar:options.topBar.drawBehind.get];
117
 		[viewController setDrawBehindTopBar:options.topBar.drawBehind.get];
123
 	}
118
 	}
124
 	
119
 	
125
-	if (options.topBar.title.text.hasValue) {
126
-		[viewController setNavigationItemTitle:options.topBar.title.text.get];
127
-	}
128
-	
129
 	if (options.topBar.largeTitle.visible.hasValue) {
120
 	if (options.topBar.largeTitle.visible.hasValue) {
130
 		[viewController setTopBarPrefersLargeTitle:options.topBar.largeTitle.visible.get];
121
 		[viewController setTopBarPrefersLargeTitle:options.topBar.largeTitle.visible.get];
131
 	}
122
 	}
167
 		RCTRootView* rootView = (RCTRootView*)viewController.view;
158
 		RCTRootView* rootView = (RCTRootView*)viewController.view;
168
 		rootView.passThroughTouches = !options.overlay.interceptTouchOutside.get;
159
 		rootView.passThroughTouches = !options.overlay.interceptTouchOutside.get;
169
 	}
160
 	}
170
-
171
-	if (options.topBar.title.component.name.hasValue) {
172
-		[self setCustomNavigationTitleView:options perform:nil];
173
-	}
174
-
175
-	[self setTitleViewWithSubtitle:withDefault];
176
-}
177
-
178
-- (void)removeTitleComponentIfNeeded:(RNNNavigationOptions *)options {
179
-	if (options.topBar.title.text.hasValue) {
180
-        [_customTitleView componentDidDisappear];
181
-		[_customTitleView removeFromSuperview];
182
-		_customTitleView = nil;
183
-	}
161
+	
162
+	[_topBarTitlePresenter mergeOptions:options.topBar resolvedOptions:currentOptions.topBar];
184
 }
163
 }
185
 
164
 
186
 - (void)renderComponents:(RNNNavigationOptions *)options perform:(RNNReactViewReadyCompletionBlock)readyBlock {
165
 - (void)renderComponents:(RNNNavigationOptions *)options perform:(RNNReactViewReadyCompletionBlock)readyBlock {
187
     RNNNavigationOptions *withDefault = [options withDefault:[self defaultOptions]];
166
     RNNNavigationOptions *withDefault = [options withDefault:[self defaultOptions]];
188
-	[self setCustomNavigationTitleView:withDefault perform:readyBlock];
189
-}
190
-
191
-- (void)setCustomNavigationTitleView:(RNNNavigationOptions *)options perform:(RNNReactViewReadyCompletionBlock)readyBlock {
192
-	UIViewController<RNNLayoutProtocol>* viewController = self.boundViewController;
193
-	if (![options.topBar.title.component.waitForRender getWithDefaultValue:NO] && readyBlock) {
194
-		readyBlock();
195
-		readyBlock = nil;
196
-	}
197
-	
198
-	if (options.topBar.title.component.name.hasValue) {
199
-        _customTitleView = (RNNReactTitleView *)[_componentRegistry createComponentIfNotExists:options.topBar.title.component parentComponentId:viewController.layoutInfo.componentId componentType:RNNComponentTypeTopBarTitle reactViewReadyBlock:readyBlock];
200
-		_customTitleView.backgroundColor = UIColor.clearColor;
201
-		NSString* alignment = [options.topBar.title.component.alignment getWithDefaultValue:@""];
202
-		[_customTitleView setAlignment:alignment inFrame:viewController.navigationController.navigationBar.frame];
203
-		[_customTitleView layoutIfNeeded];
204
-		
205
-		viewController.navigationItem.titleView = nil;
206
-		viewController.navigationItem.titleView = _customTitleView;
207
-        [_customTitleView componentDidAppear];
208
-	} else {
209
-		[_customTitleView removeFromSuperview];
210
-		if (readyBlock) {
211
-			readyBlock();
212
-		}
213
-	}
167
+    [_topBarTitlePresenter renderComponents:withDefault.topBar perform:readyBlock];
214
 }
168
 }
215
 
169
 
216
-- (void)setTitleViewWithSubtitle:(RNNNavigationOptions *)options {
217
-	if (!_customTitleView && ![options.topBar.largeTitle.visible getWithDefaultValue:NO]) {
218
-		_titleViewHelper = [[RNNTitleViewHelper alloc] initWithTitleViewOptions:options.topBar.title subTitleOptions:options.topBar.subtitle viewController:self.boundViewController];
219
-
220
-		if (options.topBar.title.text.hasValue) {
221
-			[_titleViewHelper setTitleOptions:options.topBar.title];
222
-		}
223
-		if (options.topBar.subtitle.text.hasValue) {
224
-			[_titleViewHelper setSubtitleOptions:options.topBar.subtitle];
225
-		}
226
-
227
-		[_titleViewHelper setup];
228
-	}
229
-}
230
 
170
 
231
 - (void)dealloc {
171
 - (void)dealloc {
232
-	[_componentRegistry clearComponentsForParentId:self.boundComponentId];
172
+	[self.componentRegistry clearComponentsForParentId:self.boundComponentId];
233
 }
173
 }
234
 @end
174
 @end

+ 2
- 2
lib/ios/RNNControllerFactory.m Wyświetl plik

114
 - (UIViewController *)createComponent:(RNNLayoutNode*)node {
114
 - (UIViewController *)createComponent:(RNNLayoutNode*)node {
115
 	RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] initWithNode:node];
115
 	RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] initWithNode:node];
116
 	RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:node.data[@"options"]];;
116
 	RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:node.data[@"options"]];;
117
-	RNNComponentPresenter* presenter = [[RNNComponentPresenter alloc] initWithComponentRegistry:_componentRegistry:_defaultOptions];
117
+	RNNComponentPresenter* presenter = [[RNNComponentPresenter alloc] initWithComponentRegistry:_componentRegistry defaultOptions:_defaultOptions];
118
 	
118
 	
119
 	RNNComponentViewController* component = [[RNNComponentViewController alloc] initWithLayoutInfo:layoutInfo rootViewCreator:_creator eventEmitter:_eventEmitter presenter:presenter options:options defaultOptions:_defaultOptions];
119
 	RNNComponentViewController* component = [[RNNComponentViewController alloc] initWithLayoutInfo:layoutInfo rootViewCreator:_creator eventEmitter:_eventEmitter presenter:presenter options:options defaultOptions:_defaultOptions];
120
 	
120
 	
193
 	RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] initWithNode:node];
193
 	RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] initWithNode:node];
194
 	RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:node.data[@"options"]];
194
 	RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:node.data[@"options"]];
195
 
195
 
196
-	RNNSideMenuChildVC *sideMenuChild = [[RNNSideMenuChildVC alloc] initWithLayoutInfo:layoutInfo creator:_creator options:options defaultOptions:_defaultOptions presenter:[[RNNComponentPresenter alloc] initWithComponentRegistry:_componentRegistry:_defaultOptions] eventEmitter:_eventEmitter childViewController:childVc type:type];
196
+	RNNSideMenuChildVC *sideMenuChild = [[RNNSideMenuChildVC alloc] initWithLayoutInfo:layoutInfo creator:_creator options:options defaultOptions:_defaultOptions presenter:[[RNNComponentPresenter alloc] initWithComponentRegistry:_componentRegistry defaultOptions:_defaultOptions] eventEmitter:_eventEmitter childViewController:childVc type:type];
197
 	
197
 	
198
 	return sideMenuChild;
198
 	return sideMenuChild;
199
 }
199
 }

+ 14
- 6
lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj Wyświetl plik

184
 		50570BEA2063E09B006A1B5C /* RNNTitleViewHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 50570BE82063E09B006A1B5C /* RNNTitleViewHelper.h */; };
184
 		50570BEA2063E09B006A1B5C /* RNNTitleViewHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 50570BE82063E09B006A1B5C /* RNNTitleViewHelper.h */; };
185
 		50570BEB2063E09B006A1B5C /* RNNTitleViewHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 50570BE92063E09B006A1B5C /* RNNTitleViewHelper.m */; };
185
 		50570BEB2063E09B006A1B5C /* RNNTitleViewHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 50570BE92063E09B006A1B5C /* RNNTitleViewHelper.m */; };
186
 		505963F722676A0000EBB63C /* RNNLayoutManagerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 505963F622676A0000EBB63C /* RNNLayoutManagerTest.m */; };
186
 		505963F722676A0000EBB63C /* RNNLayoutManagerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 505963F622676A0000EBB63C /* RNNLayoutManagerTest.m */; };
187
+		505C640223E074860078AFC0 /* TopBarTitlePresenter.h in Headers */ = {isa = PBXBuildFile; fileRef = 505C640023E074860078AFC0 /* TopBarTitlePresenter.h */; };
188
+		505C640323E074860078AFC0 /* TopBarTitlePresenter.m in Sources */ = {isa = PBXBuildFile; fileRef = 505C640123E074860078AFC0 /* TopBarTitlePresenter.m */; };
187
 		505EDD32214E4BE80071C7DE /* RNNNavigationControllerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 505EDD31214E4BE80071C7DE /* RNNNavigationControllerTest.m */; };
189
 		505EDD32214E4BE80071C7DE /* RNNNavigationControllerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 505EDD31214E4BE80071C7DE /* RNNNavigationControllerTest.m */; };
188
 		505EDD34214E7B7B0071C7DE /* RNNLeafProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 505EDD33214E7A6A0071C7DE /* RNNLeafProtocol.h */; };
190
 		505EDD34214E7B7B0071C7DE /* RNNLeafProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 505EDD33214E7A6A0071C7DE /* RNNLeafProtocol.h */; };
189
 		505EDD3C214FA8000071C7DE /* RNNComponentPresenter.h in Headers */ = {isa = PBXBuildFile; fileRef = 505EDD3A214FA8000071C7DE /* RNNComponentPresenter.h */; };
191
 		505EDD3C214FA8000071C7DE /* RNNComponentPresenter.h in Headers */ = {isa = PBXBuildFile; fileRef = 505EDD3A214FA8000071C7DE /* RNNComponentPresenter.h */; };
572
 		50570BE82063E09B006A1B5C /* RNNTitleViewHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNTitleViewHelper.h; sourceTree = "<group>"; };
574
 		50570BE82063E09B006A1B5C /* RNNTitleViewHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNTitleViewHelper.h; sourceTree = "<group>"; };
573
 		50570BE92063E09B006A1B5C /* RNNTitleViewHelper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNTitleViewHelper.m; sourceTree = "<group>"; };
575
 		50570BE92063E09B006A1B5C /* RNNTitleViewHelper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNTitleViewHelper.m; sourceTree = "<group>"; };
574
 		505963F622676A0000EBB63C /* RNNLayoutManagerTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNLayoutManagerTest.m; sourceTree = "<group>"; };
576
 		505963F622676A0000EBB63C /* RNNLayoutManagerTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNLayoutManagerTest.m; sourceTree = "<group>"; };
577
+		505C640023E074860078AFC0 /* TopBarTitlePresenter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TopBarTitlePresenter.h; sourceTree = "<group>"; };
578
+		505C640123E074860078AFC0 /* TopBarTitlePresenter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TopBarTitlePresenter.m; sourceTree = "<group>"; };
575
 		505EDD31214E4BE80071C7DE /* RNNNavigationControllerTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNNavigationControllerTest.m; sourceTree = "<group>"; };
579
 		505EDD31214E4BE80071C7DE /* RNNNavigationControllerTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNNavigationControllerTest.m; sourceTree = "<group>"; };
576
 		505EDD33214E7A6A0071C7DE /* RNNLeafProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNLeafProtocol.h; sourceTree = "<group>"; };
580
 		505EDD33214E7A6A0071C7DE /* RNNLeafProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNLeafProtocol.h; sourceTree = "<group>"; };
577
 		505EDD3A214FA8000071C7DE /* RNNComponentPresenter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNComponentPresenter.h; sourceTree = "<group>"; };
581
 		505EDD3A214FA8000071C7DE /* RNNComponentPresenter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNComponentPresenter.h; sourceTree = "<group>"; };
1086
 				651E1F8C21FD642100DFEA19 /* RNNSplitViewControllerPresenter.m */,
1090
 				651E1F8C21FD642100DFEA19 /* RNNSplitViewControllerPresenter.m */,
1087
 				30987E66AA7AB38E7370F8C8 /* RNNDotIndicatorPresenter.m */,
1091
 				30987E66AA7AB38E7370F8C8 /* RNNDotIndicatorPresenter.m */,
1088
 				309878B02F15ECDD1A286722 /* RNNDotIndicatorPresenter.h */,
1092
 				309878B02F15ECDD1A286722 /* RNNDotIndicatorPresenter.h */,
1093
+				50CED447239EA56100C42EE2 /* TopBarPresenterCreator.h */,
1094
+				50CED448239EA56100C42EE2 /* TopBarPresenterCreator.m */,
1095
+				50CED44B239EA78700C42EE2 /* TopBarAppearancePresenter.h */,
1096
+				50CED44C239EA78700C42EE2 /* TopBarAppearancePresenter.m */,
1097
+				50CED44F239F9DFC00C42EE2 /* TopBarPresenter.h */,
1098
+				50CED450239F9DFC00C42EE2 /* TopBarPresenter.m */,
1099
+				505C640023E074860078AFC0 /* TopBarTitlePresenter.h */,
1100
+				505C640123E074860078AFC0 /* TopBarTitlePresenter.m */,
1089
 			);
1101
 			);
1090
 			name = Presenters;
1102
 			name = Presenters;
1091
 			sourceTree = "<group>";
1103
 			sourceTree = "<group>";
1143
 				50570BE92063E09B006A1B5C /* RNNTitleViewHelper.m */,
1155
 				50570BE92063E09B006A1B5C /* RNNTitleViewHelper.m */,
1144
 				501CD31D214A5B6900A6E225 /* RNNLayoutInfo.h */,
1156
 				501CD31D214A5B6900A6E225 /* RNNLayoutInfo.h */,
1145
 				501CD31E214A5B6900A6E225 /* RNNLayoutInfo.m */,
1157
 				501CD31E214A5B6900A6E225 /* RNNLayoutInfo.m */,
1146
-				50CED447239EA56100C42EE2 /* TopBarPresenterCreator.h */,
1147
-				50CED448239EA56100C42EE2 /* TopBarPresenterCreator.m */,
1148
-				50CED44B239EA78700C42EE2 /* TopBarAppearancePresenter.h */,
1149
-				50CED44C239EA78700C42EE2 /* TopBarAppearancePresenter.m */,
1150
-				50CED44F239F9DFC00C42EE2 /* TopBarPresenter.h */,
1151
-				50CED450239F9DFC00C42EE2 /* TopBarPresenter.m */,
1152
 				501E0215213E7EA3003365C5 /* RNNReactView.h */,
1158
 				501E0215213E7EA3003365C5 /* RNNReactView.h */,
1153
 				501E0216213E7EA3003365C5 /* RNNReactView.m */,
1159
 				501E0216213E7EA3003365C5 /* RNNReactView.m */,
1154
 				503A8A1723BCB2ED0094D1C4 /* RNNReactButtonView.h */,
1160
 				503A8A1723BCB2ED0094D1C4 /* RNNReactButtonView.h */,
1466
 				5049593E216F5D73006D2B81 /* BoolParser.h in Headers */,
1472
 				5049593E216F5D73006D2B81 /* BoolParser.h in Headers */,
1467
 				E5F6C3A522DB4D0F0093C2CE /* UIViewController+Utils.h in Headers */,
1473
 				E5F6C3A522DB4D0F0093C2CE /* UIViewController+Utils.h in Headers */,
1468
 				50C4A496206BDDBB00DB292E /* RNNSubtitleOptions.h in Headers */,
1474
 				50C4A496206BDDBB00DB292E /* RNNSubtitleOptions.h in Headers */,
1475
+				505C640223E074860078AFC0 /* TopBarTitlePresenter.h in Headers */,
1469
 				5039559B2174867000B0A663 /* DoubleParser.h in Headers */,
1476
 				5039559B2174867000B0A663 /* DoubleParser.h in Headers */,
1470
 				E8AEDB3C1F55A1C2000F5A6A /* RNNElementView.h in Headers */,
1477
 				E8AEDB3C1F55A1C2000F5A6A /* RNNElementView.h in Headers */,
1471
 				E8E518321F83B3E0000467AC /* RNNUtils.h in Headers */,
1478
 				E8E518321F83B3E0000467AC /* RNNUtils.h in Headers */,
1730
 				50395594217485B000B0A663 /* Double.m in Sources */,
1737
 				50395594217485B000B0A663 /* Double.m in Sources */,
1731
 				504AFE751FFFF0540076E904 /* RNNTopTabsOptions.m in Sources */,
1738
 				504AFE751FFFF0540076E904 /* RNNTopTabsOptions.m in Sources */,
1732
 				50175CD2207A2AA1004FE91B /* RNNComponentOptions.m in Sources */,
1739
 				50175CD2207A2AA1004FE91B /* RNNComponentOptions.m in Sources */,
1740
+				505C640323E074860078AFC0 /* TopBarTitlePresenter.m in Sources */,
1733
 				50E02BDC21A6EE7900A43942 /* SideMenuOpenGestureModeParser.m in Sources */,
1741
 				50E02BDC21A6EE7900A43942 /* SideMenuOpenGestureModeParser.m in Sources */,
1734
 				7BEF0D1D1E43771B003E96B0 /* RNNLayoutNode.m in Sources */,
1742
 				7BEF0D1D1E43771B003E96B0 /* RNNLayoutNode.m in Sources */,
1735
 				7BA500781E254908001B9E1B /* RNNSplashScreen.m in Sources */,
1743
 				7BA500781E254908001B9E1B /* RNNSplashScreen.m in Sources */,

+ 13
- 0
lib/ios/TopBarTitlePresenter.h Wyświetl plik

1
+#import <Foundation/Foundation.h>
2
+#import "RNNNavigationOptions.h"
3
+#import "UIViewController+LayoutProtocol.h"
4
+
5
+@interface TopBarTitlePresenter : RNNBasePresenter
6
+
7
+- (void)applyOptions:(RNNTopBarOptions *)options;
8
+
9
+- (void)mergeOptions:(RNNTopBarOptions *)options resolvedOptions:(RNNTopBarOptions *)resolvedOptions;
10
+
11
+- (void)setCustomNavigationTitleView:(RNNTopBarOptions *)options perform:(RNNReactViewReadyCompletionBlock)readyBlock;
12
+
13
+@end

+ 89
- 0
lib/ios/TopBarTitlePresenter.m Wyświetl plik

1
+#import "TopBarTitlePresenter.h"
2
+#import "UIViewController+RNNOptions.h"
3
+#import "RNNTitleViewHelper.h"
4
+#import "RNNReactTitleView.h"
5
+
6
+@implementation TopBarTitlePresenter {
7
+    RNNReactTitleView* _customTitleView;
8
+    RNNTitleViewHelper* _titleViewHelper;
9
+}
10
+
11
+- (void)applyOptions:(RNNTopBarOptions *)options {
12
+	[self updateTitleWithOptions:options];
13
+}
14
+
15
+- (void)updateTitleWithOptions:(RNNTopBarOptions *)options {
16
+    if (options.title.component.hasValue) {
17
+        [self setCustomNavigationTitleView:options perform:nil];
18
+    }else if (options.subtitle.text.hasValue) {
19
+        [self setTitleViewWithSubtitle:options];
20
+    }else if (options.title.text.hasValue) {
21
+        [self removeTitleComponents];
22
+        self.boundViewController.navigationItem.title = options.title.text.get;
23
+    }
24
+}
25
+
26
+- (void)mergeOptions:(RNNTopBarOptions *)options resolvedOptions:(RNNTopBarOptions *)resolvedOptions {
27
+    [self updateTitleWithOptions:options];
28
+}
29
+
30
+- (void)setTitleViewWithSubtitle:(RNNTopBarOptions *)options {
31
+	if (!_customTitleView && ![options.largeTitle.visible getWithDefaultValue:NO]) {
32
+		_titleViewHelper = [[RNNTitleViewHelper alloc] initWithTitleViewOptions:options.title subTitleOptions:options.subtitle viewController:self.boundViewController];
33
+
34
+		if (options.title.text.hasValue) {
35
+			[_titleViewHelper setTitleOptions:options.title];
36
+		}
37
+		if (options.subtitle.text.hasValue) {
38
+			[_titleViewHelper setSubtitleOptions:options.subtitle];
39
+		}
40
+
41
+		[_titleViewHelper setup];
42
+	}
43
+}
44
+
45
+- (void)renderComponents:(RNNTopBarOptions *)options perform:(RNNReactViewReadyCompletionBlock)readyBlock {
46
+    [self setCustomNavigationTitleView:options perform:readyBlock];
47
+}
48
+
49
+- (void)setCustomNavigationTitleView:(RNNTopBarOptions *)options perform:(RNNReactViewReadyCompletionBlock)readyBlock {
50
+    UIViewController<RNNLayoutProtocol>* viewController = self.boundViewController;
51
+    if (![options.title.component.waitForRender getWithDefaultValue:NO] && readyBlock) {
52
+        readyBlock();
53
+        readyBlock = nil;
54
+    }
55
+    
56
+    if (options.title.component.name.hasValue) {
57
+        _customTitleView = (RNNReactTitleView *)[self.componentRegistry createComponentIfNotExists:options.title.component parentComponentId:viewController.layoutInfo.componentId componentType:RNNComponentTypeTopBarTitle reactViewReadyBlock:readyBlock];
58
+        _customTitleView.backgroundColor = UIColor.clearColor;
59
+        NSString* alignment = [options.title.component.alignment getWithDefaultValue:@""];
60
+        [_customTitleView setAlignment:alignment inFrame:viewController.navigationController.navigationBar.frame];
61
+        [_customTitleView layoutIfNeeded];
62
+        
63
+        viewController.navigationItem.titleView = nil;
64
+        viewController.navigationItem.titleView = _customTitleView;
65
+        [_customTitleView componentDidAppear];
66
+    } else {
67
+        [_customTitleView removeFromSuperview];
68
+        if (readyBlock) {
69
+            readyBlock();
70
+        }
71
+    }
72
+}
73
+
74
+- (void)removeTitleComponents {
75
+    [_customTitleView componentDidDisappear];
76
+    [_customTitleView removeFromSuperview];
77
+    _customTitleView = nil;
78
+    self.boundViewController.navigationItem.titleView = nil;
79
+}
80
+
81
+- (void)componentDidAppear {
82
+    [_customTitleView componentDidAppear];
83
+}
84
+
85
+- (void)componentDidDisappear {
86
+    [_customTitleView componentDidDisappear];
87
+}
88
+
89
+@end

+ 1
- 1
playground/ios/NavigationIOS12Tests/RNNRootViewControllerTest.m Wyświetl plik

49
 	layoutInfo.componentId = self.componentId;
49
 	layoutInfo.componentId = self.componentId;
50
 	layoutInfo.name = self.pageName;
50
 	layoutInfo.name = self.pageName;
51
 	
51
 	
52
-	id presenter = [OCMockObject partialMockForObject:[[RNNComponentPresenter alloc] init]];
52
+	id presenter = [OCMockObject partialMockForObject:[[RNNComponentPresenter alloc] initWithComponentRegistry:nil defaultOptions:nil]];
53
 	self.uut = [[RNNComponentViewController alloc] initWithLayoutInfo:layoutInfo rootViewCreator:self.creator eventEmitter:self.emitter presenter:presenter options:self.options defaultOptions:nil];
53
 	self.uut = [[RNNComponentViewController alloc] initWithLayoutInfo:layoutInfo rootViewCreator:self.creator eventEmitter:self.emitter presenter:presenter options:self.options defaultOptions:nil];
54
 }
54
 }
55
 
55
 

+ 2
- 2
playground/ios/NavigationTests/RNNCommandsHandlerTest.m Wyświetl plik

131
 	RNNLayoutInfo* layoutInfo = [RNNLayoutInfo new];
131
 	RNNLayoutInfo* layoutInfo = [RNNLayoutInfo new];
132
 	RNNTestRootViewCreator* creator = [[RNNTestRootViewCreator alloc] init];
132
 	RNNTestRootViewCreator* creator = [[RNNTestRootViewCreator alloc] init];
133
 	
133
 	
134
-	RNNComponentPresenter* presenter = [[RNNComponentPresenter alloc] init];
134
+	RNNComponentPresenter* presenter = [[RNNComponentPresenter alloc] initWithComponentRegistry:nil defaultOptions:nil];
135
 	RNNComponentViewController* vc = [[RNNComponentViewController alloc] initWithLayoutInfo:layoutInfo rootViewCreator:creator eventEmitter:nil presenter:presenter options:initialOptions defaultOptions:nil];
135
 	RNNComponentViewController* vc = [[RNNComponentViewController alloc] initWithLayoutInfo:layoutInfo rootViewCreator:creator eventEmitter:nil presenter:presenter options:initialOptions defaultOptions:nil];
136
 	
136
 	
137
 	RNNStackController* nav = [[RNNStackController alloc] initWithLayoutInfo:nil creator:creator options:[[RNNNavigationOptions alloc] initEmptyOptions] defaultOptions:nil presenter:[[RNNStackPresenter alloc] init] eventEmitter:nil childViewControllers:@[vc]];
137
 	RNNStackController* nav = [[RNNStackController alloc] initWithLayoutInfo:nil creator:creator options:[[RNNNavigationOptions alloc] initEmptyOptions] defaultOptions:nil presenter:[[RNNStackPresenter alloc] init] eventEmitter:nil childViewControllers:@[vc]];
154
 	RNNNavigationOptions* initialOptions = [[RNNNavigationOptions alloc] initWithDict:@{}];
154
 	RNNNavigationOptions* initialOptions = [[RNNNavigationOptions alloc] initWithDict:@{}];
155
 	initialOptions.topBar.title.text = [[Text alloc] initWithValue:@"the title"];
155
 	initialOptions.topBar.title.text = [[Text alloc] initWithValue:@"the title"];
156
 	
156
 	
157
-	RNNComponentPresenter* presenter = [[RNNComponentPresenter alloc] init];
157
+	RNNComponentPresenter* presenter = [[RNNComponentPresenter alloc] initWithComponentRegistry:nil defaultOptions:nil];
158
 	RNNComponentViewController* vc = [[RNNComponentViewController alloc] initWithLayoutInfo:nil rootViewCreator:[[RNNTestRootViewCreator alloc] init] eventEmitter:nil presenter:presenter options:initialOptions defaultOptions:nil];
158
 	RNNComponentViewController* vc = [[RNNComponentViewController alloc] initWithLayoutInfo:nil rootViewCreator:[[RNNTestRootViewCreator alloc] init] eventEmitter:nil presenter:presenter options:initialOptions defaultOptions:nil];
159
 	
159
 	
160
 	__unused RNNStackController* nav = [[RNNStackController alloc] initWithRootViewController:vc];
160
 	__unused RNNStackController* nav = [[RNNStackController alloc] initWithRootViewController:vc];

+ 1
- 1
playground/ios/NavigationTests/RNNComponentPresenterTest.m Wyświetl plik

21
 - (void)setUp {
21
 - (void)setUp {
22
     [super setUp];
22
     [super setUp];
23
 	self.componentRegistry = [OCMockObject partialMockForObject:[RNNReactComponentRegistry new]];
23
 	self.componentRegistry = [OCMockObject partialMockForObject:[RNNReactComponentRegistry new]];
24
-	self.uut = [[RNNComponentPresenter alloc] initWithComponentRegistry:self.componentRegistry:[[RNNNavigationOptions alloc] initEmptyOptions]];
24
+	self.uut = [[RNNComponentPresenter alloc] initWithComponentRegistry:self.componentRegistry defaultOptions:[[RNNNavigationOptions alloc] initEmptyOptions]];
25
 	self.boundViewController = [OCMockObject partialMockForObject:[RNNComponentViewController new]];
25
 	self.boundViewController = [OCMockObject partialMockForObject:[RNNComponentViewController new]];
26
 	[self.uut bindViewController:self.boundViewController];
26
 	[self.uut bindViewController:self.boundViewController];
27
 	self.options = [[RNNNavigationOptions alloc] initEmptyOptions];
27
 	self.options = [[RNNNavigationOptions alloc] initEmptyOptions];

+ 2
- 2
playground/ios/NavigationTests/RNNRootViewControllerTest.m Wyświetl plik

49
 	layoutInfo.componentId = self.componentId;
49
 	layoutInfo.componentId = self.componentId;
50
 	layoutInfo.name = self.pageName;
50
 	layoutInfo.name = self.pageName;
51
 	
51
 	
52
-	id presenter = [OCMockObject partialMockForObject:[[RNNComponentPresenter alloc] init]];
52
+	id presenter = [OCMockObject partialMockForObject:[[RNNComponentPresenter alloc] initWithComponentRegistry:nil defaultOptions:nil]];
53
 	self.uut = [[RNNComponentViewController alloc] initWithLayoutInfo:layoutInfo rootViewCreator:self.creator eventEmitter:self.emitter presenter:presenter options:self.options defaultOptions:nil];
53
 	self.uut = [[RNNComponentViewController alloc] initWithLayoutInfo:layoutInfo rootViewCreator:self.creator eventEmitter:self.emitter presenter:presenter options:self.options defaultOptions:nil];
54
 }
54
 }
55
 
55
 
108
 	XCTAssertTrue([self.uut prefersStatusBarHidden]);
108
 	XCTAssertTrue([self.uut prefersStatusBarHidden]);
109
 }
109
 }
110
 
110
 
111
-- (void)testTitle_string{
111
+- (void)testTitle_string {
112
 	NSString* title =@"some title";
112
 	NSString* title =@"some title";
113
 	self.options.topBar.title.text = [[Text alloc] initWithValue:title];
113
 	self.options.topBar.title.text = [[Text alloc] initWithValue:title];
114
 
114