Browse Source

Update swizzles for RN scrollview

Leo Natan 6 years ago
parent
commit
fb212e968d
No account linked to committer's email address
1 changed files with 60 additions and 15 deletions
  1. 60
    15
      ios/RNNSwizzles.m

+ 60
- 15
ios/RNNSwizzles.m View File

@@ -14,6 +14,36 @@
14 14
 
15 15
 #if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_10_3
16 16
 static id (*__SWZ_initWithEventDispatcher_orig)(id self, SEL _cmd, id eventDispatcher);
17
+static void (*__SWZ_setFrame_orig)(id self, SEL _cmd, CGRect frame);
18
+
19
+static void __RNN_setFrame_orig(UIScrollView* self, SEL _cmd, CGRect frame)
20
+{
21
+	CGPoint originalOffset = self.contentOffset;
22
+	
23
+	__SWZ_setFrame_orig(self, _cmd, frame);
24
+	
25
+	UIEdgeInsets contentInset;
26
+	if (@available(iOS 11.0, *)) {
27
+		contentInset = self.adjustedContentInset;
28
+	} else {
29
+		contentInset = self.contentInset;
30
+	}
31
+	
32
+	CGSize contentSize = self.contentSize;
33
+	
34
+	// If contentSize has not been measured yet we can't check bounds.
35
+	if (CGSizeEqualToSize(contentSize, CGSizeZero))
36
+	{
37
+		self.contentOffset = originalOffset;
38
+	}
39
+	else
40
+	{
41
+		// Make sure offset don't exceed bounds. This could happen on screen rotation.
42
+		CGSize boundsSize = self.bounds.size;
43
+		self.contentOffset = CGPointMake(MAX(-contentInset.left, MIN(contentSize.width - boundsSize.width + contentInset.right, originalOffset.x)),
44
+										 MAX(-contentInset.top, MIN(contentSize.height - boundsSize.height + contentInset.bottom, originalOffset.y)));
45
+	}
46
+}
17 47
 
18 48
 - (id)__swz_initWithEventDispatcher:(id)eventDispatcher
19 49
 {
@@ -30,21 +60,36 @@ static id (*__SWZ_initWithEventDispatcher_orig)(id self, SEL _cmd, id eventDispa
30 60
 + (void)applySwizzles
31 61
 {
32 62
 #if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_10_3
33
-	Class cls = NSClassFromString(@"RCTScrollView");
34
-	if(cls == NULL)
35
-	{
36
-		return;
37
-	}
38
-	Method m1 = class_getInstanceMethod(cls, NSSelectorFromString(@"initWithEventDispatcher:"));
39
-	
40
-	if(m1 == NULL)
41
-	{
42
-		return;
43
-	}
44
-	
45
-	__SWZ_initWithEventDispatcher_orig = (void*)method_getImplementation(m1);
46
-	Method m2 = class_getInstanceMethod([RNNSwizzles class], NSSelectorFromString(@"__swz_initWithEventDispatcher:"));
47
-	method_exchangeImplementations(m1, m2);
63
+	static dispatch_once_t onceToken;
64
+	dispatch_once(&onceToken, ^{
65
+		Class cls = NSClassFromString(@"RCTScrollView");
66
+		if(cls == NULL)
67
+		{
68
+			return;
69
+		}
70
+		Method m1 = class_getInstanceMethod(cls, NSSelectorFromString(@"initWithEventDispatcher:"));
71
+		
72
+		if(m1 == NULL)
73
+		{
74
+			return;
75
+		}
76
+		
77
+		__SWZ_initWithEventDispatcher_orig = (void*)method_getImplementation(m1);
78
+		Method m2 = class_getInstanceMethod([RNNSwizzles class], NSSelectorFromString(@"__swz_initWithEventDispatcher:"));
79
+		method_exchangeImplementations(m1, m2);
80
+		
81
+		if (@available(iOS 11.0, *)) {
82
+			cls = NSClassFromString(@"RCTCustomScrollView");
83
+			if(cls == NULL)
84
+			{
85
+				return;
86
+			}
87
+			
88
+			m1 = class_getInstanceMethod(cls, @selector(setFrame:));
89
+			__SWZ_setFrame_orig = (void*)method_getImplementation(m1);
90
+			method_setImplementation(m1, (IMP)__RNN_setFrame_orig);
91
+		}
92
+	});
48 93
 #endif
49 94
 }
50 95