9
9
10
10
#include < TargetConditionals.h>
11
11
12
+ #import < objc/runtime.h>
13
+
12
14
#import < React/RCTBridge.h>
13
15
16
+ IMP RTASwizzleSelector (Class class, SEL originalSelector, SEL swizzledSelector)
17
+ {
18
+ Method originalMethod = class_getInstanceMethod (class, originalSelector);
19
+ IMP originalImpl = method_getImplementation (originalMethod);
20
+
21
+ Method swizzledMethod = class_getInstanceMethod (class, swizzledSelector);
22
+
23
+ BOOL didAddMethod = class_addMethod (class,
24
+ originalSelector,
25
+ method_getImplementation (swizzledMethod),
26
+ method_getTypeEncoding (swizzledMethod));
27
+ if (didAddMethod) {
28
+ const char *type = method_getTypeEncoding (originalMethod);
29
+ class_replaceMethod (class, swizzledSelector, originalImpl, type);
30
+ } else {
31
+ method_exchangeImplementations (originalMethod, swizzledMethod);
32
+ }
33
+
34
+ return originalImpl;
35
+ }
36
+
37
+ // MARK: - [0.62] RCTTriggerReloadCommandListeners replaces -[RCTBridge reload]
38
+
14
39
// `RCTReloadCommand.h` is excluded from `react-native-macos`
15
40
// See https://github.com/microsoft/react-native-macos/blob/v0.61.39/React-Core.podspec#L66
16
41
#if REACT_NATIVE_VERSION >= 6200
@@ -25,3 +50,64 @@ void RTATriggerReloadCommand(RCTBridge *bridge, NSString *reason)
25
50
RCTTriggerReloadCommandListeners (reason);
26
51
#endif
27
52
}
53
+
54
+ // MARK: - [0.63.2] Images do not render on iOS 14
55
+ // See https://github.com/facebook/react-native/pull/29420
56
+
57
+ #if !TARGET_OS_OSX && REACT_NATIVE_VERSION < 6302
58
+
59
+ #import < React/RCTUIImageViewAnimated.h>
60
+
61
+ @implementation RCTUIImageViewAnimated (ReactTestApp)
62
+
63
+ static void (*orig_displayLayer)(id , SEL , CALayer *);
64
+
65
+ + (void )initialize
66
+ {
67
+ if ([self class ] != [RCTUIImageViewAnimated class ]) {
68
+ return ;
69
+ }
70
+
71
+ if (@available (iOS 14.0 , *)) {
72
+ static dispatch_once_t onceToken;
73
+ dispatch_once (&onceToken, ^{
74
+ IMP impl = RTASwizzleSelector (
75
+ [self class ], @selector (displayLayer: ), @selector (rta_displayLayer: ));
76
+ orig_displayLayer = (void (*)(id , SEL , CALayer *))impl;
77
+ });
78
+ }
79
+ }
80
+
81
+ - (void )rta_displayLayer : (CALayer *)layer
82
+ {
83
+ /* The fix for images not rendering is to let UIImageView handle it when we
84
+ * are not animating. The following change was made in react-native#29420:
85
+ *
86
+ * diff --git a/Libraries/Image/RCTUIImageViewAnimated.m b/Libraries/Image/RCTUIImageViewAnimated.m
87
+ * index 93c6a2f02f5..f6fb5bc60cc 100644
88
+ * --- a/Libraries/Image/RCTUIImageViewAnimated.m
89
+ * +++ b/Libraries/Image/RCTUIImageViewAnimated.m
90
+ * @@ -285,6 +285,8 @@ static NSUInteger RCTDeviceFreeMemory() {
91
+ * if (_currentFrame) {
92
+ * layer.contentsScale = self.animatedImageScale;
93
+ * layer.contents = (__bridge id)_currentFrame.CGImage;
94
+ * + } else {
95
+ * + [super displayLayer:layer];
96
+ * }
97
+ * }
98
+ *
99
+ * The patch calls `super` when `_currentFrame` is `nil`. For our monkey
100
+ * patch, we'll invert the logic to let the original method handle the case
101
+ * where `_currentFrame` is missing.
102
+ */
103
+ if ([self respondsToSelector: @selector (currentFrame )] &&
104
+ [self performSelector: @selector (currentFrame )] == nil ) {
105
+ [super displayLayer: layer];
106
+ } else {
107
+ orig_displayLayer (self, @selector (displayLayer: ), layer);
108
+ }
109
+ }
110
+
111
+ @end
112
+
113
+ #endif
0 commit comments