Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix tvOS compile issues; enable TVEventHandler in Modal (fix #15389) #16076

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Libraries/Text/RCTText.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
2D3B5F3A1D9B106F00451313 /* RCTTextFieldManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1362F0FF1B4D51F400E06D8C /* RCTTextFieldManager.m */; };
2D3B5F3B1D9B106F00451313 /* RCTTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 131B6ABD1AF0CD0600FFC3E0 /* RCTTextView.m */; };
2D3B5F3C1D9B106F00451313 /* RCTTextViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 131B6ABF1AF0CD0600FFC3E0 /* RCTTextViewManager.m */; };
2DEAB2901F84BA4300FC6B42 /* RCTFontAttributes.m in Sources */ = {isa = PBXBuildFile; fileRef = A85C82991F742AA20036C019 /* RCTFontAttributes.m */; };
58B511CE1A9E6C5C00147676 /* RCTRawTextManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 58B511C71A9E6C5C00147676 /* RCTRawTextManager.m */; };
58B511CF1A9E6C5C00147676 /* RCTShadowRawText.m in Sources */ = {isa = PBXBuildFile; fileRef = 58B511C91A9E6C5C00147676 /* RCTShadowRawText.m */; };
58B511D01A9E6C5C00147676 /* RCTShadowText.m in Sources */ = {isa = PBXBuildFile; fileRef = 58B511CB1A9E6C5C00147676 /* RCTShadowText.m */; };
Expand Down
97 changes: 68 additions & 29 deletions RNTester/RNTester.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@
"idiom" : "iphone",
"filename" : "Icon-60@3x.png",
"scale" : "3x"
},
{
"idiom" : "ios-marketing",
"size" : "1024x1024",
"scale" : "1x"
}
],
"info" : {
Expand Down
3 changes: 3 additions & 0 deletions RNTester/js/ListExampleShared.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,9 @@ function pressItem(context: Object, key: string) {
}

function renderSmallSwitchOption(context: Object, key: string) {
if(Platform.isTVOS) {
return null;
}
return (
<View style={styles.option}>
<Text>{key}:</Text>
Expand Down
31 changes: 25 additions & 6 deletions RNTester/js/ModalExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ var ReactNative = require('react-native');
var {
Modal,
Picker,
Platform,
StyleSheet,
Switch,
Text,
Expand Down Expand Up @@ -91,6 +92,15 @@ class ModalExample extends React.Component<{}, $FlowFixMeState> {
this.setState({transparent: !this.state.transparent});
};

renderSwitch() {
if (Platform.isTVOS) {
return null;
}
return (
<Switch value={this.state.transparent} onValueChange={this._toggleTransparent} />
);
}

render() {
var modalBackgroundStyle = {
backgroundColor: this.state.transparent ? 'rgba(0, 0, 0, 0.5)' : '#f5fcff',
Expand Down Expand Up @@ -140,9 +150,21 @@ class ModalExample extends React.Component<{}, $FlowFixMeState> {

<View style={styles.row}>
<Text style={styles.rowTitle}>Transparent</Text>
<Switch value={this.state.transparent} onValueChange={this._toggleTransparent} />
{this.renderSwitch()}
</View>

{this.renderPickers()}
<Button onPress={this._setModalVisible.bind(this, true)}>
Present
</Button>
</View>
);
}
renderPickers() {
if (Platform.isTVOS) {
return null;
}
return (
<View>
<View>
<Text style={styles.rowTitle}>Presentation style</Text>
<Picker
Expand Down Expand Up @@ -173,15 +195,12 @@ class ModalExample extends React.Component<{}, $FlowFixMeState> {
<Item label="Default supportedOrientations" value={5} />
</Picker>
</View>

<Button onPress={this._setModalVisible.bind(this, true)}>
Present
</Button>
</View>
);
}
}


exports.examples = [
{
title: 'Modal Presentation',
Expand Down
4 changes: 2 additions & 2 deletions React/Base/RCTRootView.m
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge

#if TARGET_OS_TV
self.tvRemoteHandler = [RCTTVRemoteHandler new];
for (UIGestureRecognizer *gr in self.tvRemoteHandler.tvRemoteGestureRecognizers) {
[self addGestureRecognizer:gr];
for (NSString *key in [self.tvRemoteHandler.tvRemoteGestureRecognizers allKeys]) {
[self addGestureRecognizer:self.tvRemoteHandler.tvRemoteGestureRecognizers[key]];
}
#endif

Expand Down
20 changes: 19 additions & 1 deletion React/Base/RCTTVRemoteHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,26 @@

#import <UIKit/UIKit.h>


extern NSString *const RCTTVRemoteEventMenu;
extern NSString *const RCTTVRemoteEventPlayPause;
extern NSString *const RCTTVRemoteEventSelect;

extern NSString *const RCTTVRemoteEventLongPlayPause;
extern NSString *const RCTTVRemoteEventLongSelect;

extern NSString *const RCTTVRemoteEventLeft;
extern NSString *const RCTTVRemoteEventRight;
extern NSString *const RCTTVRemoteEventUp;
extern NSString *const RCTTVRemoteEventDown;

extern NSString *const RCTTVRemoteEventSwipeLeft;
extern NSString *const RCTTVRemoteEventSwipeRight;
extern NSString *const RCTTVRemoteEventSwipeUp;
extern NSString *const RCTTVRemoteEventSwipeDown;

@interface RCTTVRemoteHandler : NSObject

@property (nonatomic, copy, readonly) NSArray *tvRemoteGestureRecognizers;
@property (nonatomic, copy, readonly) NSDictionary *tvRemoteGestureRecognizers;

@end
91 changes: 61 additions & 30 deletions React/Base/RCTTVRemoteHandler.m
Original file line number Diff line number Diff line change
Expand Up @@ -26,71 +26,102 @@
#import "RCTDevMenu.h"
#endif

NSString *const RCTTVRemoteEventMenu = @"menu";
NSString *const RCTTVRemoteEventPlayPause = @"playPause";
NSString *const RCTTVRemoteEventSelect = @"select";

NSString *const RCTTVRemoteEventLongPlayPause = @"longPlayPause";
NSString *const RCTTVRemoteEventLongSelect = @"longSelect";

NSString *const RCTTVRemoteEventLeft = @"left";
NSString *const RCTTVRemoteEventRight = @"right";
NSString *const RCTTVRemoteEventUp = @"up";
NSString *const RCTTVRemoteEventDown = @"down";

NSString *const RCTTVRemoteEventSwipeLeft = @"swipeLeft";
NSString *const RCTTVRemoteEventSwipeRight = @"swipeRight";
NSString *const RCTTVRemoteEventSwipeUp = @"swipeUp";
NSString *const RCTTVRemoteEventSwipeDown = @"swipeDown";


@implementation RCTTVRemoteHandler {
NSMutableArray<UIGestureRecognizer *> *_tvRemoteGestureRecognizers;
NSMutableDictionary<NSString *, UIGestureRecognizer *> *_tvRemoteGestureRecognizers;
}

- (instancetype)init
{
if ((self = [super init])) {
_tvRemoteGestureRecognizers = [NSMutableArray array];
_tvRemoteGestureRecognizers = [NSMutableDictionary dictionary];

// Recognizers for Apple TV remote buttons

// Play/Pause
[self addTapGestureRecognizerWithSelector:@selector(playPausePressed:)
pressType:UIPressTypePlayPause];
pressType:UIPressTypePlayPause
name:RCTTVRemoteEventPlayPause];

// Menu
[self addTapGestureRecognizerWithSelector:@selector(menuPressed:)
pressType:UIPressTypeMenu];
pressType:UIPressTypeMenu
name:RCTTVRemoteEventMenu];

// Select
[self addTapGestureRecognizerWithSelector:@selector(selectPressed:)
pressType:UIPressTypeSelect];
pressType:UIPressTypeSelect
name:RCTTVRemoteEventSelect];

// Up
[self addTapGestureRecognizerWithSelector:@selector(swipedUp:)
pressType:UIPressTypeUpArrow];
pressType:UIPressTypeUpArrow
name:RCTTVRemoteEventUp];

// Down
[self addTapGestureRecognizerWithSelector:@selector(swipedDown:)
pressType:UIPressTypeDownArrow];
pressType:UIPressTypeDownArrow
name:RCTTVRemoteEventDown];

// Left
[self addTapGestureRecognizerWithSelector:@selector(swipedLeft:)
pressType:UIPressTypeLeftArrow];
pressType:UIPressTypeLeftArrow
name:RCTTVRemoteEventLeft];

// Right
[self addTapGestureRecognizerWithSelector:@selector(swipedRight:)
pressType:UIPressTypeRightArrow];
pressType:UIPressTypeRightArrow
name:RCTTVRemoteEventRight];

// Recognizers for long button presses
// We don't intercept long menu press -- that's used by the system to go to the home screen

[self addLongPressGestureRecognizerWithSelector:@selector(longPlayPausePressed:)
pressType:UIPressTypePlayPause];
pressType:UIPressTypePlayPause
name:RCTTVRemoteEventLongPlayPause];

[self addLongPressGestureRecognizerWithSelector:@selector(longSelectPressed:)
pressType:UIPressTypeSelect];
pressType:UIPressTypeSelect
name:RCTTVRemoteEventLongSelect];

// Recognizers for Apple TV remote trackpad swipes

// Up
[self addSwipeGestureRecognizerWithSelector:@selector(swipedUp:)
direction:UISwipeGestureRecognizerDirectionUp];
direction:UISwipeGestureRecognizerDirectionUp
name:RCTTVRemoteEventSwipeUp];

