Giter Site home page Giter Site logo

software-mansion / react-native-screens Goto Github PK

View Code? Open in Web Editor NEW
2.8K 42.0 484.0 37.32 MB

Native navigation primitives for your React Native app.

License: MIT License

JavaScript 10.13% Java 2.13% Objective-C 2.41% Ruby 0.75% Starlark 0.16% TypeScript 47.98% C++ 4.59% C 0.18% Shell 0.01% Kotlin 13.39% Objective-C++ 18.11% CMake 0.16%
typescript react-native react-navigation

react-native-screens's Introduction

React Native Screens by Software Mansion

This project aims to expose native navigation container components to React Native. It is not designed to be used as a standalone library but rather as a dependency of a full-featured navigation library.

Fabric

To learn about how to use react-native-screens with Fabric architecture, head over to Fabric README. Instructions on how to run Fabric Example within this repo can be found in the FabricExample README.

Supported platforms

  • iOS
  • Android
  • tvOS
  • visionOS
  • Windows
  • Web

Installation

iOS

Installation on iOS is completely handled with auto-linking, if you have ensured pods are installed after adding this module, no other actions are necessary.

Android

On Android the View state is not persisted consistently across Activity restarts, which can lead to crashes in those cases. It is recommended to override the native Android method called on Activity restarts in your main Activity, to avoid these crashes.

For most people using an app built from the react-native template, that means editing MainActivity.java, likely located in android/app/src/main/java/<your package name>/MainActivity.java

You should add this code, which specifically discards any Activity state persisted during the Activity restart process, to avoid inconsistencies that lead to crashes. Please note that the override code should not be placed inside MainActivityDelegate, but rather directly in MainActivity.

Java
import android.os.Bundle;

public class MainActivity extends ReactActivity {

    //...code

    //react-native-screens override
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(null);
    }

    public static class MainActivityDelegate extends ReactActivityDelegate {
        //...code
    }
}
Kotlin
import android.os.Bundle;

class MainActivity: ReactActivity() {

    //...code

    //react-native-screens override
    override fun onCreate(savedInstanceState: Bundle?) {
      super.onCreate(null);
    }
}

For people that must handle cases like this, there is a more detailed discussion of the difficulties in a series of related comments.

Need to use a custom Kotlin version?

Since v3.6.0 react-native-screens has been rewritten with Kotlin. Kotlin version used in this library defaults to 1.4.10.

If you need to use a different Kotlin version, set kotlinVersion ext property in your project's android/build.gradle and the library will use this version accordingly:

buildscript {
    ext {
        ...
        kotlinVersion = "1.4.10"
    }
}

Disclaimer: react-native-screens requires Kotlin 1.3.50 or higher.

Windows

Installation on Windows should be completely handled with auto-linking when using React Native Windows 0.63+. For earlier versions, you must manually link the native module.

How can I take advantage of that?

Screens are already integrated with the React Native's most popular navigation library react-navigation and Expo.

Supported react-native version

library version react-native version
3.30.0+ 0.68.0+
3.14.0+ 0.64.0+
3.0.0+ 0.62.0+
2.0.0+ 0.60.0+

Support for Fabric

Fabric is React Native's new rendering system.

Here's a table with summary of supported react-native versions when Fabric is turned on.

library version react-native version
3.28.0+ 0.73.0+
3.21.0+ 0.72.0+
3.19.0+ 0.71.0+
3.18.0+ 0.70.0+
3.14.0+ 0.69.0+

Usage with react-navigation

Screens support is built into react-navigation starting from version 2.14.0 for all the different navigator types (stack, tab, drawer, etc).

To configure react-navigation to use screens instead of plain RN Views for rendering screen views, simply add this library as a dependency to your project:

# bare React Native project
yarn add react-native-screens

# if you use Expo managed workflow
npx expo install react-native-screens

Just make sure that the version of react-navigation you are using is 2.14.0 or higher.

You are all set 🎉 – when screens are enabled in your application code react-navigation will automatically use them instead of relying on plain React Native Views.

Experimental support for react-freeze

You have to use React Native 0.68 or higher, react-navigation 5.x or 6.x and react-native-screens >= v3.9.0

Since v3.9.0, react-native-screens comes with experimental support for react-freeze. It uses the React Suspense mechanism to prevent parts of the React component tree from rendering, while keeping its state untouched.

To benefit from this feature, enable it in your entry file (e.g. App.js) with this snippet:

import { enableFreeze } from 'react-native-screens';

enableFreeze(true);

Want to know more? Check out react-freeze README

Found a bug? File an issue here or directly in react-freeze repository.

Disabling react-native-screens

If, for whatever reason, you'd like to disable native screens support and use plain React Native Views add the following code in your entry file (e.g. App.js):

import { enableScreens } from 'react-native-screens';

enableScreens(false);

You can also disable the usage of native screens per navigator with detachInactiveScreens.

Using createNativeStackNavigator with React Navigation

To take advantage of the native stack navigator primitive for React Navigation that leverages UINavigationController on iOS and Fragment on Android, please refer:

FullWindowOverlay

Native iOS component for rendering views straight under the Window. Based on RCTPerfMonitor. You should treat it as a wrapper, providing full-screen, transparent view which receives no props and should ideally render one child View, being the root of its view hierarchy. For the example usage, see https://github.com/software-mansion/react-native-screens/blob/main/TestsExample/src/Test1096.tsx

React-native-navigation library already uses native containers for rendering navigation scenes so wrapping these scenes with <ScreenContainer> or <Screen> component does not provide any benefits. Yet if you would like to build a component that uses screens primitives under the hood (for example a view pager component) it is safe to use <ScreenContainer> and <Screen> components for that as these work out of the box when rendered on react-native-navigation scenes.

Interop with other libraries

This library should work out of the box with all existing react-native libraries. If you experience problems with interoperability please report an issue.

Guide for navigation library authors

If you are building a navigation library you may want to use react-native-screens to have control over which parts of the React component tree are attached to the native view hierarchy. To do that, react-native-screens provides you with the components documented here.

Common problems

Problems with header on iOS

Solution

Use ScrollView with prop contentInsetAdjustmentBehavior=“automatic” as a main container of the screen and set headerTranslucent: true in screen options.

Other problems

Problem Solution
SVG component becomes transparent when goBack related PRs
Memory leak while moving from one screen to another in the same stack explanation
LargeHeader stays small after pop/goBack/swipe gesture on iOS 14+ potential fix
onScroll and onMomentumScrollEnd of previous screen triggered in bottom tabs explanation

Contributing

There are many ways to contribute to this project. See CONTRIBUTING guide for more information. Thank you for your interest in contributing!

License

React native screens library is licensed under The MIT License.

Credits

This project has been build and is maintained thanks to the support from Shopify, Expo.io, and Software Mansion.

shopify expo swm

react-native-screens's People

Contributors

aleqsio avatar brentvatne avatar burakgormek avatar dependabot[bot] avatar dylancom avatar evanbacon avatar hufkens avatar jakub-gonet avatar janicduplessis avatar jb1905 avatar jkadamczyk avatar kacperkapusciak avatar kelset avatar kirillzyusko avatar kkafar avatar kmagiera avatar luism3861 avatar magicismight avatar osdnk avatar piaskowyk avatar r0b0t3d avatar radex avatar radko93 avatar satya164 avatar scottmas avatar tboba avatar tomekzaw avatar ubax avatar v-fernandez avatar wolewicki avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-native-screens's Issues

Keyboard not dismissing

Having some weird keyboard behavior when enabling Screens. Keyboard doesn't dismiss after navigating to another screen and back. Even on Keyboard.dismiss() call. It seems like without Screens keyboard is dismissed on every navigation.

