Browse Source

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 years ago
parent
commit
c5bd577b41
No account linked to committer's email address

+ 6
- 1
lib/ios/RNNBasePresenter.h View File

@@ -1,4 +1,5 @@
1 1
 #import "RNNNavigationOptions.h"
2
+#import "RNNReactComponentRegistry.h"
2 3
 
3 4
 typedef void (^RNNReactViewReadyCompletionBlock)(void);
4 5
 
@@ -8,10 +9,14 @@ typedef void (^RNNReactViewReadyCompletionBlock)(void);
8 9
 
9 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 16
 - (instancetype)initWithDefaultOptions:(RNNNavigationOptions *)defaultOptions;
14 17
 
18
+- (instancetype)initWithComponentRegistry:(RNNReactComponentRegistry *)componentRegistry defaultOptions:(RNNNavigationOptions *)defaultOptions;
19
+
15 20
 - (void)setDefaultOptions:(RNNNavigationOptions *)defaultOptions;
16 21
 
17 22
 - (void)applyOptionsOnInit:(RNNNavigationOptions *)initialOptions;

+ 7
- 1
lib/ios/RNNBasePresenter.m View File

@@ -12,13 +12,19 @@
12 12
 @end
13 13
 @implementation RNNBasePresenter
14 14
 
15
--(instancetype)initWithDefaultOptions:(RNNNavigationOptions *)defaultOptions {
15
+- (instancetype)initWithDefaultOptions:(RNNNavigationOptions *)defaultOptions {
16 16
     self = [super init];
17 17
     _defaultOptions = defaultOptions;
18 18
     self.dotIndicatorPresenter = [[RNNDotIndicatorPresenter alloc] initWithDefaultOptions:_defaultOptions];
19 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 28
 - (void)bindViewController:(UIViewController *)boundViewController {
23 29
     self.boundComponentId = boundViewController.layoutInfo.componentId;
24 30
     _boundViewController = boundViewController;

+ 0
- 2
lib/ios/RNNComponentPresenter.h View File

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

+ 17
- 77
lib/ios/RNNComponentPresenter.m View File

@@ -5,26 +5,23 @@
5 5
 #import "RNNTitleViewHelper.h"
6 6
 #import "UIViewController+LayoutProtocol.h"
7 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 18
 	return self;
23 19
 }
24 20
 
25 21
 - (void)bindViewController:(id)boundViewController {
26 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 27
 - (void)componentDidAppear {
@@ -32,7 +29,7 @@
32 29
     if ([component respondsToSelector:@selector(componentDidAppear)]) {
33 30
         [component componentDidAppear];
34 31
     }
35
-    [_customTitleView componentDidAppear];
32
+    [_topBarTitlePresenter componentDidAppear];
36 33
     [_navigationButtons componentDidAppear];
37 34
 }
38 35
 
@@ -42,7 +39,7 @@
42 39
         [component componentDidDisappear];
43 40
     }
44 41
     
45
-    [_customTitleView componentDidDisappear];
42
+    [_topBarTitlePresenter componentDidDisappear];
46 43
     [_navigationButtons componentDidDisappear];
47 44
 }
48 45
 
@@ -56,7 +53,6 @@
56 53
 	UIViewController* viewController = self.boundViewController;
57 54
 	RNNNavigationOptions *withDefault = [options withDefault:[self defaultOptions]];
58 55
 	[viewController setBackgroundImage:[withDefault.backgroundImage getWithDefaultValue:nil]];
59
-	[viewController setNavigationItemTitle:[withDefault.topBar.title.text getWithDefaultValue:nil]];
60 56
 	[viewController setTopBarPrefersLargeTitle:[withDefault.topBar.largeTitle.visible getWithDefaultValue:NO]];
61 57
 	[viewController setTabBarItemBadgeColor:[withDefault.bottomTab.badgeColor getWithDefaultValue:nil]];
62 58
 	[viewController setStatusBarBlur:[withDefault.statusBar.blur getWithDefaultValue:NO]];
@@ -75,8 +71,8 @@
75 71
 		}
