Focus Management is a system designed for 10-foot screen to let the user select a particular visual element or component on a screen. You can use one of the following options to use focus:
When an element is focused, it is highlighted to confirm the user that element is focused or selected for further action:
You.i Platform is able to dynamically calculate how it should manage focus behaviors, but sometimes it is necessary to implement custom behaviors such as focusing between elements that aren’t directionally aligned, or setting the ‘default’ item to focus on when visiting a page.
You.i Platform also has callbacks such as onFocus
and onBlur
to implement custom behavior when an element receives or loses focus.
For details on advanced focus management, see:
Focus management is required to make 10-foot navigation easy for app users. Without it, there is no way to let the user know if a visual element, such as image or button, is selected for any further action. The following diagram explains the how focus works in a default scenario for any 10-foot device:
Focus management is not required on touch devices as the elements present are navigated with a remote or keyboard keys, or game controllers using touch or swipe.
The following topics explains important focus-related concepts that a developer should know to work with You.i React Native-based app:
Use the FocusManager module to set the default focus using the focus()
function.
FocusManager.focus(componentRef);
FocusManager.focus()
can be used from any callback or with any function that gives you a ref to your component (regardless of whether the component is a Facebook RN component or a You.i Ref component such as ButtonRef
.
For example it can be from a ref callback, or from a callback like onLoad
.
A common way to do this is to store the ref and then set use it in the parent’s componentDidMount
lifecycle method.
class Screen extends React.Component {
buttonRef = React.createRef()
componentDidMount() {
FocusManager.focus(this.buttonRef.current);
}
render() {
return <Button ref={this.buttonRef} />
}
}
But you could also do this as soon as a focusable component’s ref is accessible, as in these next two examples:
//example showing focus as part of the ref callback
class Screen extends React.Component { {
_onRef = ref => {
FocusManager.focus(ref);
}
render() {
return <Button ref={this._onRef} />
}
}
//example using onLoad for ButtonRef, could substitute any other callback that gives a ref
class Screen extends React.Component {
_onLoad = ref => {
FocusManager.focus(ref);
}
render() {
return <ButtonRef onLoad={this._onLoad} />
}
}
For more information on the onLoad
callback, see Holding References to Ref Components.
The ref components in You.i React Native provides various callbacks for focus management. Refer to the following use cases to help understand how to use the focus-related callbacks:
To determine if a ref component has gained focus or lost focus, use onFocus
and onBlur
respectively.
For example:
<ViewRef
onFocus={() => {}}
onBlur={() => {}}
/>
To determine if a child ref component has gained or lost focus, use onFocusInDescendants
and onBlurInDescendants
respectively.
For example:
<ViewRef
onFocusInDescendants={() => {}}
onBlurInDescendants={() => {}}
/>
Any You.i React Native component is focusable, if its focusable
and visible
props are true
.
To make a You.i React Native component focusable, set the focusable
prop as true
.
Similarly, to make a You.i React Native component visible, set the visible
prop as true
.
ScrollRef component is not focusable, but handles focus in its descendants, that is list items.
Therefore, list items must have the focusable
prop set as true
.
Sometimes, you may want to override the default focus behavior provided by You.i React Native.
For this case, you can use setNextFocus()
to override default behavior and define your own.
The setNextFocus()
function takes three arguments:
For more information, see Working with the Focus Manager module.
If you have a sticky header set on a vertical ScrollView
, where both the header and the list items underneath are focusable, and the header is overlapping a currently focused list item, you might not be able to switch focus from the list item to the overlapping sticky header.
This is due to You.i React Native’s default focus logic.
To prevent this situation, you can either offset the size of your header by setting list magnets using snapToInterval
or through layout styling, or make your sticky headers not focusable.
Note this is the same for both sticky headers and invert sticky headers.
Using the focusable
prop, you can control whether a component should receive focus or not with You.i React Native.
When focusable
is set to false, the selected component will not be selected or receive focus.
If a view gets covered by another view, or another screen in the event of react-navigation, it is better to set the visible
prop to false.
This disables focus and prevents overdraw.
Even better, it cascades, so you can surround the entire screen with a ViewRef
component and hide it.
Sometimes, you want focus to remain within a single composition. For example, if you have an overlay that you need to show, and you want the focus system to only allow focusing on items within that composition instead of underneath, you will need to set it as the focus root.
When an item is set as the Focus Root in the scene tree, only itself or its children will be able to receive focus.
It is as if you set the focusable
prop to false on all the components that are not a child of the focus root.
For more information on setFocusRoot()
, see Working with the Focus Manager module.
For the default behavior of You.i React Native solution, focus management does not need anything more than Focus In and Focus Out timelines with animation for any view. You should always have Focus In and Focus Out timelines for any ViewRef to get it focused. Also if you have the timelines for focus, but do not have any focus animation on them, the user will never know if the particular view is selected or not.
Any UI component or View added from You.i Library will have Focus In and Focus Out timelines by default.
The React Native does very little focus management of its own with this integration of You.i Platform.
Facebook React Native communicates with You.i Platform on the focusable views, via the isTVSelectable
prop, and responds to focus in/out events, via onFocus
and onBlur
, respectively.
The following screen shot displays the Focus In and Focus Out timelines in After Effects:
The Focus In timeline allows a button to receive focus and key events automatically, if the button follows all the focus management rules. Removing the Focus In timeline will disallow the button from receiving the key press events, but it can still be manually focusable.
The following GIF illustrates the difference between Focus In start and end points and how animation plays a major role for focus management:
The following GIF illustrates the difference between Focus Out start and end points and how animation plays a major role for focus management:
Focus is handled differently in You.i React Native components with AE workflow and without AE workflow. The following table explains the differences:
Focus in You.i React Native Components with AE workflow | Focus in You.i React Native components without AE workflow |
---|---|
|
|
The safest place to set initial focus is in componentDidMount
as it runs after the first render call and works for both You.i React Native components with AE workflow and You.i React Native components without AE workflow.
Two custom React Native components, FocusZone
and FocusZoneRef
, allow you to harness the power of CYIFocusZoneView in the React Native layer and within After Effects.
These components enable you to determine where focus lands in a view, allowing you to override the Engine’s default focus logic.
These components employ a prop, entryMode
, and a function, setInitialFocus
/setInitialFocusRef
, that determine which entries in a subtree gain focus and retain it when the view connected to that subtree is exited and returned to.
The modes, and how they behave with and without an initial focus, are the following:
Mode | Behavior | If Initial Focus is Set | If Initial Focus is not Set or is Invalid |
---|---|---|---|
Normal | Behaves like a normal view; doesn’t require special handling, i.e., it follows the default focus logic of the You.i Platform. | It’s used for the first entry into the subtree. Consecutive entries behave as normal. | Behaves as normal. |
None | Focus won’t enter this component or its subtree (regardless of initial focus setting). Focus can still be explicitly assigned by requesting focus on an item within the disabled focus zone. | n/a | n/a |
Last | When focus enters the subtree, it’s given to the last thing that had focus in this subtree. | It’s used for the first entry into the subtree. Consecutive entries apply focus to the last thing that had focus in the subtree. | The first entry behaves as normal, and consecutive entries apply focus to the last thing that had focus in the subtree. |
Fixed | When focus enters the subtree, it’s given to the specified initial focus view. | It’s used for every focus entry to the subtree. | Behaves as normal. |
FocusZone
and FocusZoneRef
can be used with the Focus Manager module’s setNextFocus
function to specify where the focus will go when leaving the subtree rooted at the FocusZone
.
For details on usage, including code samples, refer to the FocusZone and FocusZoneRef component reference.
Like other You.i React Native ref components, FocusZoneRef
allows you to directly connect to views in After Effects Compositions.
For more on FocusZoneRef
and the After Effects workflow, see Setting Focus in After Effects.
The Dev panel has a tool called Focus Debugger for debugging focus when you encounter issues. It shows what You.i React Native thinks it should be handling focus at any given time. For more information on Dev Panel, see Using Dev Panel for Debugging.
When you select Focus Debugger from the Dev panel and as you navigate around the app, you can see debug draws of where focus will go for any given direction from a certain element.