Repo: https://snack.expo.io/@andrey/keyboard-bug
Focus TextInput -> Next Screen -> Back -> Keyboard is not dismissing

Touch events do not work when multiple screens are active on Android

I added a way to have transparent scenes in react-navigation a while back to support dialogs (https://github.com/react-navigation/react-navigation-stack/blob/master/src/views/StackView/StackViewCard.js#L35). It keeps all screens active in the stack but this seems to break touch events on Android because of the logic here: https://github.com/kmagiera/react-native-screens/blob/master/android/src/main/java/com/swmansion/rnscreens/ScreenContainer.java#L189

The react-navigation code is basically this:

const modalNavigatorConfig = {
  initialRouteName: 'app',
  mode: 'modal',
  headerMode: 'none',
  transparentCard: true, // <- The option for transparent card
  defaultNavigationOptions: {
    gesturesEnabled: false,
  },
  transitionConfig: () => ({
    transitionSpec: {
      duration: 300,
      easing: Easing.inOut(Easing.ease),
      timing: Animated.timing,
    },
    screenInterpolator: sceneProps => {
      const { position, scene } = sceneProps;
      const { index } = scene;

      const opacity = position.interpolate({
        inputRange: [index - 1, index],
        outputRange: [0, 1],
      });

      return { opacity };
    },
  }),
};

const ModalStack = createAppContainer(
  createStackNavigator(
    {
      app: {
        screen: RootStack,
      },
      { screen: SomeOtherRoute },
    },
    modalNavigatorConfig,
  ),
);

Question: does it work out of the box with react-native-gesture-handler?

If I'm not mistaken, to make react-native-gesture-handler work with native navigation libraries (like wix's react-native-navigation), additional steps of setting it up are required. Does additional steps required if one uses react-native-screens with react-native-gesture-handler?

It would be great to have an answer to this question in README.

Unable to resolve module: ReactNativeVersion

I get an error when trying to run a React Native app on iOS simulator.

"Unable to resolve module 'react-native/Libraries/Core/ReactNativeVersion' from '/users/...../node_modules/react-native-screens/src/screens.native.js"

It's been absolutely fine for months until i installed a package (moment.js or moment). I believe this is absolutely irrelevant.

RN version 0.47.1
React Version: 16.0.0-alpha12

How can this be resolved?

add a changelog

it would be great to have a changelog to describe any feature or breaking changes

[bug] The app will not respond to any interaction after navigate back from modal mode StackNavigator with empty screen interpolator

Thank you for this amazing library! However, when fidding with the library and knowing it's still in alpha, so I would like to report this new issue and you can find the reproducible snack here:
https://snack.expo.io/@bankify_expo_admin/react-native-screen-stack-empty-interpolation-bug

So basically I make a StackNavigator, make the mode to be 'modal' and then customize the transition that make the duration to be 0 (this is in my own app use case when I'm deciding to test out this library). After navigating back to the previous screen, the app won't respond to any interaction from user.

--UPDATE--
It's seem that the 0 duration was not the culprit but because of the empty screenInterpolator: () => ({}), in the transitionConfig

IllegalStateException:getOrCreateTransaction - Android Crash on app launch

Getting some random crashes on android, the crash reported to use android ReactFragmentActivity, irrespective of the MainActivity extended from ReactFragmentActivity

public class MainActivity extends ReactFragmentActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(null);

    }


java.lang.IllegalStateException: In order to use RNScreens components your app's activity need to extend ReactFragmentActivity or ReactCompatActivity
    at com.swmansion.rnscreens.ScreenContainer.getOrCreateTransaction(ScreenContainer.java:88)
    at com.swmansion.rnscreens.ScreenContainer.attachScreen(ScreenContainer.java:103)
    at com.swmansion.rnscreens.ScreenContainer.updateIfNeeded(ScreenContainer.java:175)
    at com.swmansion.rnscreens.ScreenContainer.onAttachedToWindow(ScreenContainer.java:127)
    at android.view.View.dispatchAttachedToWindow(View.java:15535)
    at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2918)
    at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2925)
    at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2925)
    at android.view.ViewGroup.addViewInner(ViewGroup.java:4458)
    at android.view.ViewGroup.addView(ViewGroup.java:4260)
    at android.view.ViewGroup.addView(ViewGroup.java:4200)
    at com.facebook.react.uimanager.ViewGroupManager.addView(ViewGroupManager.java:39)
    at com.facebook.react.uimanager.NativeViewHierarchyManager.manageChildren(NativeViewHierarchyManager.java:438)
    at com.facebook.react.uimanager.UIViewOperationQueue$ManageChildrenOperation.execute(UIViewOperationQueue.java:227)
    at com.facebook.react.uimanager.UIViewOperationQueue$1.run(UIViewOperationQueue.java:894)
    at com.facebook.react.uimanager.UIViewOperationQueue.flushPendingBatches(UIViewOperationQueue.java:1001)
    at com.facebook.react.uimanager.UIViewOperationQueue.access$2400(UIViewOperationQueue.java:46)
    at com.facebook.react.uimanager.UIViewOperationQueue$2.runGuarded(UIViewOperationQueue.java:959)
    at com.facebook.react.bridge.GuardedRunnable.run(GuardedRunnable.java:24)
    at android.os.Handler.handleCallback(Handler.java:754)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:163)
    at android.app.ActivityThread.main(ActivityThread.java:6228)
    at java.lang.reflect.Method.invoke(Method.java)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)

Use transparent fragment by default

On my react native App, I have a section that have look like this:

image

When you go to the next page, the blue image background remains fixed while the page go over.

We achieved this by doing something like that:

const ChapterWrapper = createStackNavigator(
  {
    "A": {
      screen: Question,
    },
    "B": {
      screen: Question,
    },
  },
  {
    cardStyle: {
      backgroundColor: 'transparent',
    },
    transitionConfig: () => ({
      // some custom animation, simplified because not impacting the issue
      containerStyle: {
        backgroundColor: 'transparent',
      },
    }),
  }
);

class QuestionsWrapper extends Component<
  IProps & IProfileCaptureContainerProps
> {
  public render() {
    return (
      <Fragment>
        <BackgroundContainer>
          <BackgroundImage chapter={this.getBackgroundChapterImage()} />
        </BackgroundContainer>
        <PageContainer>
          <ChapterWrapper navigation={this.props.navigation} />
        </PageContainer>
      </Fragment>
    );
  }
  private getBackgroundChapterImage = () => {
    const chapterLabel = this.props.navigation.getParam('chapterLabel');
  };
}

When installing react-native screen the Screen container have the default light grey android background that looks like this:

image

The explanation is that there is then this view hierarchie:

image