76 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 78
 - (void)applyOptionsOnInit:(RNNNavigationOptions *)options {
@@ -96,7 +92,6 @@
96 92
     [super mergeOptions:options resolvedOptions:currentOptions];
97 93
 	RNNNavigationOptions * withDefault	= (RNNNavigationOptions *) [[currentOptions overrideOptions:options] withDefault:[self defaultOptions]];
98 94
 	UIViewController* viewController = self.boundViewController;
99
-	[self removeTitleComponentIfNeeded:options];
100 95
 
101 96
 	if (options.backgroundImage.hasValue) {
102 97
 		[viewController setBackgroundImage:options.backgroundImage.get];
@@ -122,10 +117,6 @@
122 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 120
 	if (options.topBar.largeTitle.visible.hasValue) {
130 121
 		[viewController setTopBarPrefersLargeTitle:options.topBar.largeTitle.visible.get];
131 122
 	}
@@ -167,68 +158,17 @@
167 158
 		RCTRootView* rootView = (RCTRootView*)viewController.view;
168 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 165
 - (void)renderComponents:(RNNNavigationOptions *)options perform:(RNNReactViewReadyCompletionBlock)readyBlock {
187 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 171
 - (void)dealloc {
232
-	[_componentRegistry clearComponentsForParentId:self.boundComponentId];
172
+	[self.componentRegistry clearComponentsForParentId:self.boundComponentId];
233 173
 }
234 174
 @end

+ 2
- 2
lib/ios/RNNControllerFactory.m View File

@@ -114,7 +114,7 @@
114 114
 - (UIViewController *)createComponent:(RNNLayoutNode*)node {
115 115
 	RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] initWithNode:node];
116 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 119
 	RNNComponentViewController* component = [[RNNComponentViewController alloc] initWithLayoutInfo:layoutInfo rootViewCreator:_creator eventEmitter:_eventEmitter presenter:presenter options:options defaultOptions:_defaultOptions];
120 120
 	
@@ -193,7 +193,7 @@
193 193
 	RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] initWithNode:node];
194 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 198
 	return sideMenuChild;
199 199
 }

+ 14
- 6
lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj View File

@@ -184,6 +184,8 @@
184 184
 		50570BEA2063E09B006A1B5C /* RNNTitleViewHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 50570BE82063E09B006A1B5C /* RNNTitleViewHelper.h */; };
185 185
 		50570BEB2063E09B006A1B5C /* RNNTitleViewHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 50570BE92063E09B006A1B5C /* RNNTitleViewHelper.m */; };
186 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 189
 		505EDD32214E4BE80071C7DE /* RNNNavigationControllerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 505EDD31214E4BE80071C7DE /* RNNNavigationControllerTest.m */; };
188 190
 		505EDD34214E7B7B0071C7DE /* RNNLeafProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 505EDD33214E7A6A0071C7DE /* RNNLeafProtocol.h */; };
189 191
 		505EDD3C214FA8000071C7DE /* RNNComponentPresenter.h in Headers */ = {isa = PBXBuildFile; fileRef = 505EDD3A214FA8000071C7DE /* RNNComponentPresenter.h */; };
@@ -572,6 +574,8 @@
572 574
 		50570BE82063E09B006A1B5C /* RNNTitleViewHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNTitleViewHelper.h; sourceTree = "<group>"; };
573 575
 		50570BE92063E09B006A1B5C /* RNNTitleViewHelper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNTitleViewHelper.m; sourceTree = "<group>"; };
574 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 579
 		505EDD31214E4BE80071C7DE /* RNNNavigationControllerTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNNavigationControllerTest.m; sourceTree = "<group>"; };
576 580
 		505EDD33214E7A6A0071C7DE /* RNNLeafProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNLeafProtocol.h; sourceTree = "<group>"; };
577 581
 		505EDD3A214FA8000071C7DE /* RNNComponentPresenter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNComponentPresenter.h; sourceTree = "<group>"; };
@@ -1086,6 +1090,14 @@
1086 1090
 				651E1F8C21FD642100DFEA19 /* RNNSplitViewControllerPresenter.m */,
1087 1091
 				30987E66AA7AB38E7370F8C8 /* RNNDotIndicatorPresenter.m */,
1088 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 1102
 			name = Presenters;
1091 1103
 			sourceTree = "<group>";
@@ -1143,12 +1155,6 @@
1143 1155
 				50570BE92063E09B006A1B5C /* RNNTitleViewHelper.m */,
1144 1156
 				501CD31D214A5B6900A6E225 /* RNNLayoutInfo.h */,
1145 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 1158
 				501E0215213E7EA3003365C5 /* RNNReactView.h */,
1153 1159
 				501E0216213E7EA3003365C5 /* RNNReactView.m */,
1154 1160
 				503A8A1723BCB2ED0094D1C4 /* RNNReactButtonView.h */,
@@ -1466,6 +1472,7 @@
1466 1472
 				5049593E216F5D73006D2B81 /* BoolParser.h in Headers */,