// Down
[self addSwipeGestureRecognizerWithSelector:@selector(swipedDown:)
direction:UISwipeGestureRecognizerDirectionDown];
direction:UISwipeGestureRecognizerDirectionDown
name:RCTTVRemoteEventSwipeDown];

// Left
[self addSwipeGestureRecognizerWithSelector:@selector(swipedLeft:)
direction:UISwipeGestureRecognizerDirectionLeft];
direction:UISwipeGestureRecognizerDirectionLeft
name:RCTTVRemoteEventSwipeLeft];

// Right
[self addSwipeGestureRecognizerWithSelector:@selector(swipedRight:)
direction:UISwipeGestureRecognizerDirectionRight];
direction:UISwipeGestureRecognizerDirectionRight
name:RCTTVRemoteEventSwipeRight];

}

Expand All @@ -99,22 +130,22 @@ - (instancetype)init

- (void)playPausePressed:(UIGestureRecognizer *)r
{
[self sendAppleTVEvent:@"playPause" toView:r.view];
[self sendAppleTVEvent:RCTTVRemoteEventPlayPause toView:r.view];
}

- (void)menuPressed:(UIGestureRecognizer *)r
{
[self sendAppleTVEvent:@"menu" toView:r.view];
[self sendAppleTVEvent:RCTTVRemoteEventMenu toView:r.view];
}