in this image, the background (in green) is between the first and the second view container (red).
Since the background of them are not transparent (they have android default), the image is not shown. (my hypothesis, maybe I'm completely wrong).

I fixed this using patch package:

patch-package
--- a/node_modules/react-native-screens/android/src/main/java/com/swmansion/rnscreens/Screen.java
+++ b/node_modules/react-native-screens/android/src/main/java/com/swmansion/rnscreens/Screen.java
@@ -2,6 +2,7 @@ package com.swmansion.rnscreens;
 
 import android.annotation.SuppressLint;
 import android.content.Context;
+import android.graphics.Color;
 import android.os.Bundle;
 import android.support.annotation.Nullable;
 import android.support.v4.app.Fragment;
@@ -29,6 +30,7 @@ public class Screen extends ViewGroup {
     public View onCreateView(LayoutInflater inflater,
                              @Nullable ViewGroup container,
                              @Nullable Bundle savedInstanceState) {
+      mScreenView.setBackgroundColor(Color.TRANSPARENT);
       return mScreenView;
     }
   }

I'm happy to contribute to this repo but I will first discuss the solution

  • are transparent fragment hacky ?
  • should it be configurable somehow ?

useScreens() and transparentCard issue

When using react-native-screens with react-navigation 3 , enabling both useScreens() and transparentCard in the createStackNavigator options causes weird issues.

On iOS, if having more than 3 routes in the StackNavigator, when going back to the 2nd screen, you will not be able to interact the view anymore. Apparently something blocks it.
On Android, the 2nd screen is not clickable from the first time you navigate to it.

Here is a repo to reproduce this : https://github.com/ovy9086/react-nav-transparent-card-bug

Android crash: Can not perform this action after onSaveInstanceState

I'm seeing this crash in production, not sure how to repro.

java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
    at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:2053)
    at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:2079)
    at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:678)
    at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:632)
    at com.swmansion.rnscreens.ScreenContainer.tryCommitTransaction(ScreenContainer.java:99)
    at com.swmansion.rnscreens.ScreenContainer.updateIfNeeded(ScreenContainer.java:173)
    at com.swmansion.rnscreens.ScreenContainer.onAttachedToWindow(ScreenContainer.java:129)
    at android.view.View.dispatchAttachedToWindow(View.java:18623)
    at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3520)
    at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3527)
    at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3527)
    at android.view.ViewGroup.addViewInner(ViewGroup.java:5162)
    at android.view.ViewGroup.addView(ViewGroup.java:4953)
    at android.view.ViewGroup.addView(ViewGroup.java:4893)
    at com.facebook.react.uimanager.ViewGroupManager.addView(ViewGroupManager.java:45)
    at com.facebook.react.uimanager.NativeViewHierarchyManager.manageChildren(NativeViewHierarchyManager.java:438)
    at com.facebook.react.uimanager.UIViewOperationQueue$ManageChildrenOperation.execute(UIViewOperationQueue.java:227)
    at com.facebook.react.uimanager.UIViewOperationQueue$1.run(UIViewOperationQueue.java:914)
    at com.facebook.react.uimanager.UIViewOperationQueue.flushPendingBatches(UIViewOperationQueue.java:1021)
    at com.facebook.react.uimanager.UIViewOperationQueue.access$2500(UIViewOperationQueue.java:46)
    at com.facebook.react.uimanager.UIViewOperationQueue$2.runGuarded(UIViewOperationQueue.java:979)
    at com.facebook.react.bridge.GuardedRunnable.run(GuardedRunnable.java:24)
    at android.os.Handler.handleCallback(Handler.java:789)
    at android.os.Handler.dispatchMessage(Handler.java:98)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6944)
    at java.lang.reflect.Method.invoke(Method.java)
    at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)

Seems to be some info about this crash here https://stackoverflow.com/questions/7575921/illegalstateexception-can-not-perform-this-action-after-onsaveinstancestate-wit, not sure what the ideal fix would be.

Keyboard doesn't show up when autoFocus on component mount

Hello,

I am trying to use react-native-screens combine with react-navigation for my app for better performance, however I have a weird problem. Indeed, when I have a new page mounting with a TextInput set on autoFocus, it focused as expected but the keyboard does not show up on the screen.

If I don't put useScreens() it works perfectly, the TextInput is focused and the Keyboard appears.

react-native: 0.59.1;
react-navigation: 3.8.1;
react-native-screens: 1.0.0-alpha.22;
OS: Android;
Device: Real;

Blank screen

I am getting blank screen after installing react native screens although I followed the setup exactly line by line.

my dependencies:

"dependencies": {
    "@fortawesome/pro-light-svg-icons": "^5.8.1",
    "flow-bin": "^0.96.0",
    "react": "^16.8.6",
    "react-native": "^0.59.3",
    "react-native-gesture-handler": "^1.1.0",
    "react-native-screens": "^1.0.0-alpha.22",
    "react-native-svg": "^9.3.6",
    "react-navigation": "^3.6.1"
  }
// @flow
import React from 'react'
import { createBottomTabNavigator, createAppContainer } from 'react-navigation'
import { useScreens } from 'react-native-screens'
import { Explore, NewsFeed } from './Screens'

useScreens()

const AppNavigator = createAppContainer(
  createBottomTabNavigator(
    {
      Explore: { screen: Explore },
      NewsFeed: { screen: NewsFeed }
    }
    }
  )
)

export default AppNavigator

Tried on iPhone 6, 7 and ios simulator

Also I noticed that the example folder had react native fixed to version 0.57 is there a reason behind this? or does this library works only with react native 0.57

Reanimated version of screens

It would be helpful to have an import like react-native-screens/reanimated that gives you the same thing as screens.js but using reanimated rather than animated.

Android crashes nondeterministically when restoring from background

Hi,

at least in release builds I'm getting crashes when restoring app from background, but not always. I replaced ReactActivity with ReactFragmentActivity.

react-native: 0.57.0

Fatal Exception: java.lang.RuntimeException: Unable to start activity ComponentInfo{com._redacted_.app/com._redacted_.app.MainActivity}: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment com.swmansion.rnscreens.Screen$ScreenFragment: calling Fragment constructor caused an exception
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2747)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2808)
       at android.app.ActivityThread.-wrap12(ActivityThread.java)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1541)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:165)
       at android.app.ActivityThread.main(ActivityThread.java:6365)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:883)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
       at android.support.v4.app.Fragment.instantiate(Fragment.java:386)
       at android.support.v4.app.FragmentContainer.instantiate(FragmentContainer.java:33)
       at android.support.v4.app.FragmentState.instantiate(FragmentState.java:79)
       at android.support.v4.app.FragmentManagerImpl.restoreAllState(FragmentManager.java:3080)
       at android.support.v4.app.FragmentController.restoreAllState(FragmentController.java:152)
       at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:330)
       at com.facebook.react.ReactFragmentActivity.onCreate(ReactFragmentActivity.java:54)
       at com._redacted_.app.MainActivity.onCreate(MainActivity.java:19)
       at android.app.Activity.performCreate(Activity.java:6852)
       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2700)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2808)
       at android.app.ActivityThread.-wrap12(ActivityThread.java)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1541)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:165)
       at android.app.ActivityThread.main(ActivityThread.java:6365)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:883)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
Caused by java.lang.reflect.InvocationTargetException
       at java.lang.reflect.Constructor.newInstance0(Constructor.java)
       at java.lang.reflect.Constructor.newInstance(Constructor.java:430)
       at android.support.v4.app.Fragment.instantiate(Fragment.java:364)
       at android.support.v4.app.FragmentContainer.instantiate(FragmentContainer.java:33)
       at android.support.v4.app.FragmentState.instantiate(FragmentState.java:79)
       at android.support.v4.app.FragmentManagerImpl.restoreAllState(FragmentManager.java:3080)
       at android.support.v4.app.FragmentController.restoreAllState(FragmentController.java:152)
       at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:330)
       at com.facebook.react.ReactFragmentActivity.onCreate(ReactFragmentActivity.java:54)
       at com._redacted_.app.MainActivity.onCreate(MainActivity.java:19)
       at android.app.Activity.performCreate(Activity.java:6852)
       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2700)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2808)
       at android.app.ActivityThread.-wrap12(ActivityThread.java)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1541)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:165)
       at android.app.ActivityThread.main(ActivityThread.java:6365)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:883)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
