Compare commits

..

7 Commits

Author SHA1 Message Date
Krzysztof Magiera
1aeba7faa1 Bump version -> 2.0.0-beta.6 2020-02-17 17:09:13 +01:00
Krzysztof Magiera
e6ed4176cd Fix condition that detected whether we should update screen fram… (#336)
The previous condition was broken as under certain circumstances we would've receive a setReactFrame with no active screen rendered to only get the screen activate in a while. This resulted in the view dimention not being properly updated. This diff changes the condition and verifies whether a screen is mounted under UINavController or not. When not, we assume it is mounted under regular screen container and allow the frame to be adjusted from react.
2020-02-17 17:08:52 +01:00
Krzysztof Magiera
4f792b4281 Bump version -> 2.0.0-beta.5 2020-02-17 16:41:51 +01:00
Krzysztof Magiera
d35c523c37 Default to absolute fill for stack screen items. (#335)
This change makes navigation screen wrapper to set absolute fill style for screen items wrendered within native stack. We obvserved an issue where screens are rendered with a versy small height when the initial style is not set properly on iOS. This change makes the screen default to full screen and only then be resized down in case navigation bars are set.
2020-02-17 16:41:22 +01:00
Krzysztof Magiera
67806cbbb5 Fix several crashes in native stack related to fragment library (#331)
This change fixes two crashes related to fragment library. The first issue was a crash caused by return transaction started while the previous transaction was ongoing (e.g., quickly adding new screen on top of the stack and immediately dismissing it). The main fix was applied in the fragment library and therefore as a part of this change we update the dependency to fragment:1.2.1 which is the current latest stable version. As a result of the fragment library change we started observing other issue. The second issue was caused by the fact that under certain circumstances the view associated with a fragment couldn't been added despite it still being attached to a parent. This was resulting in a crash. This change adds a cleanup code that properly detaches the view: we do it in onCreateView but also when the fragment destroys its view (in onViewDestroy callback). The latter is necessary because when fragments are restored the order of onCreateView calls is reversed which causes inner views to attach despite their fragment managers not being initialized.
2020-02-15 01:12:59 +01:00
Krzysztof Magiera
6212847218 Bump version -> 2.0.0-beta.4 2020-02-14 17:03:20 +01:00
Krzysztof Magiera
a87faf443f Remove unnecessary logging. 2020-02-14 17:03:00 +01:00
8 changed files with 38 additions and 19 deletions

View File

@@ -49,8 +49,9 @@ repositories {
dependencies {
implementation 'com.facebook.react:react-native:+'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.coordinatorlayout:coordinatorlayout:1.0.0'
implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.fragment:fragment:1.2.1'
implementation 'androidx.coordinatorlayout:coordinatorlayout:1.1.0'
implementation 'com.google.android.material:material:1.1.0'
}
def configureReactNativePom(def pom) {

View File

@@ -220,13 +220,6 @@ public class ScreenContainer<T extends ScreenFragment> extends ViewGroup {
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
mIsAttached = false;
// fragment manager is destroyed so we can't do anything with it anymore
mFragmentManager = null;
// so we don't add the same screen twice after re-attach
removeAllViews();
// after re-attach we'll update the screen and add views again
markUpdated();
}
@Override

View File

@@ -5,6 +5,7 @@ import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
@@ -14,6 +15,17 @@ import com.facebook.react.uimanager.UIManagerModule;
public class ScreenFragment extends Fragment {
protected static View recycleView(View view) {
// screen fragments reuse view instances instead of creating new ones. In order to reuse a given
// view it needs to be detached from the view hierarchy to allow the fragment to attach it back.
ViewParent parent = view.getParent();
if (parent != null) {
((ViewGroup) parent).endViewTransition(view);
((ViewGroup) parent).removeView(view);
}
return view;
}
protected Screen mScreenView;
public ScreenFragment() {
@@ -30,7 +42,7 @@ public class ScreenFragment extends Fragment {
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
return mScreenView;
return recycleView(mScreenView);
}
public Screen getScreen() {
@@ -56,6 +68,12 @@ public class ScreenFragment extends Fragment {
dispatchOnAppear();
}
@Override
public void onDestroyView() {
super.onDestroyView();
recycleView(getView());
}
@Override
public void onDestroy() {
super.onDestroy();

View File

@@ -143,7 +143,7 @@ public class ScreenStackFragment extends ScreenFragment {
mScreenRootView = configureView();
}
return mScreenRootView;
return recycleView(mScreenRootView);
}
public boolean isDismissable() {

View File

@@ -132,6 +132,11 @@ public class ScreenStackHeaderConfig extends ViewGroup {
return;
}
AppCompatActivity activity = (AppCompatActivity) getScreenFragment().getActivity();
if (activity == null) {
return;
}
if (mIsHidden) {
if (mToolbar.getParent() != null) {
getScreenFragment().removeToolbar();
@@ -143,7 +148,6 @@ public class ScreenStackHeaderConfig extends ViewGroup {
getScreenFragment().setToolbar(mToolbar);
}
AppCompatActivity activity = (AppCompatActivity) getScreenFragment().getActivity();
activity.setSupportActionBar(mToolbar);
ActionBar actionBar = activity.getSupportActionBar();

View File

@@ -27,7 +27,6 @@ function renderComponentOrThunk(componentOrThunk, props) {
class StackView extends React.Component {
_removeScene = route => {
console.warn('REMOVE SCENE');
this.props.navigation.dispatch(StackActions.pop({ key: route.key }));
};
@@ -44,7 +43,6 @@ class StackView extends React.Component {
};
_onFinishTransitioning = () => {
console.warn('FINISH TRANSITIONING');
const { routes } = this.props.navigation.state;
let lastRoute = routes && routes.length && routes[routes.length - 1];
if (lastRoute) {
@@ -206,7 +204,7 @@ class StackView extends React.Component {
return (
<Screen
key={`screen_${route.key}`}
style={options.cardStyle}
style={[StyleSheet.absoluteFill, options.cardStyle]}
stackAnimation={stackAnimation}
stackPresentation={stackPresentation}
gestureEnabled={

View File

@@ -34,11 +34,16 @@
- (void)reactSetFrame:(CGRect)frame
{
if (_active) {
if (![self.reactViewController.parentViewController
isKindOfClass:[UINavigationController class]]) {
[super reactSetFrame:frame];
}
// ignore setFrame call from react, the frame of this view
// is controlled by the UIViewController it is contained in
// when screen is mounted under UINavigationController it's size is controller
// by the navigation controller itself. That is, it is set to fill space of
// the controller. In that case we ignore react layout system from managing
// the screen dimentions and we wait for the screen VC to update and then we
// pass the dimentions to ui view manager to take into account when laying out
// subviews
}
- (void)updateBounds

View File

@@ -1,6 +1,6 @@
{
"name": "react-native-screens",
"version": "2.0.0-beta.3",
"version": "2.0.0-beta.6",
"description": "First incomplete navigation solution for your react-native app.",
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start",