Browse Source

V2 subtitle (#2919)

* Added titleView helper

* subtitle support

* Added titleView helper

* subtitle support
yogevbd 6 years ago
parent
commit
99f8487670
No account linked to committer's email address

+ 8
- 0
lib/ios/RNNTitleOptions.h View File

@@ -6,8 +6,16 @@
6 6
 @property (nonatomic, strong) NSNumber* fontSize;
7 7
 @property (nonatomic, strong) NSNumber* color;
8 8
 @property (nonatomic, strong) NSString* fontFamily;
9
+
10
+@property (nonatomic, strong) NSString* subtitle;
11
+@property (nonatomic, strong) NSString* subtitleFontFamily;
12
+@property (nonatomic, strong) NSString* subtitleFontSize;
13
+@property (nonatomic, strong) NSString* subtitleColor;
14
+
9 15
 @property (nonatomic, strong) NSString* component;
10 16
 @property (nonatomic, strong) NSString* componentAlignment;
11 17
 
18
+@property (nonatomic, strong) NSDictionary* fontAttributes;
19
+@property (nonatomic, strong) NSDictionary* subtitleFontAttributes;
12 20
 
13 21
 @end

+ 39
- 7
lib/ios/RNNTitleOptions.m View File

@@ -1,4 +1,5 @@
1 1
 #import "RNNTitleOptions.h"
2
+#import "RNNTitleViewHelper.h"
2 3
 
3 4
 @implementation RNNTitleOptions
4 5
 
@@ -7,13 +8,27 @@
7 8
 		viewController.navigationItem.title = self.text;
8 9
 	}
9 10
 	
