Просмотр исходного кода

Extend SafeAreaView to support iOS 10

Leo Natan 6 лет назад
Родитель
Сommit
a0e6bcccc9
No account linked to committer's email address
2 измененных файлов: 124 добавлений и 0 удалений
  1. 2
    0
      .gitignore
  2. 122
    0
      ios/RNNSwizzles.m

+ 2
- 0
.gitignore Просмотреть файл

@@ -215,3 +215,5 @@ android/keystores/debug.keystore
215 215
 jsconfig.json
216 216
 .vscode/launchReactNative.js
217 217
 example/yarn.lock
218
+example/package-lock.json
219
+/package-lock.json

+ 122
- 0
ios/RNNSwizzles.m Просмотреть файл

@@ -50,3 +50,125 @@ static id (*__SWZ_initWithEventDispatcher_orig)(id self, SEL _cmd, id eventDispa
50 50
 
51 51
 @end
52 52
 
53
+
54
+#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */
55
+
56
+@interface UIView (OS10SafeAreaSupport) @end
57
+
58
+@implementation UIView (OS10SafeAreaSupport)
59
+
60
+- (UIEdgeInsets)_ln_safeAreaInsets
61
+{
62
+	static NSString* const b64 = @"X3ZpZXdDb250cm9sbGVyRm9yQW5jZXN0b3I=";
63
+	UIViewController* vc = [self valueForKey:[[NSString alloc] initWithData:[[NSData alloc] initWithBase64EncodedString:b64 options:0] encoding:NSUTF8StringEncoding]];
64
+	if(vc == nil)
65
+	{
66
+		return UIEdgeInsetsZero;
67
+	}
68
+	
69
+	CGRect myFrameInVCView = [vc.view convertRect:self.bounds fromView:self];
70
+	
71
+	UIEdgeInsets rv = UIEdgeInsetsZero;
72
+	rv.top = CGRectIntersection(myFrameInVCView, CGRectMake(0, 0, vc.view.bounds.size.width, vc.topLayoutGuide.length)).size.height;
73
+	rv.bottom = CGRectIntersection(myFrameInVCView, CGRectMake(0, vc.view.bounds.size.height - vc.bottomLayoutGuide.length, vc.view.bounds.size.width, vc.bottomLayoutGuide.length)).size.height;
74
+	
75
+	if (@available(iOS 11.0, *))
76
+	{
77
+		NSParameterAssert(UIEdgeInsetsEqualToEdgeInsets(self.safeAreaInsets, rv));
78
+	}
79
+	
80
+	return rv;
81
+}
82
+
83
+- (void)_ln_triggerSafeAreaInsetsDidChange
84
+{
85
+	if([self respondsToSelector:@selector(safeAreaInsetsDidChange)])
86
+	{
87
+		[self performSelector:@selector(safeAreaInsetsDidChange)];
88
+	}
89
+}
90
+
91
+- (void)_ln_layoutSubviews
92
+{
93
+	[self _ln_triggerSafeAreaInsetsDidChange];
94
+	
95
+	struct objc_super super = {.receiver = self, .super_class = class_getSuperclass(object_getClass(self))};
96
+	void (*super_class)(struct objc_super*, SEL) = (void*)objc_msgSendSuper;
97
+	super_class(&super, _cmd);
98
+}
99
+
100
+- (void)_ln_setFrame:(CGRect)frame
101
+{
102
+	[self _ln_triggerSafeAreaInsetsDidChange];
103
+	
104
+	struct objc_super super = {.receiver = self, .super_class = class_getSuperclass(object_getClass(self))};
105
+	void (*super_class)(struct objc_super*, SEL, CGRect) = (void*)objc_msgSendSuper;
106
+	super_class(&super, _cmd, frame);
107
+}
108
+
109
+- (void)_ln_setCenter:(CGPoint)center
110
+{
111
+	[self _ln_triggerSafeAreaInsetsDidChange];
112
+	
113
+	struct objc_super super = {.receiver = self, .super_class = class_getSuperclass(object_getClass(self))};
114
+	void (*super_class)(struct objc_super*, SEL, CGPoint) = (void*)objc_msgSendSuper;
115
+	super_class(&super, _cmd, center);
116
+}
117
+
118
+- (void)_ln_setBounds:(CGRect)bounds
119
+{
120
+	[self _ln_triggerSafeAreaInsetsDidChange];
121
+	
122
+	struct objc_super super = {.receiver = self, .super_class = class_getSuperclass(object_getClass(self))};
123
+	void (*super_class)(struct objc_super*, SEL, CGRect) = (void*)objc_msgSendSuper;
124
+	super_class(&super, _cmd, bounds);
125
+}
126
+
127
++ (void)load
128
+{
129
+	static dispatch_once_t onceToken;
130
+	dispatch_once(&onceToken, ^{
131
+		if(NSProcessInfo.processInfo.operatingSystemVersion.majorVersion < 11)
132
+		{
133
+			Class cls = NSClassFromString(@"RCTSafeAreaView");
134
+			if(cls == NULL)
135
+			{
136
+				return;
137
+			}
138
+			
139
+			Method m = class_getInstanceMethod([UIView class], @selector(_ln_safeAreaInsets));
140
+			if(NO == class_addMethod(cls, @selector(safeAreaInsets), method_getImplementation(m), method_getTypeEncoding(m)))
141
+			{
142
+				return;
143
+			}
144
+			
145
+			m = class_getInstanceMethod([UIView class], @selector(_ln_layoutSubviews));
146
+			if(NO == class_addMethod(cls, @selector(layoutSubviews), method_getImplementation(m), method_getTypeEncoding(m)))
147
+			{
148
+				return;
149
+			}
150
+			
151
+			m = class_getInstanceMethod([UIView class], @selector(_ln_setFrame:));
152
+			if(NO == class_addMethod(cls, @selector(setFrame:), method_getImplementation(m), method_getTypeEncoding(m)))
153
+			{
154
+				return;
155
+			}
156
+			
157
+			m = class_getInstanceMethod([UIView class], @selector(_ln_setCenter:));
158
+			if(NO == class_addMethod(cls, @selector(setCenter:), method_getImplementation(m), method_getTypeEncoding(m)))
159
+			{
160
+				return;
161
+			}
162
+			
163
+			m = class_getInstanceMethod([UIView class], @selector(_ln_setBounds:));
164
+			if(NO == class_addMethod(cls, @selector(setBounds:), method_getImplementation(m), method_getTypeEncoding(m)))
165
+			{
166
+				return;
167
+			}
168
+		}
169
+	});
170
+}
171
+
172
+@end
173
+
174
+#endif