DEV Community

Cover image for How to implement Split View on a tablet with React Native
Davyd NRB
Davyd NRB

Posted on • Updated on

How to implement Split View on a tablet with React Native

Tried to implement a Split View I found out the next:

1) wix/react-native-navigation has support Split View on iOS only.
2) react-navigation has only feature request for Tablet dual pane support


Is it possible with little effort to get the desired result?

Yes is it! You can check:

qr code


Someone recommends using an adaptable layout, but if we need to have an ability to "push" screens components into a separate area and support a back gesture (iOS) and a system back (Android)

Let me demonstrate the result before I explain how it works:

phone tablet
phone tablet

As you see above when split view enabled some screens opened in left or right areas. It is possible due to two container navigator.

// Main navigator
<NavigationContainer>
  <SplitView>
    <LeftStack />

    // Additional navigator
    {isTablet ? <NavigationContainer
      independent={true}
      /* 
          `independent={true}` Ignore exception when containers are nested within another
          See: https://github.com/react-navigation/react-navigation/commit/d4072e7d885222bc14f33734008f2bd10ff78bc4
      */
    >
      <RightStack />
    </NavigationContainer> : null}
  </SplitView>
</NavigationContainer>
Enter fullscreen mode Exit fullscreen mode

And to push a screen to an additional navigator we need to check it is mounted:

const pushChatSettingsScreen = ({userId}) => {
  const args = [CHAT_SETTINGS_SCREEN, {userId}];

  if (isDetailsNavigatorMounted()) {
    return detailsPush(...args);
  }

  return push(...args);
};
Enter fullscreen mode Exit fullscreen mode

src: MessageScreen/navigation.js

To understand how push \ isDetailsNavigatorMounted works please check source code of Navigator


Support system back on Android

When you try to return to a previous screen using a "system back" on Android you will be faced with the next error:

The action 'GO_BACK' was not handled by any navigator.

Is there any screen to go back to?
Enter fullscreen mode Exit fullscreen mode

It happens because each NavigationContainer subscribe on hardwareBackPress of BackHandler. And let see note about listeners invoking:

The event subscriptions are called in reverse order (i.e. the last registered subscription is called first).

So we have two <NavigationContainer/> that subscribed BackHandler and when a user press a back button only the last control all "go hack" behavior

To fix it created a specific HOC withSystemBackFix that implement the desired behavior. I wrapped all screens that would be open in split view

As a result, all screens will be closed in order how they were opened:

android


So use an example app to understand all aspects of my implementation of Split View
if you have any question I am glad to discuss them in the comments!

(c) MurAmur

Top comments (1)

Collapse
 
simplecreations profile image
SimpleCreations

Hi! The example uses two nested navigation containers. I need to be able to initiate navigation to different parts of my app from the right side column, but its navigation prop only refers to the inner navigation container and doesn't "know" about the outer navigation container. Is there a workaround for this?