11
+	NSDictionary* fontAttributes = [self fontAttributes];
12
+	
13
+	viewController.navigationController.navigationBar.titleTextAttributes = fontAttributes;
14
+	if (@available(iOS 11.0, *)){
15
+		viewController.navigationController.navigationBar.largeTitleTextAttributes = fontAttributes;
16
+	}
17
+	
18
+	if (self.subtitle) {
19
+		RNNTitleViewHelper* titleViewHelper = [[RNNTitleViewHelper alloc] init:viewController title:self.text subtitle:self.subtitle titleImageData:nil isSetSubtitle:NO];
20
+		[titleViewHelper setup:self];
21
+	}
22
+}
23
+
24
+- (NSDictionary *)fontAttributes {
25
+	NSMutableDictionary* navigationBarTitleTextAttributes = [NSMutableDictionary new];
10 26
 	if (self.fontFamily || self.fontSize || self.color) {
11
-		NSMutableDictionary* navigationBarTitleTextAttributes = [NSMutableDictionary new];
12 27
 		if (self.color) {
13
-			navigationBarTitleTextAttributes[NSForegroundColorAttributeName] = [RCTConvert UIColor:[self valueForKey:@"color"]];
28
+			navigationBarTitleTextAttributes[NSForegroundColorAttributeName] = [RCTConvert UIColor:self.color];
14 29
 		}
15 30
 		if (self.fontFamily){
16
-			if(self.fontSize) {
31
+			if (self.fontSize) {
17 32
 				navigationBarTitleTextAttributes[NSFontAttributeName] = [UIFont fontWithName:self.fontFamily size:[self.fontSize floatValue]];
18 33
 			} else {
19 34
 				navigationBarTitleTextAttributes[NSFontAttributeName] = [UIFont fontWithName:self.fontFamily size:20];
@@ -21,12 +36,29 @@
21 36
 		} else if (self.fontSize) {
22 37
 			navigationBarTitleTextAttributes[NSFontAttributeName] = [UIFont systemFontOfSize:[self.fontSize floatValue]];
23 38
 		}
24
-		viewController.navigationController.navigationBar.titleTextAttributes = navigationBarTitleTextAttributes;
25
-		if (@available(iOS 11.0, *)){
26
-			viewController.navigationController.navigationBar.largeTitleTextAttributes = navigationBarTitleTextAttributes;
39
+	}
40
+	
41
+	return navigationBarTitleTextAttributes;
42
+}
43
+
44
+- (NSDictionary *)subtitleFontAttributes {
45
+	NSMutableDictionary* navigationBarTitleTextAttributes = [NSMutableDictionary new];
46
+	if (self.subtitleFontFamily || self.subtitleFontSize || self.subtitleColor) {
47
+		if (self.subtitleColor) {
48
+			navigationBarTitleTextAttributes[NSForegroundColorAttributeName] = [RCTConvert UIColor:self.subtitleColor];
49
+		}
50
+		if (self.subtitleFontFamily){
51
+			if (self.subtitleFontSize) {
52
+				navigationBarTitleTextAttributes[NSFontAttributeName] = [UIFont fontWithName:self.subtitleFontFamily size:[self.subtitleFontSize floatValue]];
53
+			} else {
54
+				navigationBarTitleTextAttributes[NSFontAttributeName] = [UIFont fontWithName:self.subtitleFontFamily size:14];
55
+			}
56
+		} else if (self.subtitleFontSize) {
57
+			navigationBarTitleTextAttributes[NSFontAttributeName] = [UIFont systemFontOfSize:[self.subtitleFontSize floatValue]];
27 58
 		}
28
-		
29 59
 	}
60
+	
61
+	return navigationBarTitleTextAttributes;
30 62
 }
31 63
 
32 64
 @end

+ 24
- 0
lib/ios/RNNTitleViewHelper.h View File

@@ -0,0 +1,24 @@
1
+#import <Foundation/Foundation.h>
2
+#import <UIKit/UIKit.h>
3
+#import "RNNTitleOptions.h"
4
+
5
+@interface RNNTitleView : UIView
6
+
7
+@property (nonatomic, strong) UILabel *titleLabel;
8
+
9
+@property (nonatomic, strong) UILabel *subtitleLabel;
10
+
11
+@end
12
+
13
+@interface RNNTitleViewHelper : NSObject
14
+
15
+
16
+- (instancetype)init:(UIViewController*)viewController
17
+			   title:(NSString*)title subtitle:(NSString*)subtitle
18
+	  titleImageData:(id)titleImageData
19
+	   isSetSubtitle:(BOOL)isSetSubtitle;
20
+
21
+-(void)setup:(RNNTitleOptions*)style;
22
+
23
+@end
24
+

+ 193
- 0
lib/ios/RNNTitleViewHelper.m View File

@@ -0,0 +1,193 @@
1
+
2
+#import "RNNTitleViewHelper.h"
3
+#import <React/RCTConvert.h>
4
+#import "RCTHelpers.h"
5
+
6
+@implementation RNNTitleView
7
+
8
+
9
+@end
10
+
11
+@interface RNNTitleViewHelper ()
12
+
13
+@property (nonatomic, weak) UIViewController *viewController;
14
+
15
+@property (nonatomic, strong) NSString *title;
16
+@property (nonatomic, strong) NSString *subtitle;
17
+@property (nonatomic, strong) id titleImageData;
18
+@property (nonatomic) BOOL isSetSubtitle;
19
+
20
+@property (nonatomic, strong) RNNTitleView *titleView;
21
+
22
+@end
23
+
24
+
25
+@implementation RNNTitleViewHelper
26
+
27
+- (instancetype)init:(UIViewController*)viewController
28
+			   title:(NSString*)title subtitle:(NSString*)subtitle
29
+	  titleImageData:(id)titleImageData
30
+	   isSetSubtitle:(BOOL)isSetSubtitle {
31
+	self = [super init];
32
+	if (self) {
33
+		self.viewController = viewController;
34
+		if (isSetSubtitle){
35
+			self.title = viewController.navigationItem.title;
36
+		} else {
37
+			self.title = [RNNTitleViewHelper validateString:title];
38
+		}
39
+		self.subtitle = [RNNTitleViewHelper validateString:subtitle];
40
+		self.titleImageData = titleImageData;
41
+	}
42
+	return self;
43
+}
44
+
45
++(NSString*)validateString:(NSString*)string {
46
+	if ([string isEqual:[NSNull null]]) {
47
+		return nil;
48
+	}
49
+	
50
+	return string;
51
+}
52
+
53
+-(void)setup:(RNNTitleOptions*)style {
54
+
55
+	CGRect navigationBarBounds = self.viewController.navigationController.navigationBar.bounds;
56
+	
57
+	self.titleView = [[RNNTitleView alloc] initWithFrame:navigationBarBounds];
58
+	self.titleView.backgroundColor = [UIColor clearColor];
59
+	self.titleView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
60
+	self.titleView.clipsToBounds = YES;
61
+	
62
+	self.viewController.navigationItem.title = self.title;
63
+	
64
+	if ([self isTitleOnly]) {
65
+		self.viewController.navigationItem.titleView = nil;
66
+		return;
67
+	}
68
+	
69
+	if ([self isTitleImage]) {
70
+		[self setupTitleImage];
71
+		return;
72
+	}
73
+	
74
+	if (self.subtitle) {
75
+		self.titleView.subtitleLabel = [self setupSubtitle:style];
76
+	}
77
+	
78
+	if (self.title) {
79
+		self.titleView.titleLabel = [self setupTitle:style];
80
+	}
81
+	
82
+	[self centerTitleView:navigationBarBounds titleLabel:self.titleView.titleLabel subtitleLabel:self.titleView.subtitleLabel];
83
+	
84
+	self.viewController.navigationItem.titleView = self.titleView;
85
+}
86
+
87
+
88
+-(BOOL)isTitleOnly {
89
+	return self.title && !self.subtitle && !self.titleImageData;
90
+}
91
+
92
+
93
+-(BOOL)isTitleImage {
94
+	return self.titleImageData && ![self.titleImageData isEqual:[NSNull null]];
95
+}
96
+
97
+
98
+-(void)setupTitleImage {
99
+	UIImage *titleImage = [RCTConvert UIImage:self.titleImageData];
100
+	UIImageView *imageView = [[UIImageView alloc] initWithImage:titleImage];
101
+	imageView.contentMode = UIViewContentModeScaleAspectFit;
102
+	imageView.autoresizingMask = self.titleView.autoresizingMask;
103
+	
104
+	self.viewController.navigationItem.titleView = imageView;
105
+}
106
+
107
+
108
+-(void)centerTitleView:(CGRect)navigationBarBounds titleLabel:(UILabel*)titleLabel subtitleLabel:(UILabel*)subtitleLabel
109
+{
110
+	CGRect titleViewFrame = navigationBarBounds;
111
+	titleViewFrame.size.width = MAX(titleLabel.frame.size.width, subtitleLabel.frame.size.width);;
112
+	self.titleView.frame = titleViewFrame;
113
+	
114
+	for (UIView *view in self.titleView.subviews) {
115
+		CGRect viewFrame = view.frame;
116
+		viewFrame.size.width = self.titleView.frame.size.width;
117
+		viewFrame.origin.x = (self.titleView.frame.size.width - viewFrame.size.width)/2;
118
+		view.frame = viewFrame;
119
+	}
120
+	
121
+}
122
+
123
+
124
+-(UILabel*)setupSubtitle:(RNNTitleOptions*)style {
125
+	CGRect subtitleFrame = self.titleView.frame;
126
+	subtitleFrame.size.height /= 2;
127
+	subtitleFrame.origin.y = subtitleFrame.size.height;
128
+	
129
+	UILabel *subtitleLabel = [[UILabel alloc] initWithFrame:subtitleFrame];
130
+	subtitleLabel.textAlignment = NSTextAlignmentCenter;
131
+	subtitleLabel.backgroundColor = [UIColor clearColor];
132
+	subtitleLabel.autoresizingMask = self.titleView.autoresizingMask;
133
+	
134
+	[subtitleLabel setAttributedText:[[NSAttributedString alloc] initWithString:self.subtitle attributes:style.fontAttributes]];
135
+	
136
+	
137
+	CGSize labelSize = [subtitleLabel.text sizeWithAttributes:style.fontAttributes];
138
+	CGRect labelframe = subtitleLabel.frame;
139
+	labelframe.size = labelSize;
140
+	subtitleLabel.frame = labelframe;
141
+	[subtitleLabel sizeToFit];
142
+	
143
+	[self.titleView addSubview:subtitleLabel];
144
+	
145
+	return subtitleLabel;
146
+}
147
+
148
+
149
+-(UILabel*)setupTitle:(RNNTitleOptions*)style {
150
+	CGRect titleFrame = self.titleView.frame;
151
+	if (self.subtitle) {
152
+		titleFrame.size.height /= 2;
153
+	}
154
+	UILabel *titleLabel = [[UILabel alloc] initWithFrame:titleFrame];
155
+	titleLabel.textAlignment = NSTextAlignmentCenter;
156
+	titleLabel.backgroundColor = [UIColor clearColor];
157
+	
158
+	titleLabel.autoresizingMask = self.titleView.autoresizingMask;
159
+	
160
+	UIFont *titleFont = [UIFont boldSystemFontOfSize:17.f];
161
+	
162
+	id fontSize = style.subtitleFontSize;
163
+	if (fontSize) {
164
+		CGFloat fontSizeFloat = [RCTConvert CGFloat:fontSize];
165
+		titleFont = [UIFont boldSystemFontOfSize:fontSizeFloat];
166
+	}
167
+	
168
+	[titleLabel setAttributedText:[[NSAttributedString alloc] initWithString:self.title attributes:style.subtitleFontAttributes]];
169
+	
170
+	CGSize labelSize = [titleLabel.text sizeWithAttributes:@{NSFontAttributeName:titleFont}];
171
+	CGRect labelframe = titleLabel.frame;
172
+	labelframe.size = labelSize;
173
+	titleLabel.frame = labelframe;
174
+	
175
+	if (!self.subtitle) {
176
+		titleLabel.center = self.titleView.center;
177
+	}
178
+	
179
+	id navBarTextColor = style.subtitleColor;
180
+	if (navBarTextColor) {
181
+		UIColor *color = navBarTextColor != (id)[NSNull null] ? [RCTConvert UIColor:navBarTextColor] : nil;
182
+		titleLabel.textColor = color;
183
+	}
184
+	
185
+	[titleLabel sizeToFit];
186
+	[self.titleView addSubview:titleLabel];
187
+	
188
+	return titleLabel;
189
+}
190
+
191
+
192
+@end
193
+

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

@@ -79,6 +79,8 @@
79 79
 		504AFE771FFFF1E20076E904 /* RNNTopBarOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = A7626BFE1FC2FB6700492FB8 /* RNNTopBarOptions.h */; };
80 80
 		50570B262061473D006A1B5C /* RNNTitleOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 50570B242061473D006A1B5C /* RNNTitleOptions.h */; };
81 81
 		50570B272061473D006A1B5C /* RNNTitleOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 50570B252061473D006A1B5C /* RNNTitleOptions.m */; };