Caused by java.lang.IllegalStateException: Screen fragments should never be restored
       at com.swmansion.rnscreens.Screen$ScreenFragment.<init>(Screen.java:19)
       at java.lang.reflect.Constructor.newInstance0(Constructor.java)
       at java.lang.reflect.Constructor.newInstance(Constructor.java:430)
       at android.support.v4.app.Fragment.instantiate(Fragment.java:364)
       at android.support.v4.app.FragmentContainer.instantiate(FragmentContainer.java:33)
       at android.support.v4.app.FragmentState.instantiate(FragmentState.java:79)
       at android.support.v4.app.FragmentManagerImpl.restoreAllState(FragmentManager.java:3080)
       at android.support.v4.app.FragmentController.restoreAllState(FragmentController.java:152)
       at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:330)
       at com.facebook.react.ReactFragmentActivity.onCreate(ReactFragmentActivity.java:54)
       at com._redacted_.app.MainActivity.onCreate(MainActivity.java:19)
       at android.app.Activity.performCreate(Activity.java:6852)
       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2700)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2808)
       at android.app.ActivityThread.-wrap12(ActivityThread.java)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1541)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:165)
       at android.app.ActivityThread.main(ActivityThread.java:6365)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:883)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
Fatal Exception: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
       at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:2053)
       at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:2079)
       at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:678)
       at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:632)
       at com.swmansion.rnscreens.ScreenContainer.tryCommitTransaction(ScreenContainer.java:99)
       at com.swmansion.rnscreens.ScreenContainer.updateIfNeeded(ScreenContainer.java:173)
       at com.swmansion.rnscreens.ScreenContainer.access$000(ScreenContainer.java:21)
       at com.swmansion.rnscreens.ScreenContainer$1.doFrame(ScreenContainer.java:34)
       at com.facebook.react.modules.core.ReactChoreographer$ReactChoreographerDispatcher.doFrame(ReactChoreographer.java:134)
       at com.facebook.react.modules.core.ChoreographerCompat$FrameCallback$1.doFrame(ChoreographerCompat.java:105)
       at android.view.Choreographer$CallbackRecord.run(Choreographer.java:964)
       at android.view.Choreographer.doCallbacks(Choreographer.java:778)
       at android.view.Choreographer.doFrame(Choreographer.java:710)
       at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:952)
       at android.os.Handler.handleCallback(Handler.java:790)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loop(Looper.java:172)
       at android.app.ActivityThread.main(ActivityThread.java:6590)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

Screen unresponsive to touch when using tab navigator

Sorry, but my project is quite complicated so I can't isolate a test case.