- (void)selectPressed:(UIGestureRecognizer *)r
{
[self sendAppleTVEvent:@"select" toView:r.view];
[self sendAppleTVEvent:RCTTVRemoteEventSelect toView:r.view];
}

- (void)longPlayPausePressed:(UIGestureRecognizer *)r
{
[self sendAppleTVEvent:@"longPlayPause" toView:r.view];
[self sendAppleTVEvent:RCTTVRemoteEventLongPlayPause toView:r.view];

#if __has_include("RCTDevMenu.h") && RCT_DEV
// If shake to show is enabled on device, use long play/pause event to show dev menu
Expand All @@ -124,53 +155,53 @@ - (void)longPlayPausePressed:(UIGestureRecognizer *)r

- (void)longSelectPressed:(UIGestureRecognizer *)r
{
[self sendAppleTVEvent:@"longSelect" toView:r.view];
[self sendAppleTVEvent:RCTTVRemoteEventLongSelect toView:r.view];
}

- (void)swipedUp:(UIGestureRecognizer *)r
{
[self sendAppleTVEvent:@"up" toView:r.view];
[self sendAppleTVEvent:RCTTVRemoteEventUp toView:r.view];
}

- (void)swipedDown:(UIGestureRecognizer *)r
{
[self sendAppleTVEvent:@"down" toView:r.view];
[self sendAppleTVEvent:RCTTVRemoteEventDown toView:r.view];
}

- (void)swipedLeft:(UIGestureRecognizer *)r
{
[self sendAppleTVEvent:@"left" toView:r.view];
[self sendAppleTVEvent:RCTTVRemoteEventLeft toView:r.view];
}

- (void)swipedRight:(UIGestureRecognizer *)r
{
[self sendAppleTVEvent:@"right" toView:r.view];
[self sendAppleTVEvent:RCTTVRemoteEventRight toView:r.view];
}

#pragma mark -

- (void)addLongPressGestureRecognizerWithSelector:(nonnull SEL)selector pressType:(UIPressType)pressType
- (void)addLongPressGestureRecognizerWithSelector:(nonnull SEL)selector pressType:(UIPressType)pressType name:(NSString *)name
{
UILongPressGestureRecognizer *recognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:selector];
recognizer.allowedPressTypes = @[@(pressType)];

[_tvRemoteGestureRecognizers addObject:recognizer];
_tvRemoteGestureRecognizers[name] = recognizer;
}

- (void)addTapGestureRecognizerWithSelector:(nonnull SEL)selector pressType:(UIPressType)pressType
- (void)addTapGestureRecognizerWithSelector:(nonnull SEL)selector pressType:(UIPressType)pressType name:(NSString *)name
{
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:selector];
recognizer.allowedPressTypes = @[@(pressType)];

[_tvRemoteGestureRecognizers addObject:recognizer];
_tvRemoteGestureRecognizers[name] = recognizer;
}

- (void)addSwipeGestureRecognizerWithSelector:(nonnull SEL)selector direction:(UISwipeGestureRecognizerDirection)direction
- (void)addSwipeGestureRecognizerWithSelector:(nonnull SEL)selector direction:(UISwipeGestureRecognizerDirection)direction name:(NSString *)name
{
UISwipeGestureRecognizer *recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:selector];
recognizer.direction = direction;

