|
11 | 11 | #import <React/RCTEventDispatcherProtocol.h> |
12 | 12 | #import <React/RCTInitializing.h> |
13 | 13 | #import <React/RCTLog.h> |
| 14 | +#import <React/RCTStatusBarAppearance.h> |
14 | 15 | #import <React/RCTUtils.h> |
15 | 16 |
|
16 | 17 | #import <FBReactNativeSpec/FBReactNativeSpec.h> |
@@ -68,6 +69,28 @@ static BOOL RCTViewControllerBasedStatusBarAppearance() |
68 | 69 | return value; |
69 | 70 | } |
70 | 71 |
|
| 72 | +// UIKit makes the app-level setters no-ops only for apps built with the iOS 27 SDK. |
| 73 | +static BOOL RCTAppLevelStatusBarIsNoOp() |
| 74 | +{ |
| 75 | +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 270000 |
| 76 | + if (@available(iOS 27.0, *)) { |
| 77 | + return YES; |
| 78 | + } |
| 79 | +#endif |
| 80 | + return NO; |
| 81 | +} |
| 82 | + |
| 83 | +static void RCTWarnAppLevelStatusBarUnavailable() |
| 84 | +{ |
| 85 | + static dispatch_once_t onceToken; |
| 86 | + dispatch_once(&onceToken, ^{ |
| 87 | + RCTLogWarn( |
| 88 | + @"StatusBar has no effect because UIViewControllerBasedStatusBarAppearance is NO in Info.plist. " |
| 89 | + @"Apps built with the iOS 27 SDK cannot use the app-level status bar API that this setting uses. " |
| 90 | + @"Set UIViewControllerBasedStatusBarAppearance to YES to control the status bar from JavaScript."); |
| 91 | + }); |
| 92 | +} |
| 93 | + |
71 | 94 | RCT_EXPORT_MODULE() |
72 | 95 |
|
73 | 96 | + (BOOL)requiresMainQueueSetup |
@@ -147,30 +170,32 @@ - (void)setStyle:(NSString *)style animated:(BOOL)animated |
147 | 170 | { |
148 | 171 | dispatch_async(dispatch_get_main_queue(), ^{ |
149 | 172 | UIStatusBarStyle statusBarStyle = [RCTConvert UIStatusBarStyle:style]; |
150 | | - if (RCTViewControllerBasedStatusBarAppearance()) { |
151 | | - RCTLogWarn(@"RCTStatusBarManager is a no-op when \ |
152 | | - UIViewControllerBasedStatusBarAppearance is YES; set the status bar from your view controller instead"); |
153 | | - } else { |
| 173 | + [RCTStatusBarAppearance setStyle:statusBarStyle animated:animated]; |
| 174 | + if (!RCTViewControllerBasedStatusBarAppearance()) { |
154 | 175 | #pragma clang diagnostic push |
155 | 176 | #pragma clang diagnostic ignored "-Wdeprecated-declarations" |
156 | 177 | [RCTSharedApplication() setStatusBarStyle:statusBarStyle animated:animated]; |
157 | | - } |
158 | 178 | #pragma clang diagnostic pop |
| 179 | + if (RCTAppLevelStatusBarIsNoOp()) { |
| 180 | + RCTWarnAppLevelStatusBarUnavailable(); |
| 181 | + } |
| 182 | + } |
159 | 183 | }); |
160 | 184 | } |
161 | 185 |
|
162 | 186 | - (void)setHidden:(BOOL)hidden withAnimation:(NSString *)withAnimation |
163 | 187 | { |
164 | 188 | dispatch_async(dispatch_get_main_queue(), ^{ |
165 | 189 | UIStatusBarAnimation animation = [RCTConvert UIStatusBarAnimation:withAnimation]; |
166 | | - if (RCTViewControllerBasedStatusBarAppearance()) { |
167 | | - RCTLogWarn(@"RCTStatusBarManager is a no-op when \ |
168 | | - UIViewControllerBasedStatusBarAppearance is YES; set the status bar from your view controller instead"); |
169 | | - } else { |
| 190 | + [RCTStatusBarAppearance setHidden:hidden withAnimation:animation]; |
| 191 | + if (!RCTViewControllerBasedStatusBarAppearance()) { |
170 | 192 | #pragma clang diagnostic push |
171 | 193 | #pragma clang diagnostic ignored "-Wdeprecated-declarations" |
172 | 194 | [RCTSharedApplication() setStatusBarHidden:hidden withAnimation:animation]; |
173 | 195 | #pragma clang diagnostic pop |
| 196 | + if (RCTAppLevelStatusBarIsNoOp()) { |
| 197 | + RCTWarnAppLevelStatusBarUnavailable(); |
| 198 | + } |
174 | 199 | } |
175 | 200 | }); |
176 | 201 | } |
|
0 commit comments