I noticed that when upgrading from alpha.16 to alpha.19, the screen becomes unresponsive to touch when tabbing between views using the tab navigator on iOS. After toggling through several tabs the screen once again becomes responsive. Each of my tab navigators has nested stack navigators (not sure if that's relevant)

Hope this helps uncover an issue.

getting an error when compiling with react native 0.59.0

FAILURE: Build failed with an exception.
* What went wrong:
A problem occurred configuring project ':app'.
> Failed to notify project evaluation listener.
   > Could not resolve all dependencies for configuration ':app:debugCompileClasspath'.
      > More than one variant of project :react-native-screens matches the consumer attributes:
          - Configuration ':react-native-screens:debugApiElements' variant android-aidl:
              - Found artifactType 'android-aidl' but wasn't required.
              - Required com.android.build.api.attributes.BuildTypeAttr 'debug' and found compatible value 'debug'.
              - Found com.android.build.api.attributes.VariantAttr 'debug' but wasn't required.
              - Required com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Aar' and found compatible value 'Aar'.
              - Required org.gradle.usage 'java-api' and found compatible value 'java-api'.
          - Configuration ':react-native-screens:debugApiElements' variant android-classes:
              - Found artifactType 'android-classes' but wasn't required.
              - Required com.android.build.api.attributes.BuildTypeAttr 'debug' and found compatible value 'debug'.
              - Found com.android.build.api.attributes.VariantAttr 'debug' but wasn't required.
              - Required com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Aar' and found compatible value 'Aar'.
              - Required org.gradle.usage 'java-api' and found compatible value 'java-api'.
          - Configuration ':react-native-screens:debugApiElements' variant android-manifest:
              - Found artifactType 'android-manifest' but wasn't required.
              - Required com.android.build.api.attributes.BuildTypeAttr 'debug' and found compatible value 'debug'.
              - Found com.android.build.api.attributes.VariantAttr 'debug' but wasn't required.
              - Required com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Aar' and found compatible value 'Aar'.
              - Required org.gradle.usage 'java-api' and found compatible value 'java-api'.
          - Configuration ':react-native-screens:debugApiElements' variant android-renderscript:
              - Found artifactType 'android-renderscript' but wasn't required.
              - Required com.android.build.api.attributes.BuildTypeAttr 'debug' and found compatible value 'debug'.
              - Found com.android.build.api.attributes.VariantAttr 'debug' but wasn't required.
              - Required com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Aar' and found compatible value 'Aar'.
              - Required org.gradle.usage 'java-api' and found compatible value 'java-api'.
          - Configuration ':react-native-screens:debugApiElements' variant jar:
              - Found artifactType 'jar' but wasn't required.
              - Required com.android.build.api.attributes.BuildTypeAttr 'debug' and found compatible value 'debug'.
              - Found com.android.build.api.attributes.VariantAttr 'debug' but wasn't required.
              - Required com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Aar' and found compatible value 'Aar'.
              - Required org.gradle.usage 'java-api' and found compatible value 'java-api'.
   > Could not get unknown property 'mergeResourcesProvider' for object of type com.android.build.gradle.internal.api.ApplicationVariantImpl.
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 5s

Memory leak in iOS

bug

Used by in iOS will cause memory leak.

image

image

env

react-native: 0.59.4
react: 16.8.3
react-navigation: 3.5.1
react-native-screens: 1.0.0-alpha.22

demo

import React from "react";
import { View, Text } from "react-native";
import { createStackNavigator, createAppContainer } from "react-navigation";
import { useScreens } from 'react-native-screens';
useScreens();

class HomeScreen extends React.Component {
  render() {
    return (
      <View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
        <Text>Home Screen</Text>
      </View>
    );
  }
}

const AppNavigator = createStackNavigator({
  Home: {
    screen: HomeScreen
  }
});

const AppContainer = createAppContainer(AppNavigator)

AppRegistry.registerComponent('AwesomeProject', () => AppContainer)

Crash on iOS in dev mode

Not sure exactly when it happens but once in a while when developing the app will crash with

NSArrayM insertObject:atIndex:]: object cannot be nil'
*** First throw call stack:
(
	0   CoreFoundation                      0x0000000111da629b __exceptionPreprocess + 331
	1   libobjc.A.dylib                     0x0000000110547735 objc_exception_throw + 48
	2   CoreFoundation                      0x0000000111cf08fc _CFThrowFormattedException + 194
	3   CoreFoundation                      0x0000000111cccb85 -[__NSArrayM insertObject:atIndex:] + 1269
	4   UIKitCore                           0x0000000120f92057 -[UIViewController _addChildViewController:performHierarchyCheck:notifyWillMove:] + 577
	5   UIKitCore                           0x0000000120fb3efc -[UIViewController(UIContainerViewControllerProtectedMethods) addChildViewController:] + 71
	6   th3rdwave                           0x000000010c3b5861 -[RNSScreenContainerView attachScreen:] + 113
	7   th3rdwave                           0x000000010c3b5f8c -[RNSScreenContainerView updateContainer] + 1516
	8   th3rdwave                           0x000000010c3b6bee __57-[RNSScreenContainerManager uiManagerDidPerformMounting:]_block_invoke + 350
	9   th3rdwave                           0x000000010bf0980d __RCTExecuteOnMainQueue_block_invoke + 29
	10  libdispatch.dylib                   0x00000001151905d1 _dispatch_call_block_and_release + 12
	11  libdispatch.dylib                   0x000000011519163e _dispatch_client_callout + 8
	12  libdispatch.dylib                   0x000000011519e9d6 _dispatch_main_queue_callback_4CF + 1541
	13  CoreFoundation                      0x0000000111d097f9 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
	14  CoreFoundation                      0x0000000111d03e86 __CFRunLoopRun + 2342
	15  CoreFoundation                      0x0000000111d03221 CFRunLoopRunSpecific + 625
	16  GraphicsServices                    0x000000011879b1dd GSEventRunModal + 62
	17  UIKitCore                           0x000000012085f115 UIApplicationMain + 140
	18  th3rdwave                           0x000000010bb63890 main + 112
	19  libdyld.dylib                       0x0000000115207551 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

My guess is that it has to do with cleanup when the native module gets invalidated.

Call willMoveToWindow before navigating with react-navaigation

(discussion happened offline with @kmagiera)
ccing @brentvatne as it will probably require changes in react-navigation.

On my project, we had a bug with react-native <InputAccesoryView />:

dec-06-2018 15-50-29

After investigating with @chdeps, we decided to patch rn and using the nice hooks that react-native-screens give us:

/**
 * Copyright (c) 2015-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#import "RCTInputAccessoryView.h"

#import <React/RCTBridge.h>
#import <React/RCTTouchHandler.h>
#import <React/UIView+React.h>

#import "RCTInputAccessoryViewContent.h"

@interface RCTInputAccessoryView()

// Overriding `inputAccessoryView` to `readwrite`.
@property (nonatomic, readwrite, retain) UIView *inputAccessoryView;

@end

@implementation RCTInputAccessoryView
{
  BOOL _shouldBecomeFirstResponder;
}

  - (instancetype)initWithBridge:(RCTBridge *)bridge
  {
    if (self = [super init]) {
      _inputAccessoryView = [RCTInputAccessoryViewContent new];
      RCTTouchHandler *const touchHandler = [[RCTTouchHandler alloc] initWithBridge:bridge];
      [touchHandler attachToView:_inputAccessoryView];
    }
    return self;
  }

  - (BOOL)canBecomeFirstResponder
  {
    return true;
  }

  - (void)reactSetFrame:(CGRect)frame
  {
    [_inputAccessoryView reactSetFrame:frame];

    if (_shouldBecomeFirstResponder) {
      _shouldBecomeFirstResponder = NO;
      [self becomeFirstResponder];
    }
  }

+  - (void)didMoveToWindow {
+    [super didMoveToWindow];
+    BOOL isVisible = self.superview && self.window;
+    
+    if (isVisible) {
+      [self becomeFirstResponder];
+    } else {
+      [self resignFirstResponder];
+    }
+  }

  - (void)insertReactSubview:(UIView *)subview atIndex:(NSInteger)index
  {
    [super insertReactSubview:subview atIndex:index];
    [_inputAccessoryView insertReactSubview:subview atIndex:index];
  }

  - (void)removeReactSubview:(UIView *)subview
  {
    [super removeReactSubview:subview];
    [_inputAccessoryView removeReactSubview:subview];
  }

  - (void)didUpdateReactSubviews
  {
    // Do nothing, as subviews are managed by `insertReactSubview:atIndex:`.
  }

  - (void)didSetProps:(NSArray<NSString *> *)changedProps
  {
    // If the accessory view is not linked to a text input via nativeID, assume it is
    // a standalone component that should get focus whenever it is rendered.
    if (![changedProps containsObject:@"nativeID"] && !self.nativeID) {
      _shouldBecomeFirstResponder = YES;
    }
  }

@end

That worked well:

dec-06-2018 15-30-50

But the actually the stays too long. We tryed to do:

#import "RCTInputAccessoryView.h"

#import <React/RCTBridge.h>
#import <React/RCTTouchHandler.h>
#import <React/UIView+React.h>

#import "RCTInputAccessoryViewContent.h"

@interface RCTInputAccessoryView()

// Overriding `inputAccessoryView` to `readwrite`.
@property (nonatomic, readwrite, retain) UIView *inputAccessoryView;

@end

@implementation RCTInputAccessoryView
{
  BOOL _shouldBecomeFirstResponder;
}

/// .....

+  - (void)didMoveToWindow {
+    [super didMoveToWindow];
+    BOOL isVisible = self.superview && self.window;
+    
+    if (isVisible) {
+      [self becomeFirstResponder];
+    } else {
+      [self resignFirstResponder];
+    }
+  }

+  - (void)willMoveToWindow:newWindow {
+    [super didMoveToWindow:newWindow];
+    [self resignFirstResponder];
+  }

/// .....

@end

But still the problem.

IOS dev are calling willMoveToWindow before navigation and didMoveToWindow after/
React navigation isn't thus it make it hard to use the willMoveToWindow usefully.

Android Build

Hello,

I am trying to build my project but I keep on getting:

:react-native-screens:compileDebugJavaWithJavac
/mypathnode_modules/react-native-screens/android/src/main/java/com/swmansion/rnscreens/ScreenContainerViewManager.java:5: error: package com.facebook.react.module.annotations does not exist
import com.facebook.react.module.annotations.ReactModule;
                                            ^
/mypathnode_modules/react-native-screens/android/src/main/java/com/swmansion/rnscreens/ScreenContainer.java:13: error: cannot find symbol
import com.facebook.react.modules.core.ChoreographerCompat;
                                      ^
  symbol:   class ChoreographerCompat
  location: package com.facebook.react.modules.core
/mypathnode_modules/react-native-screens/android/src/main/java/com/swmansion/rnscreens/ScreenContainer.java:14: error: cannot find symbol
import com.facebook.react.modules.core.ReactChoreographer;
                                      ^
  symbol:   class ReactChoreographer
  location: package com.facebook.react.modules.core
/mypathnode_modules/react-native-screens/android/src/main/java/com/swmansion/rnscreens/ScreenContainerViewManager.java:9: error: cannot find symbol
@ReactModule(name = ScreenContainerViewManager.REACT_CLASS)
 ^
  symbol: class ReactModule
/mypathnode_modules/react-native-screens/android/src/main/java/com/swmansion/rnscreens/ScreenContainer.java:31: error: package ChoreographerCompat does not exist
  private ChoreographerCompat.FrameCallback mFrameCallback = new ChoreographerCompat.FrameCallback() {
                             ^
/mypathnode_modules/react-native-screens/android/src/main/java/com/swmansion/rnscreens/LifecycleHelper.java:10: error: cannot find symbol
import com.facebook.react.modules.core.ChoreographerCompat;
                                      ^
  symbol:   class ChoreographerCompat
  location: package com.facebook.react.modules.core
/mypathnode_modules/react-native-screens/android/src/main/java/com/swmansion/rnscreens/LifecycleHelper.java:11: error: cannot find symbol
import com.facebook.react.modules.core.ReactChoreographer;
                                      ^
  symbol:   class ReactChoreographer
  location: package com.facebook.react.modules.core
/mypathnode_modules/react-native-screens/android/src/main/java/com/swmansion/rnscreens/ScreenViewManager.java:3: error: package com.facebook.react.module.annotations does not exist
import com.facebook.react.module.annotations.ReactModule;
                                            ^
/mypathnode_modules/react-native-screens/android/src/main/java/com/swmansion/rnscreens/ScreenViewManager.java:8: error: cannot find symbol
@ReactModule(name = ScreenViewManager.REACT_CLASS)
 ^
  symbol: class ReactModule
/mypathnode_modules/react-native-screens/android/src/main/java/com/swmansion/rnscreens/ScreenContainer.java:31: error: package ChoreographerCompat does not exist
  private ChoreographerCompat.FrameCallback mFrameCallback = new ChoreographerCompat.FrameCallback() {
                                                                                    ^
/mypathnode_modules/react-native-screens/android/src/main/java/com/swmansion/rnscreens/ScreenContainer.java:40: error: getCurrentActivity() is not public in ReactContext; cannot be accessed from outside package
    Activity activity = ((ReactContext) context).getCurrentActivity();
                                                ^
/mypathnode_modules/react-native-screens/android/src/main/java/com/swmansion/rnscreens/ScreenContainer.java:60: error: package ReactChoreographer does not exist
              ReactChoreographer.CallbackType.NATIVE_ANIMATED_MODULE,
                                ^
/mypathnode_modules/react-native-screens/android/src/main/java/com/swmansion/rnscreens/ScreenContainer.java:59: error: cannot find symbol
      ReactChoreographer.getInstance().postFrameCallback(
      ^
  symbol:   variable ReactChoreographer
  location: class ScreenContainer
/mypathnode_modules/react-native-screens/android/src/main/java/com/swmansion/rnscreens/RNScreensPackage.java:12: error: RNScreensPackage is not abstract and does not override abstract method createJSModules() in ReactPackage
public class RNScreensPackage implements ReactPackage {
       ^

My gradle is:

buildscript {
    ext {
        buildToolsVersion = "27.0.3"
        minSdkVersion = 16
        compileSdkVersion = 27
        targetSdkVersion = 26
        supportLibVersion = "27.1.1"
    }
    repositories {
        jcenter()
        google()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.3'
        classpath 'com.google.gms:google-services:4.0.1'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        mavenLocal()
        google()
        jcenter()
        maven {
            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
            url "$rootDir/../node_modules/react-native/android"
            url "https://maven.google.com"
        }
        google()
    }
}


task wrapper(type: Wrapper) {
    gradleVersion = '4.4'
    distributionUrl = distributionUrl.replace("bin", "all")
}

apply plugin: 'com.google.gms.google-services'

and app gradle

apply plugin: "com.android.application"

import com.android.build.OutputFile

/**
 * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
 * and bundleReleaseJsAndAssets).
 * These basically call `react-native bundle` with the correct arguments during the Android build
 * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the
 * bundle directly from the development server. Below you can see all the possible configurations
 * and their defaults. If you decide to add a configuration block, make sure to add it before the
 * `apply from: "../../node_modules/react-native/react.gradle"` line.
 *
 * project.ext.react = [
 *   // the name of the generated asset file containing your JS bundle
 *   bundleAssetName: "index.android.bundle",
 *
 *   // the entry file for bundle generation
 *   entryFile: "index.android.js",
 *
 *   // whether to bundle JS and assets in debug mode
 *   bundleInDebug: false,
 *
 *   // whether to bundle JS and assets in release mode
 *   bundleInRelease: true,
 *
 *   // whether to bundle JS and assets in another build variant (if configured).
 *   // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants
 *   // The configuration property can be in the following formats
 *   //         'bundleIn${productFlavor}${buildType}'
 *   //         'bundleIn${buildType}'
 *   // bundleInFreeDebug: true,
 *   // bundleInPaidRelease: true,
 *   // bundleInBeta: true,
 *
 *   // whether to disable dev mode in custom build variants (by default only disabled in release)
 *   // for example: to disable dev mode in the staging build type (if configured)
 *   devDisabledInStaging: true,
 *   // The configuration property can be in the following formats
 *   //         'devDisabledIn${productFlavor}${buildType}'
 *   //         'devDisabledIn${buildType}'
 *
 *   // the root of your project, i.e. where "package.json" lives
 *   root: "../../",
 *
 *   // where to put the JS bundle asset in debug mode
 *   jsBundleDirDebug: "$buildDir/intermediates/assets/debug",
 *
 *   // where to put the JS bundle asset in release mode
 *   jsBundleDirRelease: "$buildDir/intermediates/assets/release",
 *
 *   // where to put drawable resources / React Native assets, e.g. the ones you use via
 *   // require('./image.png')), in debug mode
 *   resourcesDirDebug: "$buildDir/intermediates/res/merged/debug",
 *
 *   // where to put drawable resources / React Native assets, e.g. the ones you use via
 *   // require('./image.png')), in release mode
 *   resourcesDirRelease: "$buildDir/intermediates/res/merged/release",
 *
 *   // by default the gradle tasks are skipped if none of the JS files or assets change; this means
 *   // that we don't look at files in android/ or ios/ to determine whether the tasks are up to
 *   // date; if you have any other folders that you want to ignore for performance reasons (gradle
 *   // indexes the entire tree), add them here. Alternatively, if you have JS files in android/
 *   // for example, you might want to remove it from here.
 *   inputExcludes: ["android/**", "ios/**"],
 *
 *   // override which node gets called and with what additional arguments
 *   nodeExecutableAndArgs: ["node"],
 *
 *   // supply additional arguments to the packager
 *   extraPackagerArgs: []
 * ]
 */

project.ext.react = [
        entryFile: "index.js"
]

apply from: "../../node_modules/react-native/react.gradle"

/**
 * Set this to true to create two separate APKs instead of one:
 *   - An APK that only works on ARM devices
 *   - An APK that only works on x86 devices
 * The advantage is the size of the APK is reduced by about 4MB.
 * Upload all the APKs to the Play Store and people will download
 * the correct one based on the CPU architecture of their device.
 */
def enableSeparateBuildPerCPUArchitecture = false

/**
 * Run Proguard to shrink the Java bytecode in release builds.
 */
def enableProguardInReleaseBuilds = false

android {
    compileSdkVersion rootProject.ext.compileSdkVersion
    buildToolsVersion rootProject.ext.buildToolsVersion

    defaultConfig {
        applicationId "com.helloworld"
        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        versionCode 1
        versionName "1.0"
        ndk {
            abiFilters "armeabi-v7a", "x86"
        }
    }
    splits {
        abi {
            reset()
            enable enableSeparateBuildPerCPUArchitecture
            universalApk false  // If true, also generate a universal APK
            include "armeabi-v7a", "x86"
        }
    }
    buildTypes {
        release {
            minifyEnabled enableProguardInReleaseBuilds
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
        }
    }
    // applicationVariants are e.g. debug, release
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            // For each separate APK per architecture, set a unique version code as described here:
            // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits
            def versionCodes = ["armeabi-v7a":1, "x86":2]
            def abi = output.getFilter(OutputFile.ABI)
            if (abi != null) {  // null for the universal-debug, universal-release variants
                output.versionCodeOverride =
                        versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
            }
        }
    }
}