1467 1473
 				E5F6C3A522DB4D0F0093C2CE /* UIViewController+Utils.h in Headers */,
1468 1474
 				50C4A496206BDDBB00DB292E /* RNNSubtitleOptions.h in Headers */,
1475
+				505C640223E074860078AFC0 /* TopBarTitlePresenter.h in Headers */,
1469 1476
 				5039559B2174867000B0A663 /* DoubleParser.h in Headers */,
1470 1477
 				E8AEDB3C1F55A1C2000F5A6A /* RNNElementView.h in Headers */,
1471 1478
 				E8E518321F83B3E0000467AC /* RNNUtils.h in Headers */,
@@ -1730,6 +1737,7 @@
1730 1737
 				50395594217485B000B0A663 /* Double.m in Sources */,
1731 1738
 				504AFE751FFFF0540076E904 /* RNNTopTabsOptions.m in Sources */,
1732 1739
 				50175CD2207A2AA1004FE91B /* RNNComponentOptions.m in Sources */,
1740
+				505C640323E074860078AFC0 /* TopBarTitlePresenter.m in Sources */,
1733 1741
 				50E02BDC21A6EE7900A43942 /* SideMenuOpenGestureModeParser.m in Sources */,
1734 1742
 				7BEF0D1D1E43771B003E96B0 /* RNNLayoutNode.m in Sources */,
1735 1743
 				7BA500781E254908001B9E1B /* RNNSplashScreen.m in Sources */,

+ 13
- 0
lib/ios/TopBarTitlePresenter.h View File

@@ -0,0 +1,13 @@
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 View File

@@ -0,0 +1,89 @@
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 View File

@@ -49,7 +49,7 @@
49 49
 	layoutInfo.componentId = self.componentId;
50 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 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 View File

@@ -131,7 +131,7 @@
131 131
 	RNNLayoutInfo* layoutInfo = [RNNLayoutInfo new];
132 132
 	RNNTestRootViewCreator* creator = [[RNNTestRootViewCreator alloc] init];
133 133
 	
134
-	RNNComponentPresenter* presenter = [[RNNComponentPresenter alloc] init];
134
+	RNNComponentPresenter* presenter = [[RNNComponentPresenter alloc] initWithComponentRegistry:nil defaultOptions:nil];
135 135
 	RNNComponentViewController* vc = [[RNNComponentViewController alloc] initWithLayoutInfo:layoutInfo rootViewCreator:creator eventEmitter:nil presenter:presenter options:initialOptions defaultOptions:nil];
136 136
 	
137 137
 	RNNStackController* nav = [[RNNStackController alloc] initWithLayoutInfo:nil creator:creator options:[[RNNNavigationOptions alloc] initEmptyOptions] defaultOptions:nil presenter:[[RNNStackPresenter alloc] init] eventEmitter:nil childViewControllers:@[vc]];
@@ -154,7 +154,7 @@
154 154
 	RNNNavigationOptions* initialOptions = [[RNNNavigationOptions alloc] initWithDict:@{}];
155 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 158
 	RNNComponentViewController* vc = [[RNNComponentViewController alloc] initWithLayoutInfo:nil rootViewCreator:[[RNNTestRootViewCreator alloc] init] eventEmitter:nil presenter:presenter options:initialOptions defaultOptions:nil];
159 159
 	
160 160
 	__unused RNNStackController* nav = [[RNNStackController alloc] initWithRootViewController:vc];

+ 1
- 1
playground/ios/NavigationTests/RNNComponentPresenterTest.m View File

@@ -21,7 +21,7 @@
21 21
 - (void)setUp {
22 22
     [super setUp];
23 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 25
 	self.boundViewController = [OCMockObject partialMockForObject:[RNNComponentViewController new]];
26 26
 	[self.uut bindViewController:self.boundViewController];
27 27
 	self.options = [[RNNNavigationOptions alloc] initEmptyOptions];

+ 2
- 2
playground/ios/NavigationTests/RNNRootViewControllerTest.m View File

@@ -49,7 +49,7 @@
49 49
 	layoutInfo.componentId = self.componentId;
50 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 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,7 +108,7 @@
108 108
 	XCTAssertTrue([self.uut prefersStatusBarHidden]);
109 109
 }
110 110
 
111
-- (void)testTitle_string{
111
+- (void)testTitle_string {
112 112
 	NSString* title =@"some title";
113 113
 	self.options.topBar.title.text = [[Text alloc] initWithValue:title];
114 114