mirror of
https://github.com/status-im/react-native.git
synced 2025-02-04 13:44:04 +00:00
Apple TV support 1: existing Objective C code should compile for tvOS
Summary: First commit for Apple TV support: changes to existing Objective-C code so that it will compile correctly for tvOS. Closes https://github.com/facebook/react-native/pull/9649 Differential Revision: D3916021 Pulled By: javache fbshipit-source-id: 34acc9daf3efff835ffe38c43ba5d4098a02c830
This commit is contained in:
parent
339531065f
commit
d368ebfab2
@ -19,7 +19,9 @@
|
||||
#import "RCTJavaScriptLoader.h"
|
||||
#import "RCTLinkingManager.h"
|
||||
#import "RCTRootView.h"
|
||||
#if !TARGET_OS_TV
|
||||
#import "RCTPushNotificationManager.h"
|
||||
#endif
|
||||
|
||||
@interface AppDelegate() <RCTBridgeDelegate>
|
||||
|
||||
@ -79,6 +81,8 @@
|
||||
|
||||
# pragma mark - Push Notifications
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
|
||||
// Required to register for notifications
|
||||
- (void)application:(__unused UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
|
||||
{
|
||||
@ -109,4 +113,6 @@
|
||||
[RCTPushNotificationManager didReceiveLocalNotification:notification];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
@ -64,7 +64,9 @@ RCT_EXPORT_MODULE();
|
||||
[_resizableRootView setSizeFlexibility:RCTRootViewSizeFlexibilityHeight];
|
||||
|
||||
_currentSizeTextView = [UITextView new];
|
||||
#ifndef TARGET_OS_TV
|
||||
_currentSizeTextView.editable = NO;
|
||||
#endif
|
||||
_currentSizeTextView.text = @"Resizable view has not been resized yet";
|
||||
_currentSizeTextView.textColor = [UIColor blackColor];
|
||||
_currentSizeTextView.backgroundColor = [UIColor whiteColor];
|
||||
|
@ -63,11 +63,13 @@
|
||||
|
||||
- (void)testFamily
|
||||
{
|
||||
#if !TARGET_OS_TV
|
||||
{
|
||||
UIFont *expected = [UIFont fontWithName:@"Cochin" size:14];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontFamily": @"Cochin"}];
|
||||
RCTAssertEqualFonts(expected, result);
|
||||
}
|
||||
#endif
|
||||
{
|
||||
UIFont *expected = [UIFont fontWithName:@"HelveticaNeue" size:14];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontFamily": @"Helvetica Neue"}];
|
||||
@ -135,6 +137,7 @@
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontFamily": @"HelveticaNeue-Bold", @"fontWeight": @"normal"}];
|
||||
RCTAssertEqualFonts(expected, result);
|
||||
}
|
||||
#if !TARGET_OS_TV
|
||||
{
|
||||
UIFont *expected = [UIFont fontWithName:@"Cochin-Bold" size:14];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontFamily": @"Cochin", @"fontWeight": @"700"}];
|
||||
@ -145,6 +148,7 @@
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontFamily": @"Cochin", @"fontWeight": @"100"}];
|
||||
RCTAssertEqualFonts(expected, result);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)testFamilyAndStyle
|
||||
|
@ -96,12 +96,16 @@
|
||||
_textView = [[RCTUITextView alloc] initWithFrame:CGRectZero];
|
||||
_textView.backgroundColor = [UIColor clearColor];
|
||||
_textView.textColor = [UIColor blackColor];
|
||||
#if !TARGET_OS_TV
|
||||
_textView.scrollsToTop = NO;
|
||||
#endif
|
||||
_textView.scrollEnabled = NO;
|
||||
_textView.delegate = self;
|
||||
|
||||
_scrollView = [[UIScrollView alloc] initWithFrame:CGRectZero];
|
||||
#if !TARGET_OS_TV
|
||||
_scrollView.scrollsToTop = NO;
|
||||
#endif
|
||||
[_scrollView addSubview:_textView];
|
||||
|
||||
[self addSubview:_scrollView];
|
||||
@ -283,11 +287,13 @@ static NSAttributedString *removeReactTagFromString(NSAttributedString *string)
|
||||
|
||||
if (_placeholder) {
|
||||
_placeholderView = [[UITextView alloc] initWithFrame:self.bounds];
|
||||
_placeholderView.editable = NO;
|
||||
_placeholderView.userInteractionEnabled = NO;
|
||||
_placeholderView.backgroundColor = [UIColor clearColor];
|
||||
_placeholderView.scrollEnabled = NO;
|
||||
#if !TARGET_OS_TV
|
||||
_placeholderView.editable = NO;
|
||||
_placeholderView.scrollsToTop = NO;
|
||||
#endif
|
||||
_placeholderView.attributedText =
|
||||
[[NSAttributedString alloc] initWithString:_placeholder attributes:@{
|
||||
NSFontAttributeName : (_textView.font ? _textView.font : [self defaultPlaceholderFont]),
|
||||
|
@ -70,8 +70,11 @@ RCT_EXPORT_MODULE()
|
||||
[_socket setDelegateDispatchQueue:_jsQueue];
|
||||
|
||||
NSURL *startDevToolsURL = [NSURL URLWithString:@"/launch-js-devtools" relativeToURL:_url];
|
||||
[NSURLConnection connectionWithRequest:[NSURLRequest requestWithURL:startDevToolsURL] delegate:nil];
|
||||
|
||||
NSURLSession *session = [NSURLSession sharedSession];
|
||||
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:[NSURLRequest requestWithURL:startDevToolsURL]
|
||||
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error){}];
|
||||
[dataTask resume];
|
||||
if (![self connectToProxy]) {
|
||||
RCTLogError(@"Connection to %@ timed out. Are you running node proxy? If "
|
||||
"you are running on the device, check if you have the right IP "
|
||||
|
@ -72,10 +72,14 @@ typedef NSURL RCTFileURL;
|
||||
+ (UIKeyboardType)UIKeyboardType:(id)json;
|
||||
+ (UIKeyboardAppearance)UIKeyboardAppearance:(id)json;
|
||||
+ (UIReturnKeyType)UIReturnKeyType:(id)json;
|
||||
#if !TARGET_OS_TV
|
||||
+ (UIDataDetectorTypes)UIDataDetectorTypes:(id)json;
|
||||
#endif
|
||||
|
||||
+ (UIViewContentMode)UIViewContentMode:(id)json;
|
||||
#if !TARGET_OS_TV
|
||||
+ (UIBarStyle)UIBarStyle:(id)json;
|
||||
#endif
|
||||
|
||||
+ (CGFloat)CGFloat:(id)json;
|
||||
+ (CGPoint)CGPoint:(id)json;
|
||||
|
@ -330,6 +330,7 @@ RCT_ENUM_CONVERTER(UIKeyboardType, (@{
|
||||
@"numeric": @(UIKeyboardTypeDecimalPad),
|
||||
}), UIKeyboardTypeDefault, integerValue)
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
RCT_MULTI_ENUM_CONVERTER(UIDataDetectorTypes, (@{
|
||||
@"phoneNumber": @(UIDataDetectorTypePhoneNumber),
|
||||
@"link": @(UIDataDetectorTypeLink),
|
||||
@ -338,6 +339,7 @@ RCT_MULTI_ENUM_CONVERTER(UIDataDetectorTypes, (@{
|
||||
@"none": @(UIDataDetectorTypeNone),
|
||||
@"all": @(UIDataDetectorTypeAll),
|
||||
}), UIDataDetectorTypePhoneNumber, unsignedLongLongValue)
|
||||
#endif
|
||||
|
||||
RCT_ENUM_CONVERTER(UIKeyboardAppearance, (@{
|
||||
@"default": @(UIKeyboardAppearanceDefault),
|
||||
@ -379,10 +381,12 @@ RCT_ENUM_CONVERTER(UIViewContentMode, (@{
|
||||
@"stretch": @(UIViewContentModeScaleToFill),
|
||||
}), UIViewContentModeScaleAspectFill, integerValue)
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
RCT_ENUM_CONVERTER(UIBarStyle, (@{
|
||||
@"default": @(UIBarStyleDefault),
|
||||
@"black": @(UIBarStyleBlack),
|
||||
}), UIBarStyleDefault, integerValue)
|
||||
#endif
|
||||
|
||||
// TODO: normalise the use of w/width so we can do away with the alias values (#6566645)
|
||||
static void RCTConvertCGStructValue(const char *type, NSArray *fields, NSDictionary *aliases, CGFloat *result, id json)
|
||||
|
@ -92,14 +92,6 @@ RCT_EXTERN UIViewController *__nullable RCTPresentedViewController(void);
|
||||
// Does this device support force touch (aka 3D Touch)?
|
||||
RCT_EXTERN BOOL RCTForceTouchAvailable(void);
|
||||
|
||||
// Return a UIAlertView initialized with the given values
|
||||
// or nil if running in an app extension
|
||||
RCT_EXTERN UIAlertView *__nullable RCTAlertView(NSString *title,
|
||||
NSString *__nullable message,
|
||||
id __nullable delegate,
|
||||
NSString *__nullable cancelButtonTitle,
|
||||
NSArray<NSString *> *__nullable otherButtonTitles);
|
||||
|
||||
// Create an NSError in the RCTErrorDomain
|
||||
RCT_EXTERN NSError *RCTErrorWithMessage(NSString *message);
|
||||
|
||||
|
@ -493,31 +493,6 @@ BOOL RCTForceTouchAvailable(void)
|
||||
(RCTKeyWindow() ?: [UIView new]).traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable;
|
||||
}
|
||||
|
||||
UIAlertView *__nullable RCTAlertView(NSString *title,
|
||||
NSString *__nullable message,
|
||||
id __nullable delegate,
|
||||
NSString *__nullable cancelButtonTitle,
|
||||
NSArray<NSString *> *__nullable otherButtonTitles)
|
||||
{
|
||||
if (RCTRunningInAppExtension()) {
|
||||
RCTLogError(@"RCTAlertView is unavailable when running in an app extension");
|
||||
return nil;
|
||||
}
|
||||
|
||||
UIAlertView *alertView = [UIAlertView new];
|
||||
alertView.title = title;
|
||||
alertView.message = message;
|
||||
alertView.delegate = delegate;
|
||||
if (cancelButtonTitle != nil) {
|
||||
[alertView addButtonWithTitle:cancelButtonTitle];
|
||||
alertView.cancelButtonIndex = 0;
|
||||
}
|
||||
for (NSString *buttonTitle in otherButtonTitles) {
|
||||
[alertView addButtonWithTitle:buttonTitle];
|
||||
}
|
||||
return alertView;
|
||||
}
|
||||
|
||||
NSError *RCTErrorWithMessage(NSString *message)
|
||||
{
|
||||
NSDictionary<NSString *, id> *errorInfo = @{NSLocalizedDescriptionKey: message};
|
||||
|
@ -12,6 +12,14 @@
|
||||
#import "RCTBridgeModule.h"
|
||||
#import "RCTInvalidating.h"
|
||||
|
||||
typedef NS_ENUM(NSInteger, RCTAlertViewStyle) {
|
||||
RCTAlertViewStyleDefault = 0,
|
||||
RCTAlertViewStyleSecureTextInput,
|
||||
RCTAlertViewStylePlainTextInput,
|
||||
RCTAlertViewStyleLoginAndPasswordInput
|
||||
};
|
||||
|
||||
|
||||
@interface RCTAlertManager : NSObject <RCTBridgeModule, RCTInvalidating>
|
||||
|
||||
@end
|
||||
|
@ -16,22 +16,21 @@
|
||||
|
||||
@implementation RCTConvert (UIAlertViewStyle)
|
||||
|
||||
RCT_ENUM_CONVERTER(UIAlertViewStyle, (@{
|
||||
@"default": @(UIAlertViewStyleDefault),
|
||||
@"secure-text": @(UIAlertViewStyleSecureTextInput),
|
||||
@"plain-text": @(UIAlertViewStylePlainTextInput),
|
||||
@"login-password": @(UIAlertViewStyleLoginAndPasswordInput),
|
||||
}), UIAlertViewStyleDefault, integerValue)
|
||||
RCT_ENUM_CONVERTER(RCTAlertViewStyle, (@{
|
||||
@"default": @(RCTAlertViewStyleDefault),
|
||||
@"secure-text": @(RCTAlertViewStyleSecureTextInput),
|
||||
@"plain-text": @(RCTAlertViewStylePlainTextInput),
|
||||
@"login-password": @(RCTAlertViewStyleLoginAndPasswordInput),
|
||||
}), RCTAlertViewStyleDefault, integerValue)
|
||||
|
||||
@end
|
||||
|
||||
@interface RCTAlertManager() <UIAlertViewDelegate>
|
||||
@interface RCTAlertManager()
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTAlertManager
|
||||
{
|
||||
NSMutableArray<UIAlertView *> *_alerts;
|
||||
NSMutableArray<UIAlertController *> *_alertControllers;
|
||||
NSMutableArray<RCTResponseSenderBlock> *_alertCallbacks;
|
||||
NSMutableArray<NSArray<NSString *> *> *_alertButtonKeys;
|
||||
@ -46,9 +45,6 @@ RCT_EXPORT_MODULE()
|
||||
|
||||
- (void)invalidate
|
||||
{
|
||||
for (UIAlertView *alert in _alerts) {
|
||||
[alert dismissWithClickedButtonIndex:0 animated:YES];
|
||||
}
|
||||
for (UIAlertController *alertController in _alertControllers) {
|
||||
[alertController.presentingViewController dismissViewControllerAnimated:YES completion:nil];
|
||||
}
|
||||
@ -73,7 +69,7 @@ RCT_EXPORT_METHOD(alertWithArgs:(NSDictionary *)args
|
||||
{
|
||||
NSString *title = [RCTConvert NSString:args[@"title"]];
|
||||
NSString *message = [RCTConvert NSString:args[@"message"]];
|
||||
UIAlertViewStyle type = [RCTConvert UIAlertViewStyle:args[@"type"]];
|
||||
RCTAlertViewStyle type = [RCTConvert RCTAlertViewStyle:args[@"type"]];
|
||||
NSArray<NSDictionary *> *buttons = [RCTConvert NSDictionaryArray:args[@"buttons"]];
|
||||
NSString *defaultValue = [RCTConvert NSString:args[@"defaultValue"]];
|
||||
NSString *cancelButtonKey = [RCTConvert NSString:args[@"cancelButtonKey"]];
|
||||
@ -85,7 +81,7 @@ RCT_EXPORT_METHOD(alertWithArgs:(NSDictionary *)args
|
||||
}
|
||||
|
||||
if (buttons.count == 0) {
|
||||
if (type == UIAlertViewStyleDefault) {
|
||||
if (type == RCTAlertViewStyleDefault) {
|
||||
buttons = @[@{@"0": RCTUIKitLocalizedString(@"OK")}];
|
||||
cancelButtonKey = @"0";
|
||||
} else {
|
||||
@ -108,14 +104,14 @@ RCT_EXPORT_METHOD(alertWithArgs:(NSDictionary *)args
|
||||
message:nil
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
switch (type) {
|
||||
case UIAlertViewStylePlainTextInput: {
|
||||
case RCTAlertViewStylePlainTextInput: {
|
||||
[alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) {
|
||||
textField.secureTextEntry = NO;
|
||||
textField.text = defaultValue;
|
||||
}];
|
||||
break;
|
||||
}
|
||||
case UIAlertViewStyleSecureTextInput: {
|
||||
case RCTAlertViewStyleSecureTextInput: {
|
||||
[alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) {
|
||||
textField.placeholder = RCTUIKitLocalizedString(@"Password");
|
||||
textField.secureTextEntry = YES;
|
||||
@ -123,7 +119,7 @@ RCT_EXPORT_METHOD(alertWithArgs:(NSDictionary *)args
|
||||
}];
|
||||
break;
|
||||
}
|
||||
case UIAlertViewStyleLoginAndPasswordInput: {
|
||||
case RCTAlertViewStyleLoginAndPasswordInput: {
|
||||
[alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) {
|
||||
textField.placeholder = RCTUIKitLocalizedString(@"Login");
|
||||
textField.text = defaultValue;
|
||||
@ -134,7 +130,7 @@ RCT_EXPORT_METHOD(alertWithArgs:(NSDictionary *)args
|
||||
}];
|
||||
break;
|
||||
}
|
||||
case UIAlertViewStyleDefault:
|
||||
case RCTAlertViewStyleDefault:
|
||||
break;
|
||||
}
|
||||
|
||||
@ -156,11 +152,11 @@ RCT_EXPORT_METHOD(alertWithArgs:(NSDictionary *)args
|
||||
style:buttonStyle
|
||||
handler:^(__unused UIAlertAction *action) {
|
||||
switch (type) {
|
||||
case UIAlertViewStylePlainTextInput:
|
||||
case UIAlertViewStyleSecureTextInput:
|
||||
case RCTAlertViewStylePlainTextInput:
|
||||
case RCTAlertViewStyleSecureTextInput:
|
||||
callback(@[buttonKey, [alertController.textFields.firstObject text]]);
|
||||
break;
|
||||
case UIAlertViewStyleLoginAndPasswordInput: {
|
||||
case RCTAlertViewStyleLoginAndPasswordInput: {
|
||||
NSDictionary<NSString *, NSString *> *loginCredentials = @{
|
||||
@"login": [alertController.textFields.firstObject text],
|
||||
@"password": [alertController.textFields.lastObject text]
|
||||
@ -168,7 +164,7 @@ RCT_EXPORT_METHOD(alertWithArgs:(NSDictionary *)args
|
||||
callback(@[buttonKey, loginCredentials]);
|
||||
break;
|
||||
}
|
||||
case UIAlertViewStyleDefault:
|
||||
case RCTAlertViewStyleDefault:
|
||||
callback(@[buttonKey]);
|
||||
break;
|
||||
}
|
||||
@ -183,37 +179,4 @@ RCT_EXPORT_METHOD(alertWithArgs:(NSDictionary *)args
|
||||
[presentingController presentViewController:alertController animated:YES completion:nil];
|
||||
}
|
||||
|
||||
#pragma mark - UIAlertViewDelegate
|
||||
|
||||
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
|
||||
{
|
||||
NSUInteger index = [_alerts indexOfObject:alertView];
|
||||
RCTAssert(index != NSNotFound, @"Dismissed alert was not recognised");
|
||||
|
||||
RCTResponseSenderBlock callback = _alertCallbacks[index];
|
||||
NSArray<NSString *> *buttonKeys = _alertButtonKeys[index];
|
||||
|
||||
switch (alertView.alertViewStyle) {
|
||||
case UIAlertViewStylePlainTextInput:
|
||||
case UIAlertViewStyleSecureTextInput:
|
||||
callback(@[buttonKeys[buttonIndex], [alertView textFieldAtIndex:0].text]);
|
||||
break;
|
||||
case UIAlertViewStyleLoginAndPasswordInput: {
|
||||
NSDictionary<NSString *, NSString *> *loginCredentials = @{
|
||||
@"login": [alertView textFieldAtIndex:0].text,
|
||||
@"password": [alertView textFieldAtIndex:1].text,
|
||||
};
|
||||
callback(@[buttonKeys[buttonIndex], loginCredentials]);
|
||||
break;
|
||||
}
|
||||
case UIAlertViewStyleDefault:
|
||||
callback(@[buttonKeys[buttonIndex]]);
|
||||
break;
|
||||
}
|
||||
|
||||
[_alerts removeObjectAtIndex:index];
|
||||
[_alertCallbacks removeObjectAtIndex:index];
|
||||
[_alertButtonKeys removeObjectAtIndex:index];
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -67,7 +67,11 @@ static NSString *RCTGetStorageDirectory()
|
||||
static NSString *storageDirectory = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
#if TARGET_OS_TV
|
||||
storageDirectory = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;
|
||||
#else
|
||||
storageDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
|
||||
#endif
|
||||
storageDirectory = [storageDirectory stringByAppendingPathComponent:RCTStorageDirectory];
|
||||
});
|
||||
return storageDirectory;
|
||||
@ -214,6 +218,10 @@ RCT_EXPORT_MODULE()
|
||||
{
|
||||
RCTAssertThread(RCTGetMethodQueue(), @"Must be executed on storage thread");
|
||||
|
||||
#if TARGET_OS_TV
|
||||
RCTLogWarn(@"Persistent storage is not supported on tvOS, your data may be removed at any point.")
|
||||
#endif
|
||||
|
||||
NSError *error = nil;
|
||||
if (!RCTHasCreatedStorageDirectory) {
|
||||
[[NSFileManager defaultManager] createDirectoryAtPath:RCTGetStorageDirectory()
|
||||
|
@ -76,8 +76,11 @@ RCT_EXPORT_METHOD(showMessage:(NSString *)message color:(UIColor *)color backgro
|
||||
if (!self->_window && !RCTRunningInTestEnvironment()) {
|
||||
CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;
|
||||
self->_window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, screenWidth, 22)];
|
||||
#if TARGET_OS_TV
|
||||
self->_window.windowLevel = UIWindowLevelNormal + 1;
|
||||
#else
|
||||
self->_window.windowLevel = UIWindowLevelStatusBar + 1;
|
||||
|
||||
#endif
|
||||
// set a root VC so rotation is supported
|
||||
self->_window.rootViewController = [UIViewController new];
|
||||
|
||||
|
@ -120,7 +120,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
||||
|
||||
@end
|
||||
|
||||
@interface RCTDevMenu () <RCTBridgeModule, UIActionSheetDelegate, RCTInvalidating, RCTWebSocketProxyDelegate>
|
||||
@interface RCTDevMenu () <RCTBridgeModule, RCTInvalidating, RCTWebSocketProxyDelegate>
|
||||
|
||||
@property (nonatomic, strong) Class executorClass;
|
||||
|
||||
@ -128,7 +128,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
||||
|
||||
@implementation RCTDevMenu
|
||||
{
|
||||
UIActionSheet *_actionSheet;
|
||||
UIAlertController *_actionSheet;
|
||||
NSUserDefaults *_defaults;
|
||||
NSMutableDictionary *_settings;
|
||||
NSURLSessionDataTask *_updateTask;
|
||||
@ -409,7 +409,7 @@ RCT_EXPORT_MODULE()
|
||||
{
|
||||
_presentedItems = nil;
|
||||
[_updateTask cancel];
|
||||
[_actionSheet dismissWithClickedButtonIndex:_actionSheet.cancelButtonIndex animated:YES];
|
||||
[_actionSheet dismissViewControllerAnimated:YES completion:^(void){}];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
||||
@ -423,7 +423,7 @@ RCT_EXPORT_MODULE()
|
||||
- (void)toggle
|
||||
{
|
||||
if (_actionSheet) {
|
||||
[_actionSheet dismissWithClickedButtonIndex:_actionSheet.cancelButtonIndex animated:YES];
|
||||
[_actionSheet dismissViewControllerAnimated:YES completion:^(void){}];
|
||||
_actionSheet = nil;
|
||||
} else {
|
||||
[self show];
|
||||
@ -458,13 +458,11 @@ RCT_EXPORT_MODULE()
|
||||
Class jsDebuggingExecutorClass = objc_lookUpClass("RCTWebSocketExecutor");
|
||||
if (!jsDebuggingExecutorClass) {
|
||||
[items addObject:[RCTDevMenuItem buttonItemWithTitle:[NSString stringWithFormat:@"%@ Debugger Unavailable", _webSocketExecutorName] handler:^{
|
||||
UIAlertView *alert = RCTAlertView(
|
||||
[NSString stringWithFormat:@"%@ Debugger Unavailable", self->_webSocketExecutorName],
|
||||
[NSString stringWithFormat:@"You need to include the RCTWebSocket library to enable %@ debugging", self->_webSocketExecutorName],
|
||||
nil,
|
||||
@"OK",
|
||||
nil);
|
||||
[alert show];
|
||||
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:[NSString stringWithFormat:@"%@ Debugger Unavailable", self->_webSocketExecutorName]
|
||||
message:[NSString stringWithFormat:@"You need to include the RCTWebSocket library to enable %@ debugging", self->_webSocketExecutorName]
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
[RCTPresentedViewController() presentViewController:alertController animated:YES completion:NULL];
|
||||
}]];
|
||||
} else {
|
||||
BOOL isDebuggingJS = _executorClass && _executorClass == jsDebuggingExecutorClass;
|
||||
@ -514,55 +512,45 @@ RCT_EXPORT_METHOD(show)
|
||||
return;
|
||||
}
|
||||
|
||||
UIActionSheet *actionSheet = [UIActionSheet new];
|
||||
actionSheet.title = @"React Native: Development";
|
||||
actionSheet.delegate = self;
|
||||
|
||||
_actionSheet = [UIAlertController alertControllerWithTitle:@"React Native: Development"
|
||||
message:@""
|
||||
preferredStyle:UIAlertControllerStyleActionSheet];
|
||||
NSArray<RCTDevMenuItem *> *items = [self menuItems];
|
||||
for (RCTDevMenuItem *item in items) {
|
||||
switch (item.type) {
|
||||
case RCTDevMenuTypeButton: {
|
||||
[actionSheet addButtonWithTitle:item.title];
|
||||
[_actionSheet addAction:[UIAlertAction actionWithTitle:item.title
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction *action) {
|
||||
// Cancel button tappped.
|
||||
[item callHandler];
|
||||
}]];
|
||||
break;
|
||||
}
|
||||
case RCTDevMenuTypeToggle: {
|
||||
BOOL selected = [item.value boolValue];
|
||||
[actionSheet addButtonWithTitle:selected? item.selectedTitle : item.title];
|
||||
[_actionSheet addAction:[UIAlertAction actionWithTitle:(selected? item.selectedTitle : item.title)
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction *action) {
|
||||
BOOL value = [self->_settings[item.key] boolValue];
|
||||
[self updateSetting:item.key value:@(!value)]; // will call handler
|
||||
}]];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[actionSheet addButtonWithTitle:@"Cancel"];
|
||||
actionSheet.cancelButtonIndex = actionSheet.numberOfButtons - 1;
|
||||
[_actionSheet addAction:[UIAlertAction actionWithTitle:@"Cancel"
|
||||
style:UIAlertActionStyleCancel
|
||||
handler:^(UIAlertAction *action) {
|
||||
}]];
|
||||
|
||||
actionSheet.actionSheetStyle = UIBarStyleBlack;
|
||||
[actionSheet showInView:RCTKeyWindow().rootViewController.view];
|
||||
_actionSheet = actionSheet;
|
||||
_presentedItems = items;
|
||||
[RCTPresentedViewController() presentViewController:_actionSheet animated:YES completion:^(void){}];
|
||||
}
|
||||
|
||||
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
|
||||
{
|
||||
_actionSheet = nil;
|
||||
if (buttonIndex == actionSheet.cancelButtonIndex) {
|
||||
return;
|
||||
}
|
||||
|
||||
RCTDevMenuItem *item = _presentedItems[buttonIndex];
|
||||
switch (item.type) {
|
||||
case RCTDevMenuTypeButton: {
|
||||
[item callHandler];
|
||||
break;
|
||||
}
|
||||
case RCTDevMenuTypeToggle: {
|
||||
BOOL value = [_settings[item.key] boolValue];
|
||||
[self updateSetting:item.key value:@(!value)]; // will call handler
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(reload)
|
||||
{
|
||||
|
@ -19,6 +19,8 @@ RCT_EXPORT_MODULE()
|
||||
|
||||
- (void)startObserving
|
||||
{
|
||||
#if !TARGET_OS_TV
|
||||
|
||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||
|
||||
#define ADD_KEYBOARD_HANDLER(NAME, SELECTOR) \
|
||||
@ -33,6 +35,8 @@ RCT_EXPORT_MODULE()
|
||||
|
||||
#undef ADD_KEYBOARD_HANDLER
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
- (NSArray<NSString *> *)supportedEvents
|
||||
@ -94,6 +98,9 @@ static NSString *RCTAnimationNameForCurve(UIViewAnimationCurve curve)
|
||||
|
||||
static NSDictionary *RCTParseKeyboardNotification(NSNotification *notification)
|
||||
{
|
||||
#if TARGET_OS_TV
|
||||
return @{};
|
||||
#else
|
||||
NSDictionary *userInfo = notification.userInfo;
|
||||
CGRect beginFrame = [userInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue];
|
||||
CGRect endFrame = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
|
||||
@ -106,4 +113,5 @@ static NSDictionary *RCTParseKeyboardNotification(NSNotification *notification)
|
||||
@"duration": @(duration * 1000.0), // ms
|
||||
@"easing": RCTAnimationNameForCurve(curve),
|
||||
};
|
||||
#endif
|
||||
}
|
||||
|
@ -60,8 +60,10 @@
|
||||
_stackTraceTableView.delegate = self;
|
||||
_stackTraceTableView.dataSource = self;
|
||||
_stackTraceTableView.backgroundColor = [UIColor clearColor];
|
||||
#if !TARGET_OS_TV
|
||||
_stackTraceTableView.separatorColor = [UIColor colorWithWhite:1 alpha:0.3];
|
||||
_stackTraceTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
|
||||
#endif
|
||||
_stackTraceTableView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
|
||||
[rootView addSubview:_stackTraceTableView];
|
||||
|
||||
@ -175,9 +177,10 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
|
||||
[fullStackTrace appendFormat:@" %@\n", [self formatFrameSource:stackFrame]];
|
||||
}
|
||||
}
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
UIPasteboard *pb = [UIPasteboard generalPasteboard];
|
||||
[pb setString:fullStackTrace];
|
||||
#endif
|
||||
}
|
||||
|
||||
- (NSString *)formatFrameSource:(RCTJSStackFrame *)stackFrame
|
||||
|
@ -99,6 +99,7 @@ static UIViewAnimationOptions UIViewAnimationOptionsFromRCTAnimationType(RCTAnim
|
||||
// `UIKeyboardWillChangeFrameNotification`s.
|
||||
+ (void)initializeStatics
|
||||
{
|
||||
#if !TARGET_OS_TV
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
@ -106,12 +107,15 @@ static UIViewAnimationOptions UIViewAnimationOptionsFromRCTAnimationType(RCTAnim
|
||||
name:UIKeyboardWillChangeFrameNotification
|
||||
object:nil];
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
+ (void)keyboardWillChangeFrame:(NSNotification *)notification
|
||||
{
|
||||
#if !TARGET_OS_TV
|
||||
NSDictionary *userInfo = notification.userInfo;
|
||||
_currentKeyboardAnimationCurve = [userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
|
||||
#endif
|
||||
}
|
||||
|
||||
- (instancetype)initWithDuration:(NSTimeInterval)duration dictionary:(NSDictionary *)config
|
||||
@ -225,8 +229,9 @@ static UIViewAnimationOptions UIViewAnimationOptionsFromRCTAnimationType(RCTAnim
|
||||
NSDictionary *_componentDataByName;
|
||||
|
||||
NSMutableSet<id<RCTComponent>> *_bridgeTransactionListeners;
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
UIInterfaceOrientation _currentInterfaceOrientation;
|
||||
#endif
|
||||
}
|
||||
|
||||
@synthesize bridge = _bridge;
|
||||
@ -244,6 +249,7 @@ RCT_EXPORT_MODULE()
|
||||
|
||||
- (void)interfaceOrientationWillChange:(NSNotification *)notification
|
||||
{
|
||||
#if !TARGET_OS_TV
|
||||
UIInterfaceOrientation nextOrientation =
|
||||
[notification.userInfo[UIApplicationStatusBarOrientationUserInfoKey] integerValue];
|
||||
|
||||
@ -260,6 +266,7 @@ RCT_EXPORT_MODULE()
|
||||
}
|
||||
|
||||
_currentInterfaceOrientation = nextOrientation;
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)invalidate
|
||||
@ -339,11 +346,13 @@ RCT_EXPORT_MODULE()
|
||||
selector:@selector(didReceiveNewContentSizeMultiplier)
|
||||
name:RCTAccessibilityManagerDidUpdateMultiplierNotification
|
||||
object:_bridge.accessibilityManager];
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(interfaceOrientationWillChange:)
|
||||
name:UIApplicationWillChangeStatusBarOrientationNotification
|
||||
object:nil];
|
||||
#endif
|
||||
|
||||
[RCTAnimation initializeStatics];
|
||||
}
|
||||
|
||||
@ -1510,7 +1519,9 @@ RCT_EXPORT_METHOD(clearJSResponder)
|
||||
allJSConstants[name] = constantsNamespace;
|
||||
}];
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
_currentInterfaceOrientation = [RCTSharedApplication() statusBarOrientation];
|
||||
#endif
|
||||
[allJSConstants addEntriesFromDictionary:@{
|
||||
@"customBubblingEventTypes": bubblingEvents,
|
||||
@"customDirectEventTypes": directEvents,
|
||||
|
@ -381,6 +381,7 @@ void RCTProfileUnhookModules(RCTBridge *bridge)
|
||||
atomically:YES
|
||||
encoding:NSUTF8StringEncoding
|
||||
error:nil];
|
||||
#if !TARGET_OS_TV
|
||||
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:@[[NSURL fileURLWithPath:outFile]]
|
||||
applicationActivities:nil];
|
||||
activityViewController.completionHandler = ^(__unused NSString *activityType, __unused BOOL completed) {
|
||||
@ -392,6 +393,7 @@ void RCTProfileUnhookModules(RCTBridge *bridge)
|
||||
animated:YES
|
||||
completion:nil];
|
||||
});
|
||||
#endif
|
||||
});
|
||||
} else {
|
||||
RCTProfileInit(RCTProfilingBridge());
|
||||
@ -753,6 +755,7 @@ void RCTProfileSendResult(RCTBridge *bridge, NSString *route, NSData *data)
|
||||
encoding:NSUTF8StringEncoding];
|
||||
|
||||
if (message.length) {
|
||||
#if !TARGET_OS_TV
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[[[UIAlertView alloc] initWithTitle:@"Profile"
|
||||
message:message
|
||||
@ -760,6 +763,7 @@ void RCTProfileSendResult(RCTBridge *bridge, NSString *route, NSData *data)
|
||||
cancelButtonTitle:@"OK"
|
||||
otherButtonTitles:nil] show];
|
||||
});
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}];
|
||||
|
@ -104,7 +104,9 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
||||
|
||||
UIView *view = [self.manager view];
|
||||
view.reactTag = tag;
|
||||
#if !TARGET_OS_TV
|
||||
view.multipleTouchEnabled = YES;
|
||||
#endif
|
||||
view.userInteractionEnabled = YES; // required for touch handling
|
||||
view.layer.allowsGroupOpacity = YES; // required for touch handling
|
||||
return view;
|
||||
|
@ -149,6 +149,7 @@ RCT_CUSTOM_VIEW_PROPERTY(region, MKCoordinateRegion, RCTMap)
|
||||
}
|
||||
}
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
- (void)mapView:(RCTMap *)mapView annotationView:(MKAnnotationView *)view
|
||||
didChangeDragState:(MKAnnotationViewDragState)newState
|
||||
fromOldState:(MKAnnotationViewDragState)oldState
|
||||
@ -172,6 +173,7 @@ RCT_CUSTOM_VIEW_PROPERTY(region, MKCoordinateRegion, RCTMap)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif //TARGET_OS_TV
|
||||
|
||||
- (MKAnnotationView *)mapView:(RCTMap *)mapView
|
||||
viewForAnnotation:(RCTMapAnnotation *)annotation
|
||||
@ -280,7 +282,9 @@ RCT_CUSTOM_VIEW_PROPERTY(region, MKCoordinateRegion, RCTMap)
|
||||
}
|
||||
}
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
annotationView.draggable = annotation.draggable;
|
||||
#endif
|
||||
|
||||
return annotationView;
|
||||
}
|
||||
|
@ -25,7 +25,9 @@
|
||||
RCTModalHostViewController *_modalViewController;
|
||||
RCTTouchHandler *_touchHandler;
|
||||
UIView *_reactSubview;
|
||||
#if !TARGET_OS_TV
|
||||
UIInterfaceOrientation _lastKnownOrientation;
|
||||
#endif
|
||||
}
|
||||
|
||||
RCT_NOT_IMPLEMENTED(- (instancetype)initWithFrame:(CGRect)frame)
|
||||
@ -61,6 +63,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:coder)
|
||||
|
||||
- (void)notifyForOrientationChange
|
||||
{
|
||||
#if !TARGET_OS_TV
|
||||
if (!_onOrientationChange) {
|
||||
return;
|
||||
}
|
||||
@ -77,6 +80,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:coder)
|
||||
@"orientation": isPortrait ? @"portrait" : @"landscape",
|
||||
};
|
||||
_onOrientationChange(eventPayload);
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)insertReactSubview:(UIView *)subview atIndex:(NSInteger)atIndex
|
||||
@ -119,7 +123,9 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:coder)
|
||||
if (!_isPresented && self.window) {
|
||||
RCTAssert(self.reactViewController, @"Can't present modal view controller without a presenting view controller");
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
_modalViewController.supportedInterfaceOrientations = [self supportedOrientationsMask];
|
||||
#endif
|
||||
if ([self.animationType isEqualToString:@"fade"]) {
|
||||
_modalViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
|
||||
} else if ([self.animationType isEqualToString:@"slide"]) {
|
||||
@ -161,6 +167,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:coder)
|
||||
_modalViewController.modalPresentationStyle = transparent ? UIModalPresentationOverFullScreen : UIModalPresentationFullScreen;
|
||||
}
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
- (UIInterfaceOrientationMask)supportedOrientationsMask
|
||||
{
|
||||
if (_supportedOrientations.count == 0) {
|
||||
@ -187,5 +194,6 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:coder)
|
||||
}
|
||||
return supportedOrientations;
|
||||
}
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
@ -13,6 +13,8 @@
|
||||
|
||||
@property (nonatomic, copy) void (^boundsDidChangeBlock)(CGRect newBounds);
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
@property (nonatomic, assign) UIInterfaceOrientationMask supportedInterfaceOrientations;
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
@ -15,8 +15,10 @@
|
||||
@implementation RCTModalHostViewController
|
||||
{
|
||||
CGRect _lastViewFrame;
|
||||
#if !TARGET_OS_TV
|
||||
UIStatusBarStyle _preferredStatusBarStyle;
|
||||
BOOL _preferredStatusBarHidden;
|
||||
#endif
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
@ -25,8 +27,10 @@
|
||||
return nil;
|
||||
}
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
_preferredStatusBarStyle = [[UIApplication sharedApplication] statusBarStyle];
|
||||
_preferredStatusBarHidden = [[UIApplication sharedApplication] isStatusBarHidden];
|
||||
#endif
|
||||
|
||||
return self;
|
||||
}
|
||||
@ -41,6 +45,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
- (UIStatusBarStyle)preferredStatusBarStyle
|
||||
{
|
||||
return _preferredStatusBarStyle;
|
||||
@ -50,6 +55,7 @@
|
||||
{
|
||||
return _preferredStatusBarHidden;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if RCT_DEV
|
||||
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
|
||||
|
@ -169,6 +169,7 @@ NSInteger kNeverProgressed = -10000;
|
||||
*/
|
||||
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item
|
||||
{
|
||||
#if !TARGET_OS_TV
|
||||
if (self.interactivePopGestureRecognizer.state == UIGestureRecognizerStateBegan) {
|
||||
if (self.navigationLock == RCTNavigationLockNone) {
|
||||
self.navigationLock = RCTNavigationLockNative;
|
||||
@ -180,7 +181,9 @@ NSInteger kNeverProgressed = -10000;
|
||||
// recognizer when we lock the navigation.
|
||||
RCTAssert(NO, @"Should never receive gesture start while JS locks navigator");
|
||||
}
|
||||
} else {
|
||||
} else
|
||||
#endif //TARGET_OS_TV
|
||||
{
|
||||
if (self.navigationLock == RCTNavigationLockNone) {
|
||||
// Must be coming from native interaction, lock it - it will be unlocked
|
||||
// in `didMoveToNavigationController`
|
||||
@ -348,19 +351,23 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
|
||||
|
||||
- (void)setInteractivePopGestureEnabled:(BOOL)interactivePopGestureEnabled
|
||||
{
|
||||
#if !TARGET_OS_TV
|
||||
_interactivePopGestureEnabled = interactivePopGestureEnabled;
|
||||
|
||||
_navigationController.interactivePopGestureRecognizer.delegate = self;
|
||||
_navigationController.interactivePopGestureRecognizer.enabled = interactivePopGestureEnabled;
|
||||
|
||||
_popGestureState = interactivePopGestureEnabled ? RCTPopGestureStateEnabled : RCTPopGestureStateDisabled;
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
#if !TARGET_OS_TV
|
||||
if (_navigationController.interactivePopGestureRecognizer.delegate == self) {
|
||||
_navigationController.interactivePopGestureRecognizer.delegate = nil;
|
||||
}
|
||||
#endif
|
||||
_navigationController.delegate = nil;
|
||||
[_navigationController removeFromParentViewController];
|
||||
}
|
||||
@ -422,7 +429,9 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
|
||||
{
|
||||
if (_navigationController.navigationLock == RCTNavigationLockNone) {
|
||||
_navigationController.navigationLock = RCTNavigationLockJavaScript;
|
||||
#if !TARGET_OS_TV
|
||||
_navigationController.interactivePopGestureRecognizer.enabled = NO;
|
||||
#endif
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
@ -435,7 +444,9 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
|
||||
// Unless the pop gesture has been explicitly disabled (RCTPopGestureStateDisabled),
|
||||
// Set interactivePopGestureRecognizer.enabled to YES
|
||||
// If the popGestureState is RCTPopGestureStateDefault the default behavior will be maintained
|
||||
#if !TARGET_OS_TV
|
||||
_navigationController.interactivePopGestureRecognizer.enabled = self.popGestureState != RCTPopGestureStateDisabled;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -15,7 +15,9 @@
|
||||
|
||||
RCT_ENUM_CONVERTER(UIProgressViewStyle, (@{
|
||||
@"default": @(UIProgressViewStyleDefault),
|
||||
#if !TARGET_OS_TV
|
||||
@"bar": @(UIProgressViewStyleBar),
|
||||
#endif
|
||||
}), UIProgressViewStyleDefault, integerValue)
|
||||
|
||||
@end
|
||||
|
@ -14,7 +14,9 @@
|
||||
#import "RCTConvert.h"
|
||||
#import "RCTEventDispatcher.h"
|
||||
#import "RCTLog.h"
|
||||
#if !TARGET_OS_TV
|
||||
#import "RCTRefreshControl.h"
|
||||
#endif
|
||||
#import "RCTUIManager.h"
|
||||
#import "RCTUtils.h"
|
||||
#import "UIView+Private.h"
|
||||
@ -140,7 +142,9 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
||||
|
||||
@property (nonatomic, copy) NSIndexSet *stickyHeaderIndices;
|
||||
@property (nonatomic, assign) BOOL centerContent;
|
||||
#if !TARGET_OS_TV
|
||||
@property (nonatomic, strong) RCTRefreshControl *rctRefreshControl;
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
||||
@ -275,9 +279,11 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
||||
CGFloat scrollTop = self.bounds.origin.y + self.contentInset.top;
|
||||
// If the RefreshControl is refreshing, remove it's height so sticky headers are
|
||||
// positioned properly when scrolling down while refreshing.
|
||||
#if !TARGET_OS_TV
|
||||
if (_rctRefreshControl != nil && _rctRefreshControl.refreshing) {
|
||||
scrollTop -= _rctRefreshControl.frame.size.height;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Find the section headers that need to be docked
|
||||
__block UIView *previousHeader = nil;
|
||||
@ -358,6 +364,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
||||
return [super hitTest:point withEvent:event];
|
||||
}
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
- (void)setRctRefreshControl:(RCTRefreshControl *)refreshControl
|
||||
{
|
||||
if (_rctRefreshControl) {
|
||||
@ -366,6 +373,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
||||
_rctRefreshControl = refreshControl;
|
||||
[self addSubview:_rctRefreshControl];
|
||||
}
|
||||
#endif //TARGET_OS_TV
|
||||
|
||||
@end
|
||||
|
||||
@ -423,9 +431,12 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
|
||||
- (void)insertReactSubview:(UIView *)view atIndex:(NSInteger)atIndex
|
||||
{
|
||||
[super insertReactSubview:view atIndex:atIndex];
|
||||
#if !TARGET_OS_TV
|
||||
if ([view isKindOfClass:[RCTRefreshControl class]]) {
|
||||
[_scrollView setRctRefreshControl:(RCTRefreshControl *)view];
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
RCTAssert(_contentView == nil, @"RCTScrollView may only contain a single subview");
|
||||
_contentView = view;
|
||||
[_scrollView addSubview:view];
|
||||
@ -435,9 +446,12 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
|
||||
- (void)removeReactSubview:(UIView *)subview
|
||||
{
|
||||
[super removeReactSubview:subview];
|
||||
#if !TARGET_OS_TV
|
||||
if ([subview isKindOfClass:[RCTRefreshControl class]]) {
|
||||
[_scrollView setRctRefreshControl:nil];
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
RCTAssert(_contentView == subview, @"Attempted to remove non-existent subview");
|
||||
_contentView = nil;
|
||||
}
|
||||
@ -491,11 +505,13 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
|
||||
_scrollView.frame = self.bounds;
|
||||
_scrollView.contentOffset = originalOffset;
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
// Adjust the refresh control frame if the scrollview layout changes.
|
||||
RCTRefreshControl *refreshControl = _scrollView.rctRefreshControl;
|
||||
if (refreshControl && refreshControl.refreshing) {
|
||||
refreshControl.frame = (CGRect){_scrollView.contentOffset, {_scrollView.frame.size.width, refreshControl.frame.size.height}};
|
||||
}
|
||||
#endif
|
||||
|
||||
[self updateClippedSubviews];
|
||||
}
|
||||
@ -926,9 +942,11 @@ RCT_SET_AND_PRESERVE_OFFSET(setIndicatorStyle, indicatorStyle, UIScrollViewIndic
|
||||
RCT_SET_AND_PRESERVE_OFFSET(setKeyboardDismissMode, keyboardDismissMode, UIScrollViewKeyboardDismissMode)
|
||||
RCT_SET_AND_PRESERVE_OFFSET(setMaximumZoomScale, maximumZoomScale, CGFloat)
|
||||
RCT_SET_AND_PRESERVE_OFFSET(setMinimumZoomScale, minimumZoomScale, CGFloat)
|
||||
RCT_SET_AND_PRESERVE_OFFSET(setPagingEnabled, isPagingEnabled, BOOL)
|
||||
RCT_SET_AND_PRESERVE_OFFSET(setScrollEnabled, isScrollEnabled, BOOL)
|
||||
#if !TARGET_OS_TV
|
||||
RCT_SET_AND_PRESERVE_OFFSET(setPagingEnabled, isPagingEnabled, BOOL)
|
||||
RCT_SET_AND_PRESERVE_OFFSET(setScrollsToTop, scrollsToTop, BOOL)
|
||||
#endif
|
||||
RCT_SET_AND_PRESERVE_OFFSET(setShowsHorizontalScrollIndicator, showsHorizontalScrollIndicator, BOOL)
|
||||
RCT_SET_AND_PRESERVE_OFFSET(setShowsVerticalScrollIndicator, showsVerticalScrollIndicator, BOOL)
|
||||
RCT_SET_AND_PRESERVE_OFFSET(setZoomScale, zoomScale, CGFloat);
|
||||
|
@ -151,12 +151,18 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
|
||||
|
||||
- (UITabBarItemPositioning)itemPositoning
|
||||
{
|
||||
#if TARGET_OS_TV
|
||||
return 0;
|
||||
#else
|
||||
return _tabController.tabBar.itemPositioning;
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)setItemPositioning:(UITabBarItemPositioning)itemPositioning
|
||||
{
|
||||
#if !TARGET_OS_TV
|
||||
_tabController.tabBar.itemPositioning = itemPositioning;
|
||||
#endif
|
||||
}
|
||||
|
||||
#pragma mark - UITabBarControllerDelegate
|
||||
|
@ -32,7 +32,9 @@ RCT_ENUM_CONVERTER(UITabBarSystemItem, (@{
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTTabBarItem
|
||||
@implementation RCTTabBarItem{
|
||||
UITapGestureRecognizer *_selectRecognizer;
|
||||
}
|
||||
|
||||
@synthesize barItem = _barItem;
|
||||
|
||||
@ -84,7 +86,7 @@ RCT_ENUM_CONVERTER(UITabBarSystemItem, (@{
|
||||
_barItem.selectedImage = oldItem.selectedImage;
|
||||
_barItem.badgeValue = oldItem.badgeValue;
|
||||
}
|
||||
|
||||
|
||||
if (_renderAsOriginal) {
|
||||
self.barItem.image = [_icon imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
|
||||
} else {
|
||||
@ -95,7 +97,7 @@ RCT_ENUM_CONVERTER(UITabBarSystemItem, (@{
|
||||
- (void)setSelectedIcon:(UIImage *)selectedIcon
|
||||
{
|
||||
_selectedIcon = selectedIcon;
|
||||
|
||||
|
||||
if (_renderAsOriginal) {
|
||||
self.barItem.selectedImage = [_selectedIcon imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
|
||||
} else {
|
||||
|
@ -124,7 +124,9 @@ static UIView *RCTFindNavBarShadowViewInView(UIView *view)
|
||||
UINavigationItem *item = self.navigationItem;
|
||||
item.title = _navItem.title;
|
||||
item.titleView = _navItem.titleImageView;
|
||||
#if !TARGET_OS_TV
|
||||
item.backBarButtonItem = _navItem.backButtonItem;
|
||||
#endif //TARGET_OS_TV
|
||||
item.leftBarButtonItem = _navItem.leftButtonItem;
|
||||
item.rightBarButtonItem = _navItem.rightButtonItem;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user