react-native-pager-view: App Crash - UIViewControllerHierarchyInconsistency

Bug

When i open the app, it crashes sometimes ( %20 crash rate ) There is no log on console, Flipper can’t catch any error, Only Crashlytics catches the error.

  • Android is working very well.
  • There is no problem on version 3.3.0

Screen Shot 2020-05-05 at 17 21 56

react-native info output:

System:
    OS: macOS 10.15.3
    CPU: (4) x64 Intel(R) Core(TM) i5-5257U CPU @ 2.70GHz
    Memory: 162.63 MB / 8.00 GB
    Shell: 5.7.1 - /bin/zsh
  Binaries:
    Node: 12.11.1 - /usr/local/bin/node
    Yarn: 1.17.3 - /usr/local/bin/yarn
    npm: 6.14.5 - /usr/local/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  SDKs:
    iOS SDK:
      Platforms: iOS 13.2, DriverKit 19.0, macOS 10.15, tvOS 13.2, watchOS 6.1
    Android SDK: Not Found
  IDEs:
    Android Studio: Not Found
    Xcode: 11.3.1/11C505 - /usr/bin/xcodebuild
  Languages:
    Python: 2.7.16 - /usr/bin/python
  npmPackages:
    @react-native-community/cli: Not Found
    react: 16.13.1 => 16.13.1 
    react-native: 0.62.2 => 0.62.2 
  npmGlobalPackages:
    *react-native*: Not Found

Library version: 4.0.0

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 8
  • Comments: 58 (17 by maintainers)

Most upvoted comments

This seems to have to reappeared (5.4.0 + iOS).

Screenshot 2021-07-30 at 09 00 48
Exception thrown while executing UI block: A view can only be associated with at most one view controller at a time! View <RCTView: 0x7fe85544df90; reactTag: 7413; frame = (0 0; 0 0); layer = <CALayer: 0x6000002f6180>> is associated with <UIViewController: 0x7fe8550becb0>. Clear this association before associating this view with <UIViewController: 0x7fe854f78b50>.

__44-[RCTUIManager flushUIBlocksWithCompletion:]_block_invoke
    RCTUIManager.m:1193
__44-[RCTUIManager flushUIBlocksWithCompletion:]_block_invoke.493
__RCTExecuteOnMainQueue_block_invoke
_dispatch_call_block_and_release
_dispatch_client_callout
_dispatch_main_queue_callback_4CF
__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__
__CFRunLoopRun
CFRunLoopRunSpecific
GSEventRunModal
-[UIApplication _run]
UIApplicationMain
main
start
0x0

I narrowed down the problem in my case to version 4.1.0.

4.0.1: works as expected 4.1.0: throws the ViewController error above and the app crashes.

I had the same issue and @farad4y patch fixed it. Here is the patch created using patch-package:

diff --git a/node_modules/@react-native-community/viewpager/ios/ReactNativePageView.m b/node_modules/@react-native-community/viewpager/ios/ReactNativePageView.m
index cbb3b36..d7e8893 100644
--- a/node_modules/@react-native-community/viewpager/ios/ReactNativePageView.m
+++ b/node_modules/@react-native-community/viewpager/ios/ReactNativePageView.m
@@ -379,7 +379,7 @@ - (void)setReactViewControllers:(NSInteger)index
 
 - (UIViewController *)createChildViewController:(UIView *)view {
     UIViewController *childViewController = [[UIViewController alloc] init];
-    childViewController.view = view;
+    [childViewController.view addSubview: view];
     return childViewController;
 }

Also experiencing this on iOS. I tried reproducing in a sample project, but was not successful.

Here is a rough description of my setup:

I have a react-navigation TabNavigationController with three tabs, first and last have a ViewPager. Both use the same wrapper around ViewPager, with the following snippet:

  useEffect(() => {
    setPage(props.selectedTab);
    viewPager.current?.setPage(props.selectedTab);
  }, [props.selectedTab]);

On startup when the initial tab is the third one (I guess otherwise it just renders the first tab) I get the crash. However, I can fix it when replacing the above snippet with the following:

  useEffect(() => {
    setPage(props.selectedTab);
    setTimeout(() => {
      viewPager.current?.setPage(props.selectedTab);
    }, 50);
  }, [props.selectedTab]);

I hope this might help resolve the issue!

Had also the same problem, I used requestAnimationFrame(() => refViewPager.current?.setPage(index)); to avoid the exception.

Currently experiencing this issue

Exception thrown while executing UI block: A view can only be associated with at most one view controller at a time! 
View <RCTView: 0x7fe0e7e62ad0; reactTag: 355; frame = (0 0; 414 896); layer = <CALayer: 0x600003a877c0>> is associated 
with <UIViewController: 0x7fe0e7c4e450>. Clear this association before associating this view with 
<UIViewController: 0x7fe0e7c56060>.

__44-[RCTUIManager flushUIBlocksWithCompletion:]_block_invoke
    RCTUIManager.m:1192
__44-[RCTUIManager flushUIBlocksWithCompletion:]_block_invoke.489
__RCTExecuteOnMainQueue_block_invoke
_dispatch_call_block_and_release
_dispatch_client_callout
_dispatch_main_queue_callback_4CF
__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__
__CFRunLoopRun
CFRunLoopRunSpecific
GSEventRunModal
-[UIApplication _run]
UIApplicationMain
main
start
0x0

I’m trying to integrate a dialog component inside one of the pages. It works well on android. But not on iOS. I’m trying to find the cause. I tried to place my dialog component on its parent module. but still the same. Someone might know a fix or any advise? Thanks!

I reopening this issue, because bug still exist

There may be a race condition causing this crash.

UIViewControllerHierarchyInconsistency A view can only be associated with at most one view controller at a time!

In ReactNativePageView.m the createChildViewController is called with the same array of UIViews (self.reactSubviews) from renderChildrenViewControllers and addPages.

The @farad4y 's patch fixes the issue because addSubview removes the previous superview if needed before adding it to the new superview.

@troZee I replaced childViewController.view = view; to [childViewController.view addSubview: view]; then issue is solved

I can’t provide any reproducible example right now, i have to create a new project for this

@Bardiamist I have pushed a new commit. Could you retest it ?

LGTM. Tested 5 times without crash. Gesture was fixed.

Can anyone test this code ? #432

Instructions:

I tested. Looks no crash (it not 100% reproducable for me so tested 6 times without errors). But I can’t change page by gesture with this code.

Also faced the same problem

Can you try to change:

   {displayList && displayList.map((share,index) =>
          renderSlide(share, index)
        )}

into:

{ (displayList || []).map((share,index) =>
        renderSlide(share, index)
 )}

Also faced the same problem. omg i hope this fixes.

Have upgraded to “@react-native-community/viewpager”: “^4.1.3”, and will monitor

I’m facing the same problem. I’ll try to upgrade the version and see if it’s fixed.

Extra info: We use redux-offline. When i disable redux-online, works perfectly. This is really strange because there is no problem on version 3.3.0