82
+		50570BEA2063E09B006A1B5C /* RNNTitleViewHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 50570BE82063E09B006A1B5C /* RNNTitleViewHelper.h */; };
83
+		50570BEB2063E09B006A1B5C /* RNNTitleViewHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 50570BE92063E09B006A1B5C /* RNNTitleViewHelper.m */; };
82 84
 		50762D08205E96C200E3D18A /* RNNModalAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 50762D06205E96C200E3D18A /* RNNModalAnimation.h */; };
83 85
 		50762D09205E96C200E3D18A /* RNNModalAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 50762D07205E96C200E3D18A /* RNNModalAnimation.m */; };
84 86
 		507E7D57201DDD3000444E6C /* RNNAnimationOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 507E7D55201DDD3000444E6C /* RNNAnimationOptions.h */; };
@@ -266,6 +268,8 @@
266 268
 		504AFE731FFFF0540076E904 /* RNNTopTabsOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNTopTabsOptions.m; sourceTree = "<group>"; };
267 269
 		50570B242061473D006A1B5C /* RNNTitleOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNTitleOptions.h; sourceTree = "<group>"; };
268 270
 		50570B252061473D006A1B5C /* RNNTitleOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNTitleOptions.m; sourceTree = "<group>"; };
271
+		50570BE82063E09B006A1B5C /* RNNTitleViewHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNTitleViewHelper.h; sourceTree = "<group>"; };
272
+		50570BE92063E09B006A1B5C /* RNNTitleViewHelper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNTitleViewHelper.m; sourceTree = "<group>"; };
269 273
 		50762D06205E96C200E3D18A /* RNNModalAnimation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNModalAnimation.h; sourceTree = "<group>"; };
270 274
 		50762D07205E96C200E3D18A /* RNNModalAnimation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNModalAnimation.m; sourceTree = "<group>"; };
271 275
 		507E7D55201DDD3000444E6C /* RNNAnimationOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNAnimationOptions.h; sourceTree = "<group>"; };
@@ -542,6 +546,12 @@
542 546
 				E8AEDB461F58414D000F5A6A /* Animations */,