dependencies {
    compile project(':rn-fetch-blob')
    compile project(':react-native-vector-icons')
    compile project(':react-native-svg')
    compile project(':react-native-screens')
    compile project(':react-native-prompt-android')
    compile project(':react-native-picker')
    compile project(':react-native-pdf')
    compile project(':react-native-linear-gradient')
    compile project(':react-native-firebase')
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation "com.android.support:appcompat-v7:27.+"
    implementation "com.facebook.react:react-native:+"  // From node_modules
    implementation 'com.android.support:support-annotations:28.0.0'
}

// Run this once to be able to run the application with BUCK
// puts all compile dependencies into folder libs for BUCK to use
task copyDownloadableDepsToLibs(type: Copy) {
    from configurations.compile
    into 'libs'
}

Does it have anything to do with my classpath 'com.android.tools.build:gradle:3.1.3'?

Breaks react-native-modal

Using screens causes react-native-modal <Modal /> to not appear when isVisible={true} is set on initial render.

Touch events work in the last active Screen only

I'm trying to experiment with the lib. The idea was to implement some kind of virtualized list detaching off-screen items. I noticed that touch components don't work inside Screen views but the last one. Is this intentional? Can I change this somehow?

It's probably not a good idea to attach/detach views on scroll anyway. Though, I see a few use cases where at least two screens could be active at the same time and would need to handle touch events.

Thank you for your amazing work ❤️

Crash when closing the app while the rn activity is not on top

When an app opens a new activity and then is backgrounded it crashes because getCurrentActivity returns another activity.

In my case it happens when using facebook sign in and then backgrounding the app.

EDIT: Can't seem to repro consistently but I think my theory about getCurrentActivity is still valid.

