question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

hasTVPreferredFocus props breaks remote events on tvOS 14.2

See original GitHub issue

Description

With the update to tvOS 14.2 we noticed that remote events stop emitting. For example the press of the play/pause button or simply pressing the remote to select something. After further investigation we realised that the use of the prop hasTVPreferredFocus is the culprit.

I have created a sample project that illustrate this https://github.com/darji89/react-native-tvos-remote-bug

React Native version:

System: OS: macOS 10.15.4 CPU: (12) x64 Intel® Core™ i7-9750H CPU @ 2.60GHz Memory: 875.97 MB / 16.00 GB Shell: 3.2.57 - /bin/bash Binaries: Node: 10.18.0 - ~/.nvm/versions/node/v10.18.0/bin/node Yarn: 1.19.1 - /usr/local/bin/yarn npm: 6.13.4 - ~/.nvm/versions/node/v10.18.0/bin/npm Watchman: 4.9.0 - /usr/local/bin/watchman Managers: CocoaPods: 1.8.4 - /usr/local/bin/pod SDKs: iOS SDK: Platforms: iOS 14.2, DriverKit 20.0, macOS 11.0, tvOS 14.2, watchOS 7.1 Android SDK: Not Found IDEs: Android Studio: 3.5 AI-191.8026.42.35.5977832 Xcode: 12.2/12B45b - /usr/bin/xcodebuild Languages: Java: 13.0.1 - /usr/bin/javac Python: 2.7.16 - /usr/bin/python npmPackages: @react-native-community/cli: Not Found react: 16.13.1 => 16.13.1 react-native: Not Found react-native-macos: Not Found react-native-tvos: 0.63.1-4 npmGlobalPackages: react-native: Not Found

Steps To Reproduce

  1. clone this repo: https://github.com/darji89/react-native-tvos-remote-bug
  2. run the app on a tvOS 14.2 device. Alternate pressing the select and the menu button.
  3. In the logs you can see which key is being pressed.
  4. A “press me” button will appear and disappear.
  5. After the button disappear it doesn’t appear back - this is because the button had hasTVPreferredFocus prop
  6. if you remove this prop and restart the app (!) the toggle between the two screen will work.

Expected Results

I should be able to keep toggling screen by alternating between pressing the select and menu button. I can also confirm that this bug is also still present is use the Pressable component instead of TouchableOpacity

Snack, code example, screenshot, or link to a repository:

https://github.com/darji89/react-native-tvos-remote-bug

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:16

github_iconTop GitHub Comments

3reactions
douglowdercommented, Nov 25, 2020

@darji89 you want TVMenuControl. Apple requires that back navigation with the menu key go to the home screen when you are at the bottom of your navigation stack. To support this, the RN tvOS code does not automatically add a gesture handler for menu key presses. To get the menu key behavior you want, call TVMenuControl.enableTVMenuKey() when you want to handle menu key presses, and TVMenuControl.disableTVMenuKey() when you want to allow the app to exit normally with the menu key.

TVMenuControl: This module provides methods to enable and disable navigation using the menu key on the TV remote. This is required in order to fix an issue with Apple’s guidelines for menu key navigation (see https://github.com/facebook/react-native/issues/18930). The RNTester app uses this new module to implement correct menu key behavior.

3reactions
douglowdercommented, Nov 25, 2020

Since the react-native-tvos-controller does take over the gesture handlers normally present in RCTRootView, I’m going to “officially” recommend that for this use case, you not use that package and instead use useTVEventHandler() in your code. It will actually simplify this code.

Here’s your code modified to show the button on ‘select’ and hide it on ‘playPause’. If you really want to use the menu key, you would import TVMenuControl and call TVMenuControl.enableTVMenuKey() first.

I have an issue (#16 ) in the backlog to try to pull in some of the additional functionality of react-native-tvos-controller (particularly the pan gesture handling).

import React, { useState, } from 'react';
import ReactNative, {
  StyleSheet,
  View,
  Text,
  TouchableOpacity,
  useTVEventHandler,
} from 'react-native';

const App: () => React$Node = () => {
  const [toggle, setToggle] = useState(false);
  const myTVEventHandler = (evt: HWFocusEvent) => {
    if (evt.eventType === 'select') {
      setToggle(true);
    }
    if (evt.eventType === 'playPause') {
      setToggle(false);
    }
  };
  useTVEventHandler(myTVEventHandler);
  return (
    <View style={styles.root}>
      {toggle && (
        <TouchableOpacity hasTVPreferredFocus onPress={() => {
          console.log('press');
        }}>
          <Text style={styles.label}>Press me</Text>
        </TouchableOpacity>
      )}
    </View>
  );
};
Read more comments on GitHub >

github_iconTop Results From Across the Web

About Apple TV 4K and Apple TV HD software updates
To enable Siri, go to Settings > General > Siri. Then press the Siri button on your remote to see some examples of...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found