Browse Source

V2 custom top bar (#2632)

* custom titleView support

* custom navBar and titleView support
yogevbd 7 years ago
parent
commit
82f4ee2ca9
No account linked to committer's email address

+ 7
- 0
lib/ios/RNNCustomTitleView.h View File

1
+#import <UIKit/UIKit.h>
2
+
3
+@interface RNNCustomTitleView : UIView
4
+
5
+-(instancetype)initWithFrame:(CGRect)frame subView:(UIView*)subView alignment:(NSString*)alignment;
6
+
7
+@end

+ 47
- 0
lib/ios/RNNCustomTitleView.m View File

1
+#import "RNNCustomTitleView.h"
2
+
3
+@interface RNNCustomTitleView ()
4
+@property (nonatomic, strong) UIView *subView;
5
+@property (nonatomic, strong) NSString *subViewAlign;
6
+@end
7
+
8
+@implementation RNNCustomTitleView
9
+
10
+
11
+-(instancetype)initWithFrame:(CGRect)frame subView:(UIView*)subView alignment:(NSString*)alignment {
12
+    self = [super initWithFrame:frame];
13
+    
14
+    if (self) {
15
+        self.backgroundColor = [UIColor clearColor];
16
+        self.subView = subView;
17
+        self.subViewAlign = alignment;
18
+        
19
+        subView.frame = self.bounds;
20
+        [self addSubview:subView];
21
+    }
22
+    
23
+    return self;
24
+}
25
+
26
+
27
+-(void)layoutSubviews {
28
+    [super layoutSubviews];
29
+    
30
+    if ([self.subViewAlign isEqualToString:@"fill"]) {
31
+        self.subView.frame = self.bounds;
32
+    }
33
+    else {
34
+        
35
+        CGFloat superViewWidth = self.superview.frame.size.width;
36
+        CGFloat paddingLeftFromCenter = (superViewWidth/2) - self.frame.origin.x;
37
+        CGFloat paddingRightFromCenter = self.frame.size.width - paddingLeftFromCenter;;
38
+        CGRect reactViewFrame = self.subView.bounds;
39
+        CGFloat minPadding = MIN(paddingLeftFromCenter, paddingRightFromCenter);
40
+        
41
+        reactViewFrame.size.width = minPadding*2;
42
+        reactViewFrame.origin.x = paddingLeftFromCenter - minPadding;
43
+        self.subView.frame = reactViewFrame;
44
+    }
45
+}
46
+
47
+@end

+ 23
- 1
lib/ios/RNNRootViewController.m View File

2
 #import "RNNRootViewController.h"
2
 #import "RNNRootViewController.h"
3
 #import <React/RCTConvert.h>
3
 #import <React/RCTConvert.h>
4
 #import "RNNAnimator.h"
4
 #import "RNNAnimator.h"
5
+#import "RNNCustomTitleView.h"
5
 
6
 
6
 @interface RNNRootViewController()
7
 @interface RNNRootViewController()
7
 @property (nonatomic, strong) NSString* componentName;
8
 @property (nonatomic, strong) NSString* componentName;
8
 @property (nonatomic) BOOL _statusBarHidden;
9
 @property (nonatomic) BOOL _statusBarHidden;
9
-
10
+@property (nonatomic) id<RNNRootViewCreator> creator;
10
 @end
11
 @end
11
 
12
 
12
 @implementation RNNRootViewController
13
 @implementation RNNRootViewController
22
 	self.options = options;
23
 	self.options = options;
23
 	self.eventEmitter = eventEmitter;
24
 	self.eventEmitter = eventEmitter;
24
 	self.animator = [[RNNAnimator alloc] initWithTransitionOptions:self.options.customTransition];
25
 	self.animator = [[RNNAnimator alloc] initWithTransitionOptions:self.options.customTransition];
26
+	self.creator = creator;
25
 	self.view = [creator createRootView:self.componentName rootViewId:self.componentId];
27
 	self.view = [creator createRootView:self.componentName rootViewId:self.componentId];
26
 	
28
 	
27
 	[[NSNotificationCenter defaultCenter] addObserver:self
29
 	[[NSNotificationCenter defaultCenter] addObserver:self
37
 -(void)viewWillAppear:(BOOL)animated{
39
 -(void)viewWillAppear:(BOOL)animated{
38
 	[super viewWillAppear:animated];
40
 	[super viewWillAppear:animated];
39
 	[self.options applyOn:self];
41
 	[self.options applyOn:self];
42
+	[self setCustomNavigationTitleView];
43
+	[self setCustomNavigationBarView];
40
 }
44
 }
41
 
45
 
42
 -(void)viewDidAppear:(BOOL)animated {
46
 -(void)viewDidAppear:(BOOL)animated {
57
 	[super viewDidLoad];
61
 	[super viewDidLoad];
58
 }
62
 }
59
 
63
 
64
+- (void)setCustomNavigationTitleView {
65
+	if (self.options.topBar.customTitleViewName) {
66
+		UIView *reactView = [_creator createRootView:self.options.topBar.customTitleViewName rootViewId:self.options.topBar.customTitleViewName];
67
+		
68
+		RNNCustomTitleView *titleView = [[RNNCustomTitleView alloc] initWithFrame:self.navigationController.navigationBar.bounds subView:reactView alignment:nil];
69
+		self.navigationItem.titleView = titleView;
70
+	}
71
+}
72
+
73
+- (void)setCustomNavigationBarView {
74
+	if (self.options.topBar.customViewName) {
75
+		UIView *reactView = [_creator createRootView:self.options.topBar.customViewName rootViewId:@"navBar"];
76
+		
77
+		RNNCustomTitleView *titleView = [[RNNCustomTitleView alloc] initWithFrame:self.navigationController.navigationBar.bounds subView:reactView alignment:nil];
78
+		[self.navigationController.navigationBar addSubview:titleView];
79
+	}
80
+}
81
+
60
 -(BOOL)isCustomTransitioned {
82
 -(BOOL)isCustomTransitioned {
61
 	return self.options.customTransition != nil;
83
 	return self.options.customTransition != nil;
62
 }
84
 }

+ 3
- 0
lib/ios/RNNTopBarOptions.h View File

21
 @property (nonatomic, strong) NSNumber* largeTitle;
21
 @property (nonatomic, strong) NSNumber* largeTitle;
22
 @property (nonatomic, strong) NSString* testID;
22
 @property (nonatomic, strong) NSString* testID;
23
 
23
 
24
+@property (nonatomic, strong) NSString* customTitleViewName;
25
+@property (nonatomic, strong) NSString* customViewName;
26
+
24
 @end
27
 @end

+ 1
- 0
lib/ios/RNNTopBarOptions.m View File

1
 #import "RNNTopBarOptions.h"
1
 #import "RNNTopBarOptions.h"
2
 #import "RNNNavigationButtons.h"
2
 #import "RNNNavigationButtons.h"
3
+#import "RNNCustomTitleView.h"
3
 
4
 
4
 extern const NSInteger BLUR_TOPBAR_TAG;
5
 extern const NSInteger BLUR_TOPBAR_TAG;
5
 
6
 

+ 8
- 0
lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj View File

61
 		2DCD9196200014A900EDC75D /* RNNBridgeManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DCD9194200014A900EDC75D /* RNNBridgeManager.m */; };
61
 		2DCD9196200014A900EDC75D /* RNNBridgeManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DCD9194200014A900EDC75D /* RNNBridgeManager.m */; };
62
 		390AD477200F499D00A8250D /* RNNSwizzles.h in Headers */ = {isa = PBXBuildFile; fileRef = 390AD475200F499D00A8250D /* RNNSwizzles.h */; };
62
 		390AD477200F499D00A8250D /* RNNSwizzles.h in Headers */ = {isa = PBXBuildFile; fileRef = 390AD475200F499D00A8250D /* RNNSwizzles.h */; };
63
 		390AD478200F499D00A8250D /* RNNSwizzles.m in Sources */ = {isa = PBXBuildFile; fileRef = 390AD476200F499D00A8250D /* RNNSwizzles.m */; };
63
 		390AD478200F499D00A8250D /* RNNSwizzles.m in Sources */ = {isa = PBXBuildFile; fileRef = 390AD476200F499D00A8250D /* RNNSwizzles.m */; };
64
+		5016E8EF20209690009D4F7C /* RNNCustomTitleView.h in Headers */ = {isa = PBXBuildFile; fileRef = 5016E8ED2020968F009D4F7C /* RNNCustomTitleView.h */; };
65
+		5016E8F020209690009D4F7C /* RNNCustomTitleView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5016E8EE2020968F009D4F7C /* RNNCustomTitleView.m */; };
64
 		5032774E2015E86D00ECD75D /* RNNNavigationEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 5032774C2015E86D00ECD75D /* RNNNavigationEvent.h */; };