IllegalStateException
In order to use RNScreen components your app's activity need to extend ReactFragmentActivity or ReactCompatActivity
com.swmansion.rnscreens.ScreenContainer in <init> at line 44
com.swmansion.rnscreens.ScreenContainerViewManager in createViewInstance at line 21
com.swmansion.rnscreens.ScreenContainerViewManager in createViewInstance at line 9
com.facebook.react.uimanager.ViewManager in createView at line 44
com.facebook.react.uimanager.NativeViewHierarchyManager in createView at line 260
com.facebook.react.uimanager.UIViewOperationQueue$CreateViewOperation in execute at line 200
com.facebook.react.uimanager.UIViewOperationQueue$1 in run at line 908
com.facebook.react.uimanager.UIViewOperationQueue in flushPendingBatches at line 1021
com.facebook.react.uimanager.UIViewOperationQueue in access$2500 at line 46
com.facebook.react.uimanager.UIViewOperationQueue$2 in runGuarded at line 979
com.facebook.react.bridge.GuardedRunnable in run at line 24
android.os.Handler in handleCallback at line 739
android.os.Handler in dispatchMessage at line 95
android.os.Looper in loop at line 145
android.app.ActivityThread in main at line 5942
java.lang.reflect.Method in invoke
java.lang.reflect.Method in invoke at line 372
com.android.internal.os.ZygoteInit$MethodAndArgsCaller in run at line 1399
com.android.internal.os.ZygoteInit in main at line 1194

Screens are blank for a few frames when navigating to them

Not sure if this is expected behavior or it's something to do with my configuration, but here's a video slowed down to 25% speed

My navigator setup:

StackNavigator: {
    DrawerNavigator: {
        BottomTabNavigator: {
            StackNavigator: {
                Screen
            }
            StackNavigator: {
                Screen
            }
            ...SimilarStackNavigators
        }
    }
}

Happy to answer any other questions about my implementation. My app works significantly smoother now, very excited about this project.

No method `setReorderingAllowed` found

I'm using react-native 0.56 and have problems with Android.

I think I linked the library correctly and it compiles:

But then I get this runtime error when starting the app:

    java.lang.NoSuchMethodError: No virtual method setReorderingAllowed(Z)Landroid/support/v4/app/FragmentTransaction; in class Landroid/support/v4/app/FragmentTransaction; or its super classes (declaration of 'android.support.v4.app.FragmentTransaction' appears in /data/app/bestande.bestande-1/base.apk)
        at com.swmansion.rnscreens.ScreenContainer.getOrCreateTransaction(ScreenContainer.java:92)
        at com.swmansion.rnscreens.ScreenContainer.attachScreen(ScreenContainer.java:105)
        at com.swmansion.rnscreens.ScreenContainer.updateIfNeeded(ScreenContainer.java:168)
        at com.swmansion.rnscreens.ScreenContainer.onAttachedToWindow(ScreenContainer.java:129)
        at android.view.View.dispatchAttachedToWindow(View.java:15509)
        at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2916)
        at android.view.ViewGroup.addViewInner(ViewGroup.java:4456)
        at android.view.ViewGroup.addView(ViewGroup.java:4258)
        at android.view.ViewGroup.addView(ViewGroup.java:4198)
        at com.facebook.react.uimanager.ViewGroupManager.addView(ViewGroupManager.java:45)
        at com.facebook.react.uimanager.NativeViewHierarchyManager.manageChildren(NativeViewHierarchyManager.java:437)
        at com.facebook.react.uimanager.UIViewOperationQueue$ManageChildrenOperation.execute(UIViewOperationQueue.java:227)
        at com.facebook.react.uimanager.UIViewOperationQueue$1.run(UIViewOperationQueue.java:894)
        at com.facebook.react.uimanager.UIViewOperationQueue.flushPendingBatches(UIViewOperationQueue.java:1001)
        at com.facebook.react.uimanager.UIViewOperationQueue.access$2400(UIViewOperationQueue.java:46)
        at com.facebook.react.uimanager.UIViewOperationQueue$DispatchUIFrameCallback.doFrameGuarded(UIViewOperationQueue.java:1061)
        at com.facebook.react.uimanager.GuardedFrameCallback.doFrame(GuardedFrameCallback.java:29)
        at com.facebook.react.modules.core.ReactChoreographer$ReactChoreographerDispatcher.doFrame(ReactChoreographer.java:134)
        at com.facebook.react.modules.core.ChoreographerCompat$FrameCallback$1.doFrame(ChoreographerCompat.java:105)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:872)
        at android.view.Choreographer.doCallbacks(Choreographer.java:686)
        at android.view.Choreographer.doFrame(Choreographer.java:618)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:860)
        at android.os.Handler.handleCallback(Handler.java:751)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6119)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

Lottie animations do not show

Hi,

I have some Lottie animations.
They do play well inside Storybook, but once in my app, when I add useScreens(), the animations do not show.

I'm on Expo SDK 32 and react-navigation 2.x

Will report if this works when I migrate to newer versions

Question: Integration with TabNavigator?

So this library has been integrated with React Navigation StackNavigator. But it seems like it would make sense to integrate it with TabNavigator as well to detach non-visible tabs from the view hierarchy.

Is this feasible? Are there plans to do it? Would there be unforeseen side effects?

Thanks!

popToTop in nested StackNavigator of react-navigation BottomTabNavigator blocks main UI thread causing jank

Current Behaviour

UI thread is blocked after double tapping on a BottomTabNavigator icon (calling popToTop of the nested StackNavigator) when reseting the nested StackNavigator state.

iOS with screens

Reproducible project: https://github.com/bonesyblue/tab-stack-rn-screens

Expected Behaviour

popToTop of nested stack navigator (within a BottomTabNavigator) should not block the UI thread or cause visible UI lag / jank.

Environment

package version
react 16.6.3
react-native 0.58.6
react-navigation 3.3.2
react-native-screens 1.0.0-alpha.22

Any help or feedback on this issue would be greatly appreciated 👍

Expo / Android - Expo has Stopped in both dev / prod mode

Tested on:

  • Google Nexus 6P Expo 30 Android 8 API 26
  • Nokia 6 Expo 30 Android 8

React navigation ^2.18.0

Steps to reproduce

App.js (top / right below imports)

import { useScreens } from 'react-native-screens';
useScreens();

If I comment these out, the app works as intended.

Thanks!

iOS Modal close

I'm just opening within stack navigator (react-navigation) Modal from 'react-native' and it is not calling onRequestClose on swipe from left to right gesture, but it visually closes Modal. Without rn-screens it works.

Doesn't work in combination with react-native-navigation

Screens render content selectively when used with react-native-navigation (I'm trying to use it to create a custom tab bar). Some Views render but others don't. I couldn't discover the root cause. It could be related to a shadow applied to Views.

Note: usage of ReactFragmentActivity was supposed to be removed in RN 0.57

Does not play well with Expo Camera

I'm using the Camera module from Expo SDK31 with react-navigation v3.x

I have a navigation screen that opens on top of the camera view screen (stacknav). When going back to the camera screen, the camera view does not work anymore and is black.

Not sure what is happening exactly, but it looks like the camera view does not reinitialize properly when the screen gets focused again. I don't know if this is an Expo problem or this lib.

These workaround works:

  • Remove useScreens() call
  • Unmount the camera view when the screen is unfocused and remount on focus (using withNavigationFocus

Transparent modals

Trying to create modals that have trasparent background with react-native-screens and react-navigation and all I get is white background

}, {
	mode: 'modal',
	headerMode: 'none',
	cardStyle: {
		backgroundColor: 'transparent',
		opacity: 1,
	},
	transitionConfig: () => ({
		containerStyle: {
			backgroundColor: 'transparent',
		},
	}),
})