543 547
 				504AFE611FFE52EF0076E904 /* Options */,
544 548
 				50D031312005146C00386B3D /* Managers */,
549
+				5032774C2015E86D00ECD75D /* RNNNavigationEvent.h */,
550
+				5032774D2015E86D00ECD75D /* RNNNavigationEvent.m */,
551
+				50570BE82063E09B006A1B5C /* RNNTitleViewHelper.h */,
552
+				50570BE92063E09B006A1B5C /* RNNTitleViewHelper.m */,
553
+				5032775E2016302900ECD75D /* RNNComponentLifecycleEvent.h */,
554
+				5032775F2016302900ECD75D /* RNNComponentLifecycleEvent.m */,
545 555
 				26916C941E4B9CCC00D13680 /* RNNRootViewCreator.h */,
546 556
 				26916C961E4B9E7700D13680 /* RNNReactRootViewCreator.h */,
547 557
 				26916C971E4B9E7700D13680 /* RNNReactRootViewCreator.m */,
@@ -758,6 +768,7 @@
758 768
 				E8AEDB3C1F55A1C2000F5A6A /* RNNElementView.h in Headers */,
759 769
 				E8E518321F83B3E0000467AC /* RNNUtils.h in Headers */,
760 770
 				507F44201FFA8A8800D9425B /* RNNRootViewProtocol.h in Headers */,
771
+				50570BEA2063E09B006A1B5C /* RNNTitleViewHelper.h in Headers */,
761 772
 				263905CA1E4C6F440023D7D3 /* SidebarLuvocracyAnimation.h in Headers */,
762 773
 				50762D08205E96C200E3D18A /* RNNModalAnimation.h in Headers */,
763 774
 				390AD477200F499D00A8250D /* RNNSwizzles.h in Headers */,
@@ -907,6 +918,7 @@
907 918
 				7B1126A01E2D263F00F9B03B /* RNNEventEmitter.m in Sources */,
908 919
 				A7626BFD1FC2FB2C00492FB8 /* RNNTopBarOptions.m in Sources */,
909 920
 				263905CB1E4C6F440023D7D3 /* SidebarLuvocracyAnimation.m in Sources */,
921
+				50570BEB2063E09B006A1B5C /* RNNTitleViewHelper.m in Sources */,
910 922
 				263905E71E4CAC950023D7D3 /* RNNSideMenuChildVC.m in Sources */,
911 923
 				390AD478200F499D00A8250D /* RNNSwizzles.m in Sources */,
912 924
 				7BA500751E2544B9001B9E1B /* ReactNativeNavigation.m in Sources */,