66
 		5032774E2015E86D00ECD75D /* RNNNavigationEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 5032774C2015E86D00ECD75D /* RNNNavigationEvent.h */; };
65
 		5032774F2015E86D00ECD75D /* RNNNavigationEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 5032774D2015E86D00ECD75D /* RNNNavigationEvent.m */; };
67
 		5032774F2015E86D00ECD75D /* RNNNavigationEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 5032774D2015E86D00ECD75D /* RNNNavigationEvent.m */; };
66
 		503277602016302900ECD75D /* RNNComponentLifecycleEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 5032775E2016302900ECD75D /* RNNComponentLifecycleEvent.h */; };
68
 		503277602016302900ECD75D /* RNNComponentLifecycleEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 5032775E2016302900ECD75D /* RNNComponentLifecycleEvent.h */; };
238
 		2DCD9194200014A900EDC75D /* RNNBridgeManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNBridgeManager.m; sourceTree = "<group>"; };
240
 		2DCD9194200014A900EDC75D /* RNNBridgeManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNBridgeManager.m; sourceTree = "<group>"; };
239
 		390AD475200F499D00A8250D /* RNNSwizzles.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNSwizzles.h; sourceTree = "<group>"; };
241
 		390AD475200F499D00A8250D /* RNNSwizzles.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNSwizzles.h; sourceTree = "<group>"; };
240
 		390AD476200F499D00A8250D /* RNNSwizzles.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNSwizzles.m; sourceTree = "<group>"; };
242
 		390AD476200F499D00A8250D /* RNNSwizzles.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNSwizzles.m; sourceTree = "<group>"; };
243
+		5016E8ED2020968F009D4F7C /* RNNCustomTitleView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNNCustomTitleView.h; sourceTree = "<group>"; };
244
+		5016E8EE2020968F009D4F7C /* RNNCustomTitleView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNCustomTitleView.m; sourceTree = "<group>"; };
241
 		5032774C2015E86D00ECD75D /* RNNNavigationEvent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNNavigationEvent.h; sourceTree = "<group>"; };
245
 		5032774C2015E86D00ECD75D /* RNNNavigationEvent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNNavigationEvent.h; sourceTree = "<group>"; };
242
 		5032774D2015E86D00ECD75D /* RNNNavigationEvent.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNNavigationEvent.m; sourceTree = "<group>"; };
246
 		5032774D2015E86D00ECD75D /* RNNNavigationEvent.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNNavigationEvent.m; sourceTree = "<group>"; };
243
 		5032775E2016302900ECD75D /* RNNComponentLifecycleEvent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNComponentLifecycleEvent.h; sourceTree = "<group>"; };
247
 		5032775E2016302900ECD75D /* RNNComponentLifecycleEvent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNComponentLifecycleEvent.h; sourceTree = "<group>"; };
657
 		E8AEDB471F584175000F5A6A /* Components */ = {
661
 		E8AEDB471F584175000F5A6A /* Components */ = {
658
 			isa = PBXGroup;
662
 			isa = PBXGroup;
659
 			children = (
663
 			children = (
664
+				5016E8ED2020968F009D4F7C /* RNNCustomTitleView.h */,
665
+				5016E8EE2020968F009D4F7C /* RNNCustomTitleView.m */,
660
 				E8A5CD601F49114F00E89D0D /* RNNElement.h */,
666
 				E8A5CD601F49114F00E89D0D /* RNNElement.h */,
661
 				E8A5CD611F49114F00E89D0D /* RNNElement.m */,
667
 				E8A5CD611F49114F00E89D0D /* RNNElement.m */,
662
 				E8AEDB3A1F55A1C2000F5A6A /* RNNElementView.h */,
668
 				E8AEDB3A1F55A1C2000F5A6A /* RNNElementView.h */,
694
 				50F5DFC11F407A8C001A00BC /* RNNTabBarController.h in Headers */,
700
 				50F5DFC11F407A8C001A00BC /* RNNTabBarController.h in Headers */,
695
 				50CB3B691FDE911400AA153B /* RNNSideMenuOptions.h in Headers */,
701
 				50CB3B691FDE911400AA153B /* RNNSideMenuOptions.h in Headers */,
696
 				263905BD1E4C6F440023D7D3 /* RCCDrawerProtocol.h in Headers */,
702
 				263905BD1E4C6F440023D7D3 /* RCCDrawerProtocol.h in Headers */,
703
+				5016E8EF20209690009D4F7C /* RNNCustomTitleView.h in Headers */,
697
 				263905C21E4C6F440023D7D3 /* SidebarAnimation.h in Headers */,
704
 				263905C21E4C6F440023D7D3 /* SidebarAnimation.h in Headers */,
698
 				E8E518361F83B94A000467AC /* RNNViewLocation.h in Headers */,
705
 				E8E518361F83B94A000467AC /* RNNViewLocation.h in Headers */,
699
 				263905B51E4C6F440023D7D3 /* MMExampleDrawerVisualStateManager.h in Headers */,
706
 				263905B51E4C6F440023D7D3 /* MMExampleDrawerVisualStateManager.h in Headers */,
856
 				E8A5CD531F464F0400E89D0D /* RNNAnimator.m in Sources */,
863
 				E8A5CD531F464F0400E89D0D /* RNNAnimator.m in Sources */,
857
 				50CB3B6A1FDE911400AA153B /* RNNSideMenuOptions.m in Sources */,
864
 				50CB3B6A1FDE911400AA153B /* RNNSideMenuOptions.m in Sources */,
858
 				261F0E6B1E6F028A00989DE2 /* RNNNavigationStackManager.m in Sources */,
865
 				261F0E6B1E6F028A00989DE2 /* RNNNavigationStackManager.m in Sources */,
866
+				5016E8F020209690009D4F7C /* RNNCustomTitleView.m in Sources */,
859
 				E8DA24411F97459B00CD552B /* RNNElementFinder.m in Sources */,
867
 				E8DA24411F97459B00CD552B /* RNNElementFinder.m in Sources */,
860
 				263905BF1E4C6F440023D7D3 /* RCCTheSideBarManagerViewController.m in Sources */,
868
 				263905BF1E4C6F440023D7D3 /* RCCTheSideBarManagerViewController.m in Sources */,
861
 				7B1126A01E2D263F00F9B03B /* RNNEventEmitter.m in Sources */,
869
 				7B1126A01E2D263F00F9B03B /* RNNEventEmitter.m in Sources */,

+ 47
- 0
playground/src/screens/CustomTopBar.js View File

1
+const React = require('react');
2
+const { Component } = require('react');
3
+const {
4
+  StyleSheet,
5
+  View,
6
+  TouchableOpacity,
7
+  Text,
8
+  Alert,
9
+  Platform
10
+} = require('react-native');
11
+
12
+class CustomTopBar extends Component {
13
+
14
+  constructor(props) {
15
+    super(props);
16
+    this.state = {};
17
+  }
18
+
19
+  render() {
20
+    return (
21
+      <View style={styles.container}>
22
+        <TouchableOpacity stye={styles.button} onPress={() => Alert.alert(this.props.title, 'Thanks for that :)')}>
23
+          <Text style={styles.text}>Press Me</Text>
24
+        </TouchableOpacity>
25
+      </View>
26
+    );
27
+  }
28
+}
29
+
30
+module.exports = CustomTopBar;
31
+
32
+const styles = StyleSheet.create({
33
+  container: {
34
+    flex: 1,
35
+    justifyContent: 'center',
36
+    alignItems: 'center',
37
+    backgroundColor: 'white'
38
+  },
39
+  button: {
40
+    alignSelf: 'center',
41
+    backgroundColor: 'green'
42
+  },
43
+  text: {
44
+    alignSelf: 'center',
45
+    color: Platform.OS === 'ios' ? 'black' : 'white'
46
+  }
47
+});

+ 2
- 0
playground/src/screens/index.js View File

16
 const SideMenuScreen = require('./SideMenuScreen');
16
 const SideMenuScreen = require('./SideMenuScreen');
17
 const TopTabScreen = require('./TopTabScreen');
17
 const TopTabScreen = require('./TopTabScreen');
18
 const TopTabOptionsScreen = require('./TopTabOptionsScreen');
18
 const TopTabOptionsScreen = require('./TopTabOptionsScreen');
19
+const CustomTopBar = require('./CustomTopBar');
19
 
20
 
20
 function registerScreens() {
21
 function registerScreens() {
21
   Navigation.registerComponent(`navigation.playground.CustomTransitionDestination`, () => CustomTransitionDestination);
22
   Navigation.registerComponent(`navigation.playground.CustomTransitionDestination`, () => CustomTransitionDestination);
35
   Navigation.registerComponent('navigation.playground.SideMenuScreen', () => SideMenuScreen);
36
   Navigation.registerComponent('navigation.playground.SideMenuScreen', () => SideMenuScreen);
36
   Navigation.registerComponent('navigation.playground.TopTabScreen', () => TopTabScreen);
37
   Navigation.registerComponent('navigation.playground.TopTabScreen', () => TopTabScreen);
37
   Navigation.registerComponent('navigation.playground.TopTabOptionsScreen', () => TopTabOptionsScreen);
38
   Navigation.registerComponent('navigation.playground.TopTabOptionsScreen', () => TopTabOptionsScreen);
39
+  Navigation.registerComponent('navigation.playground.CustomTopBar', () => CustomTopBar);
38
 }
40
 }
39
 
41
 
40
 module.exports = {
42
 module.exports = {