REGISTER

Handling Multiple Native iOS Views in React Native

Piotr Trocki
2019-06-03

blog content

Need help with React Native?
hire us
Our React Native EU Conference is back
register nowlearn more

Prerequisite

This article based on creating native ui components and native modules.

Intro

As a React Native developer with native background, I wanted to create an iOS view component of react-native-viewpager. This component allows the user to swipe left and right through pages of data.

I opened the docs and followed it step by step, which seemed to work just fine. I was wondering, what about the case, when the parent view will have multiple native children views?

Problem

Let’s consider the following case. React Native view can have more than one child view in the view tree eg.

Class MyNativeView is a wrapper for NativeComponent and exposes methods, which will be called on the iOS side. A component rendering two MyNativeView’s inside a View and it looks like as follow:

screenshot presenting a component rendering two MyNativeView’s inside a View

The above picture shows example application, which contains two MyNativeView’s and 2 ButtonContainer’s, which contain two buttons called next and previous. These buttons in ButtonContainer controls the behavior of the respective views.

When the user interacts with the component, like pressing the button or swipe, MyNativeView should change the page. In this case, the component would not know which MyNativeView should be handled and which MyNativeView should change page. Below you will find a solution to this problem:

Now the above component has a reference to a particular MyNativeView, which allows us to use a specific instance of MyNativeView. Now the button can control which MyNativeView should change its page.

Let’s assume, that goToNextPage and goToPreviousPage changes pages of viewpager and call Objective-C method in iOS component. The documentation says, that it should be implemented like above.

But another question is, which view should call one of the above methods? NativeComponent does not know, which view should change the page in this case. I’ve found the answer in React Native repository.

Solution

Let’s change implementation of goToNextPage and goToPreviousPage using UIManager

dispatchViewManagerCommand needs 3 parameters:

  • <rte-code>(nonnull NSNumber *)reactTag <rte-code>— id of react view.
  • <rte-code>commandID:(NSInteger)commandID<rte-code> — Id of native method, that should be called
  • <rte-code>commandArgs:(NSArray<id>*)commandArgs<rte-code> — Args of native method, that we can pass from JS to Native side.

Now let’s describe the iOS part. To expose this method in JS, NativeModule needs export function:

Here both methods are defined in the RNCMyNativeViewManager.m. Remember, that react bridge adds <rte-code>(nonnull NSNumber*)<rte-code> reactTag as the first parameter of each exported functions. This exported functions will find a particular view using addUIBlock, which contains the viewRegistry parameter and returns the component based on reactTag, allowing it to call the method on the correct component. Now we are sure, that an appropriate view is handled correctly.

Summary:

  • Use ref to create reference to your view component
  • Method <rte-code>UIManager.dispatchViewManagerCommand<rte-code> call exported method from native module
  • Remember to add <rte-code>(nonnull NSNumber*) reactTag<rte-code> as first parameter of exported function
  • Checkout github repo to see example usage

If you like the idea that I described in this article or want to talk about it, please contact me on Twitter. If you need more help in React Native or Open Source, feel free to contact us at Callstack.

Author:
Piotr Trocki
Software developer who started his journey from mobile apps. Now Piotr is focused on mastering both Native (Android, iOS) and React Native technologies in brownfield applications. When not coding, he spends his free time on the dance floor.
arrow icon
MORE posts from this author

learn more

More posts from this category

stay tuned

Subscribe to our newsletter

You may unsubscribe from these communications at any time. For details see the Privacy Policy.