Unable to paste into TextInput

I just got this library set up and running, but when testing I find I'm unable to paste into TextInputs on Android. Not calling useScreens in my initialization fixes this issue.

Keyboard is not attached to native navigation container

I am not sure if this is intended behavior, but I expected the keyboard to be attached to the native navigation container like this:

Expected (gif showing react-native-navigation with slow animations enabled)
Image from Gyazo

Actual (gif showingreact-navigation with useScreens() with slow animations enabled)
Image from Gyazo

"expo": "^32.0.0",
"react": "16.5.0",
"react-native": "https://github.com/expo/react-native/archive/sdk-32.0.0.tar.gz",
"react-native-screens": "^1.0.0-alpha.22",
"react-navigation": "^3.0.9"

Source: https://github.com/Thorbenandresen/react-native-screens-test

useScreens() with react navigation freezes scrollView

In my basic Expo app I have a horizontal scrollview on my second tab screen, my tabs are all stackNavigators. Using a single component as tab view causes the same issue.
Issue occurs on iOS and Android.

-Opening my 2nd tab for the first time, scrollView works fine.
-Switch to first tab and back to 2nd tab freezes scrollView
-Switch to 3rd or 4th tab and back to 2nd, scrollView behaves normally

Solution:
Remove useScreens() in app.js

Using:
Expo SDK 32
React Native Screens 1.0.0-alpha.19
React Navigation 3.0.9

[Android] Crash: no view found for id 0x1f1 (unknown) for fragment ScreenFragment

Today, I attempted to update to the latest react-navigation, and I figured I would try to use react-native-screens to improve performance. Unfortunately, it crashes on Android immediately upon opening. I have followed all of the instalation instructions, and I can confirm that my code works fine if I a) do not call useScreens() and b) extend from ReactActivity instead in the code below.

The exception only shows up in adb logcat:

49:04.038 11335 11335 E AndroidRuntime: FATAL EXCEPTION: main
12-22 17:49:04.038 11335 11335 E AndroidRuntime: Process: com.zonderstudios.zonder, PID: 11335
12-22 17:49:04.038 11335 11335 E AndroidRuntime: java.lang.IllegalArgumentException: No view found for id 0x1f1 (unknown) for fragment ScreenFragment{c8216f5 #0 id=0x1f1}
12-22 17:49:04.038 11335 11335 E AndroidRuntime: 	at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1422)
12-22 17:49:04.038 11335 11335 E AndroidRuntime: 	at android.support.v4.app.FragmentManagerImpl.addAddedFragments(FragmentManager.java:2617)
12-22 17:49:04.038 11335 11335 E AndroidRuntime: 	at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2388)
12-22 17:49:04.038 11335 11335 E AndroidRuntime: 	at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2344)
12-22 17:49:04.038 11335 11335 E AndroidRuntime: 	at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2245)
12-22 17:49:04.038 11335 11335 E AndroidRuntime: 	at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:703)
12-22 17:49:04.038 11335 11335 E AndroidRuntime: 	at android.os.Handler.handleCallback(Handler.java:790)
12-22 17:49:04.038 11335 11335 E AndroidRuntime: 	at android.os.Handler.dispatchMessage(Handler.java:99)
12-22 17:49:04.038 11335 11335 E AndroidRuntime: 	at android.os.Looper.loop(Looper.java:164)
12-22 17:49:04.038 11335 11335 E AndroidRuntime: 	at android.app.ActivityThread.main(ActivityThread.java:6494)
12-22 17:49:04.038 11335 11335 E AndroidRuntime: 	at java.lang.reflect.Method.invoke(Native Method)
12-22 17:49:04.038 11335 11335 E AndroidRuntime: 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
12-22 17:49:04.038 11335 11335 E AndroidRuntime: 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
12-22 17:49:04.040  1634  1644 W ActivityManager:   Force finishing activity com.zonderstudios.zonder/.MainActivity
12-22 17:49:04.047  1634  1649 I ActivityManager: Showing crash dialog for package com.zonderstudios.zonder u0

Here is my MainActivity.java.

package com.zonderstudios.zonder;
import android.os.Bundle;
import com.facebook.react.ReactFragmentActivity;
import org.devio.rn.splashscreen.SplashScreen;
import android.content.Intent;
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.ReactRootView;
import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;

public class MainActivity extends ReactFragmentActivity {

    /**
     * Returns the name of the main component registered from JavaScript.
     * This is used to schedule rendering of the component.
     */
    @Override
    protected String getMainComponentName() {
        return "zonder";
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        MainApplication.getCallbackManager().onActivityResult(requestCode, resultCode, data);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        SplashScreen.show(this, false);
        setTheme(R.style.AppTheme);
        super.onCreate(savedInstanceState);
        // I also tried this, along with deleting the two lines for splash screen and set theme:
        // super.onCreate(null);
    }

    @Override
    protected void onPause() {
        SplashScreen.hide(this);
        super.onPause();
    }

    @Override
    protected ReactActivityDelegate createReactActivityDelegate() {
        return new ReactActivityDelegate(this, getMainComponentName()) {
            @Override
            protected ReactRootView createRootView() {
                    return new RNGestureHandlerEnabledRootView(MainActivity.this);
            }
        };
    }
}

Any thoughts on fixing this? My one thought might be that there is a conflict with something else. Not sure, though.

Tried to register two views with the same name RNSScreen

Getting the following issue when I add import { useScreens } from 'react-native-screens'; in my App.js

simulator screen shot - iphone se - 2018-09-20 at 15 25 00

simulator screen shot - iphone se - 2018-09-20 at 15 25 02

react-native info

Environment:
OS: macOS High Sierra 10.13.5
Node: 10.10.0
Yarn: 1.9.4
npm: 6.4.1
Watchman: 4.9.0
Xcode: Xcode 9.4.1 Build version 9F2000
Android Studio: Not Found

Packages: (wanted => installed)
react: 16.3.1 => 16.3.1
react-native: https://github.com/expo/react-native/archive/sdk-30.0.0.tar.gz => 0.55.4

Etc

"expo": "^30.0.0",
"react-native-screens": "^1.0.0-alpha.12",

Happens in both dev and production mode
Was not able to reproduce in a simple snack

Question: Could orientation locking be a part of this library?

One of the things I have been missing from react-navigation is the possibility to lock the orientation of the screen for an incoming view. Since this must be implemented on a UIViewController and not a UIView on iOS this was before impossible to accomplish. With react-native-screens introducing the use of UIViewController I see a possibility for this. Could this be a possible future feature for react-native-screens?

Any plans to host it on maven?

Hi, Thanks for the amazing work you guys did. This is not an issue but a request. We develop an SDK using react-native that allows other apps to display different feature without implementing them. I am trying to embed react-native-screens in my library by using following code:

In app/build.gradle

embedded "com.swmansion.reanimated:react-native-reanimated:1.0.0"
embedded "com.swmansion.rnscreens:react-native-screens:+"

In build.gradle

maven {
    // All of React Native (JS, Obj-C sources, Android bi`naries) is installed from npm
    url "$rootDir/../node_modules/react-native/android"
}
maven {
    url "$rootDir/../node_modules/react-native-screens/android/maven"
}
maven {
    url "$rootDir/../node_modules/react-native-reanimated/android/maven"
}

It compile perfectly! But when we add it to our sample app it shows error

Failed to resolve: com.swmansion.reanimated:react-native-reanimated:1.0.0
Failed to resolve: com.swmansion.rnscreens:react-native-screens:+

We have also used react-native-gesture-handler in same SDK and it works fine! Many thanks for that as well!

I saw a README.md inside android mentioning to use task ./gradlew installArchives we have made it part of our build script. I am not an expert android developer so any help will be appreciated.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.