14
14
#import < React/RCTEventDispatcherProtocol.h>
15
15
#import < React/RCTInitializing.h>
16
16
#import < React/RCTInvalidating.h>
17
- #import < React/RCTKeyWindowValuesProxy.h>
18
17
#import < React/RCTUtils.h>
19
- #import < React/RCTWindowSafeAreaProxy.h>
20
18
#import < atomic>
21
19
22
20
#import " CoreModulesPlugins.h"
@@ -31,23 +29,40 @@ @implementation RCTDeviceInfo {
31
29
NSDictionary *_currentInterfaceDimensions;
32
30
BOOL _isFullscreen;
33
31
std::atomic<BOOL > _invalidated;
32
+ NSDictionary *_constants;
33
+
34
+ __weak UIWindow *_applicationWindow;
34
35
}
35
36
37
+ static NSString *const kFrameKeyPath = @" frame" ;
38
+
36
39
@synthesize moduleRegistry = _moduleRegistry;
37
40
38
41
RCT_EXPORT_MODULE ()
39
42
40
43
- (instancetype )init
41
44
{
42
45
if (self = [super init ]) {
43
- [[RCTKeyWindowValuesProxy sharedInstance ] startObservingWindowSizeIfNecessary ];
46
+ _applicationWindow = RCTKeyWindow ();
47
+ [_applicationWindow addObserver: self forKeyPath: kFrameKeyPath options: NSKeyValueObservingOptionNew context: nil ];
44
48
}
45
49
return self;
46
50
}
47
51
52
+ - (void )observeValueForKeyPath : (NSString *)keyPath
53
+ ofObject : (id )object
54
+ change : (NSDictionary *)change
55
+ context : (void *)context
56
+ {
57
+ if ([keyPath isEqualToString: kFrameKeyPath ]) {
58
+ [self interfaceFrameDidChange ];
59
+ [[NSNotificationCenter defaultCenter ] postNotificationName: RCTWindowFrameDidChangeNotification object: self ];
60
+ }
61
+ }
62
+
48
63
+ (BOOL )requiresMainQueueSetup
49
64
{
50
- return NO ;
65
+ return YES ;
51
66
}
52
67
53
68
- (dispatch_queue_t )methodQueue
@@ -81,7 +96,7 @@ - (void)initialize
81
96
82
97
#if TARGET_OS_IOS
83
98
84
- _currentInterfaceOrientation = [RCTKeyWindowValuesProxy sharedInstance ]. currentInterfaceOrientation ;
99
+ _currentInterfaceOrientation = RCTKeyWindow (). windowScene . interfaceOrientation ;
85
100
86
101
[[NSNotificationCenter defaultCenter ] addObserver: self
87
102
selector: @selector (interfaceFrameDidChange )
@@ -98,6 +113,15 @@ - (void)initialize
98
113
selector: @selector (invalidate )
99
114
name: RCTBridgeWillInvalidateModulesNotification
100
115
object: nil ];
116
+
117
+ _constants = @{
118
+ @" Dimensions" : [self _exportedDimensions ],
119
+ // Note:
120
+ // This prop is deprecated and will be removed in a future release.
121
+ // Please use this only for a quick and temporary solution.
122
+ // Use <SafeAreaView> instead.
123
+ @" isIPhoneX_deprecated" : @(RCTIsIPhoneNotched ()),
124
+ };
101
125
}
102
126
103
127
- (void )invalidate
@@ -120,6 +144,8 @@ - (void)_cleanupObservers
120
144
121
145
[[NSNotificationCenter defaultCenter ] removeObserver: self name: RCTBridgeWillInvalidateModulesNotification object: nil ];
122
146
147
+ [_applicationWindow removeObserver: self forKeyPath: kFrameKeyPath ];
148
+
123
149
#if TARGET_OS_IOS
124
150
[[NSNotificationCenter defaultCenter ] removeObserver: self name: UIDeviceOrientationDidChangeNotification object: nil ];
125
151
#endif
@@ -132,8 +158,13 @@ static BOOL RCTIsIPhoneNotched()
132
158
133
159
#if TARGET_OS_IOS
134
160
dispatch_once (&onceToken, ^{
161
+ RCTAssertMainQueue ();
162
+
135
163
// 20pt is the top safeArea value in non-notched devices
136
- isIPhoneNotched = [RCTWindowSafeAreaProxy sharedInstance ].currentSafeAreaInsets .top > 20 ;
164
+ UIWindow *keyWindow = RCTKeyWindow ();
165
+ if (keyWindow) {
166
+ isIPhoneNotched = keyWindow.safeAreaInsets .top > 20 ;
167
+ }
137
168
});
138
169
#endif
139
170
@@ -142,11 +173,13 @@ static BOOL RCTIsIPhoneNotched()
142
173
143
174
static NSDictionary *RCTExportedDimensions (CGFloat fontScale)
144
175
{
176
+ RCTAssertMainQueue ();
145
177
UIScreen *mainScreen = UIScreen.mainScreen ;
146
178
CGSize screenSize = mainScreen.bounds .size ;
179
+ UIView *mainWindow = RCTKeyWindow ();
147
180
148
181
// We fallback to screen size if a key window is not found.
149
- CGSize windowSize = [RCTKeyWindowValuesProxy sharedInstance ]. windowSize ;
182
+ CGSize windowSize = mainWindow ? mainWindow. bounds . size : screenSize ;
150
183
151
184
NSDictionary <NSString *, NSNumber *> *dimsWindow = @{
152
185
@" width" : @(windowSize.width ),
@@ -170,7 +203,10 @@ - (NSDictionary *)_exportedDimensions
170
203
RCTAssert (_moduleRegistry, @" Failed to get exported dimensions: RCTModuleRegistry is nil" );
171
204
RCTAccessibilityManager *accessibilityManager =
172
205
(RCTAccessibilityManager *)[_moduleRegistry moduleForName: " AccessibilityManager" ];
173
- RCTAssert (accessibilityManager, @" Failed to get exported dimensions: AccessibilityManager is nil" );
206
+ // TOOD(T225745315): For some reason, accessibilityManager is nil in some cases.
207
+ // We default the fontScale to 1.0 in this case. This should be okay: if we assume
208
+ // that accessibilityManager will eventually become available, js will eventually
209
+ // be updated with the correct fontScale.
174
210
CGFloat fontScale = accessibilityManager ? accessibilityManager.multiplier : 1.0 ;
175
211
return RCTExportedDimensions (fontScale);
176
212
}
@@ -182,14 +218,7 @@ - (NSDictionary *)_exportedDimensions
182
218
183
219
- (NSDictionary <NSString *, id> *)getConstants
184
220
{
185
- return @{
186
- @" Dimensions" : [self _exportedDimensions ],
187
- // Note:
188
- // This prop is deprecated and will be removed in a future release.
189
- // Please use this only for a quick and temporary solution.
190
- // Use <SafeAreaView> instead.
191
- @" isIPhoneX_deprecated" : @(RCTIsIPhoneNotched ()),
192
- };
221
+ return _constants;
193
222
}
194
223
195
224
- (void )didReceiveNewContentSizeMultiplier
@@ -209,10 +238,11 @@ - (void)didReceiveNewContentSizeMultiplier
209
238
- (void )interfaceOrientationDidChange
210
239
{
211
240
#if TARGET_OS_IOS && !TARGET_OS_MACCATALYST
212
- UIWindow *keyWindow = RCTKeyWindow ();
213
- UIInterfaceOrientation nextOrientation = keyWindow .windowScene .interfaceOrientation ;
241
+ UIApplication *application = RCTSharedApplication ();
242
+ UIInterfaceOrientation nextOrientation = RCTKeyWindow () .windowScene .interfaceOrientation ;
214
243
215
- BOOL isRunningInFullScreen = CGRectEqualToRect (keyWindow.frame , keyWindow.screen .bounds );
244
+ BOOL isRunningInFullScreen =
245
+ CGRectEqualToRect (application.delegate .window .frame , application.delegate .window .screen .bounds );
216
246
// We are catching here two situations for multitasking view:
217
247
// a) The app is in Split View and the container gets resized -> !isRunningInFullScreen
218
248
// b) The app changes to/from fullscreen example: App runs in slide over mode and goes into fullscreen->
@@ -275,4 +305,4 @@ - (void)_interfaceFrameDidChange
275
305
Class RCTDeviceInfoCls (void )
276
306
{
277
307
return RCTDeviceInfo.class ;
278
- }
308
+ }
0 commit comments