[_tvRemoteGestureRecognizers addObject:recognizer];
_tvRemoteGestureRecognizers[name] = recognizer;
}

- (void)sendAppleTVEvent:(NSString *)eventType toView:(__unused UIView *)v
Expand Down
10 changes: 8 additions & 2 deletions React/React.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,10 @@
27595AD61E575C7800CCE2B1 /* Platform.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0D21E03699D0018521A /* Platform.h */; };
27595AD71E575C7800CCE2B1 /* SampleCxxModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0D41E03699D0018521A /* SampleCxxModule.h */; };
27595AD81E575C7800CCE2B1 /* SystraceSection.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0D51E03699D0018521A /* SystraceSection.h */; };
2D16E68E1FA4FD3900B85C8A /* RCTTVNavigationEventEmitter.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D0B842D1EC0B51200B2BD8E /* RCTTVNavigationEventEmitter.h */; };
2D1D83CD1F74E2CE00615550 /* libprivatedata-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9936F32F1F5F2E5B0010BF04 /* libprivatedata-tvOS.a */; };
2D1D83CE1F74E2DA00615550 /* libdouble-conversion.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D383D621EBD27B9005632C8 /* libdouble-conversion.a */; };
2D1D83EF1F74E76C00615550 /* RCTModalManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 91076A871F743AB00081B4FA /* RCTModalManager.m */; };
2D3B5E931D9B087300451313 /* RCTErrorInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 3EDCA8A41D3591E700450C31 /* RCTErrorInfo.m */; };
2D3B5E941D9B087900451313 /* RCTBundleURLProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 68EFE4ED1CF6EB3900A1DE13 /* RCTBundleURLProvider.m */; };
2D3B5E951D9B087C00451313 /* RCTAssert.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBA4B1A601E3B00E9B192 /* RCTAssert.m */; };
Expand Down Expand Up @@ -520,7 +524,6 @@
3D383D6D1EBD2940005632C8 /* libdouble-conversion.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139D7E881E25C6D100323FB7 /* libdouble-conversion.a */; };
3D383D6E1EBD2940005632C8 /* libjschelpers.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D3CD90B1DE5FBD600167DC4 /* libjschelpers.a */; };
3D383D6F1EBD2940005632C8 /* libthird-party.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139D7ECE1E25DB7D00323FB7 /* libthird-party.a */; };
3D383D701EBD2949005632C8 /* libdouble-conversion.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D383D621EBD27B9005632C8 /* libdouble-conversion.a */; };
3D383D711EBD2949005632C8 /* libjschelpers.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D3CD9181DE5FBD800167DC4 /* libjschelpers.a */; };
3D383D721EBD2949005632C8 /* libthird-party.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D383D3C1EBD27B6005632C8 /* libthird-party.a */; };
3D3C08891DE342FB00C268FA /* libyoga.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D3C059A1DE3340900C268FA /* libyoga.a */; };
Expand Down Expand Up @@ -1305,6 +1308,7 @@
dstPath = include/React;
dstSubfolderSpec = 16;
files = (
2D16E68E1FA4FD3900B85C8A /* RCTTVNavigationEventEmitter.h in Copy Headers */,
59500D481F71C67600B122B7 /* RCTUIManagerUtils.h in Copy Headers */,
3D0E37901F1CC5E100DCAC9F /* RCTWebSocketModule.h in Copy Headers */,
5960C1BF1F0804F50066FD5B /* RCTLayoutAnimation.h in Copy Headers */,
Expand Down Expand Up @@ -2220,7 +2224,8 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
3D383D701EBD2949005632C8 /* libdouble-conversion.a in Frameworks */,
2D1D83CE1F74E2DA00615550 /* libdouble-conversion.a in Frameworks */,
2D1D83CD1F74E2CE00615550 /* libprivatedata-tvOS.a in Frameworks */,
3D383D711EBD2949005632C8 /* libjschelpers.a in Frameworks */,
3D383D721EBD2949005632C8 /* libthird-party.a in Frameworks */,
3D8ED92C1E5B120100D83D20 /* libcxxreact.a in Frameworks */,
Expand Down Expand Up @@ -4011,6 +4016,7 @@
2D3B5EC61D9B095000451313 /* RCTProfileTrampoline-x86_64.S in Sources */,
2D3B5EA61D9B08CA00451313 /* RCTTouchEvent.m in Sources */,
2D8C2E331DA40441000EE098 /* RCTMultipartStreamReader.m in Sources */,
2D1D83EF1F74E76C00615550 /* RCTModalManager.m in Sources */,
2D3B5EF01D9B09E300451313 /* RCTWrapperViewController.m in Sources */,
2D3B5EEC1D9B09D400451313 /* RCTTabBarItemManager.m in Sources */,
2D3B5EB01D9B08FE00451313 /* RCTAlertManager.m in Sources */,
Expand Down
Loading