Apple TV: Enable long presses on TV remote; dev menu on TV device; example code
Summary: **Motivation** Properly support long presses on the Apple TV remote, and also enable dev menu functionality on a real Apple TV device (shaking an Apple TV doesn't work 😄 ) **Test plan** New example added to `RNTester`. Closes https://github.com/facebook/react-native/pull/15221 Differential Revision: D5526463 Pulled By: javache fbshipit-source-id: a61051e86bc82a9561eefc1704bed6b1f2617e05
This commit is contained in:
parent
e61257cd0a
commit
75284d3cd4
|
@ -336,6 +336,11 @@ const APIExamples: Array<RNTesterExample> = [
|
|||
module: require('./TransformExample'),
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'TVEventHandlerExample',
|
||||
module: require('./TVEventHandlerExample'),
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'VibrationExample',
|
||||
module: require('./VibrationExample'),
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
/**
|
||||
* Copyright (c) 2017-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @flow
|
||||
* @providesModule TVEventHandlerExample
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
var ReactNative = require('react-native');
|
||||
|
||||
var {
|
||||
Platform,
|
||||
StyleSheet,
|
||||
View,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
TVEventHandler,
|
||||
} = ReactNative;
|
||||
|
||||
exports.framework = 'React';
|
||||
exports.title = 'TVEventHandler example';
|
||||
exports.description = 'iOS alerts and action sheets';
|
||||
exports.examples = [{
|
||||
title: 'TVEventHandler',
|
||||
render() {return <TVEventHandlerView/>;}
|
||||
}];
|
||||
|
||||
class TVEventHandlerView extends React.Component {
|
||||
state: {
|
||||
lastEventType: string
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
lastEventType: ''
|
||||
};
|
||||
}
|
||||
|
||||
_tvEventHandler: any;
|
||||
|
||||
_enableTVEventHandler() {
|
||||
this._tvEventHandler = new TVEventHandler();
|
||||
this._tvEventHandler.enable(this, function(cmp, evt) {
|
||||
cmp.setState({
|
||||
lastEventType: evt.eventType
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
_disableTVEventHandler() {
|
||||
if (this._tvEventHandler) {
|
||||
this._tvEventHandler.disable();
|
||||
delete this._tvEventHandler;
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this._enableTVEventHandler();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this._disableTVEventHandler();
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
if (Platform.isTVOS) {
|
||||
return (
|
||||
<View>
|
||||
<TouchableOpacity onPress={() => {}}>
|
||||
<Text>
|
||||
This example enables an instance of TVEventHandler to show the last event detected from the Apple TV Siri remote or from a keyboard.
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
<Text style={{color: 'blue'}}>
|
||||
{this.state.lastEventType}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<View>
|
||||
<Text>
|
||||
This example is intended to be run on Apple TV.
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -22,6 +22,8 @@
|
|||
#import "RCTView.h"
|
||||
#import "UIView+React.h"
|
||||
|
||||
#import "RCTDevMenu.h"
|
||||
|
||||
@implementation RCTTVRemoteHandler {
|
||||
NSMutableArray<UIGestureRecognizer *> *_tvRemoteGestureRecognizers;
|
||||
}
|
||||
|
@ -60,7 +62,15 @@
|
|||
// Right
|
||||
[self addTapGestureRecognizerWithSelector:@selector(swipedRight:)
|
||||
pressType:UIPressTypeRightArrow];
|
||||
|
||||
|
||||
// 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];
|
||||
|
||||
[self addLongPressGestureRecognizerWithSelector:@selector(longSelectPressed:)
|
||||
pressType:UIPressTypeSelect];
|
||||
|
||||
// Recognizers for Apple TV remote trackpad swipes
|
||||
|
||||
|
@ -100,9 +110,19 @@
|
|||
[self sendAppleTVEvent:@"select" toView:r.view];
|
||||
}
|
||||
|
||||
- (void)longPress:(UIGestureRecognizer *)r
|
||||
- (void)longPlayPausePressed:(UIGestureRecognizer *)r
|
||||
{
|
||||
[self sendAppleTVEvent:@"longPress" toView:r.view];
|
||||
[self sendAppleTVEvent:@"longPlayPause" toView:r.view];
|
||||
|
||||
// If shake to show is enabled on device, use long play/pause event to show dev menu
|
||||
#if RCT_DEV
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:RCTShowDevMenuNotification object:nil];
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)longSelectPressed:(UIGestureRecognizer *)r
|
||||
{
|
||||
[self sendAppleTVEvent:@"longSelect" toView:r.view];
|
||||
}
|
||||
|
||||
- (void)swipedUp:(UIGestureRecognizer *)r
|
||||
|
@ -127,6 +147,14 @@
|
|||
|
||||
#pragma mark -
|
||||
|
||||
- (void)addLongPressGestureRecognizerWithSelector:(nonnull SEL)selector pressType:(UIPressType)pressType
|
||||
{
|
||||
UILongPressGestureRecognizer *recognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:selector];
|
||||
recognizer.allowedPressTypes = @[@(pressType)];
|
||||
|
||||
[_tvRemoteGestureRecognizers addObject:recognizer];
|
||||
}
|
||||
|
||||
- (void)addTapGestureRecognizerWithSelector:(nonnull SEL)selector pressType:(UIPressType)pressType
|
||||
{
|
||||
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:selector];
|
||||
|
|
|
@ -12,6 +12,13 @@
|
|||
#import <React/RCTBridge.h>
|
||||
#import <React/RCTBridgeModule.h>
|
||||
|
||||
#if RCT_DEV
|
||||
|
||||
RCT_EXTERN NSString *const RCTShowDevMenuNotification;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@class RCTDevMenuItem;
|
||||
|
||||
/**
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
#if RCT_DEV
|
||||
|
||||
static NSString *const RCTShowDevMenuNotification = @"RCTShowDevMenuNotification";
|
||||
NSString *const RCTShowDevMenuNotification = @"RCTShowDevMenuNotification";
|
||||
|
||||
@implementation UIWindow (RCTDevMenu)
|
||||
|
||||
|
|
|
@ -83,6 +83,7 @@ class Game2048 extends React.Component {
|
|||
}
|
||||
|
||||
```
|
||||
- *Dev Menu support*: On the simulator, cmd-D will bring up the developer menu, just like on iOS. To bring it up on a real Apple TV device, make a long press on the play/pause button on the remote. (Please do not shake the Apple TV device, that will not work :) )
|
||||
|
||||
- *TV remote animations*: `RCTTVView` native code implements Apple-recommended parallax animations to help guide the eye as the user navigates through views. The animations can be disabled or adjusted with new optional view properties.
|
||||
|
||||
|
|
Loading…
Reference in New Issue