callstack / react-native-pager-view

React Native wrapper for the Android ViewPager and iOS UIPageViewController.
MIT License
2.74k stars 420 forks source link

Wrong safe area in presence of absolute-positioned view #185

Open federicoparroni opened 4 years ago

federicoparroni commented 4 years ago

Bug report

Summary

As you can see from the screenshot, the safe area is computed wrongly when a view with position: absolute is placed near the view pager.

Environment info

react-native info output:

System:
    OS: macOS 10.15.4
    CPU: (4) x64 Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz
    Memory: 21.57 MB / 8.00 GB
    Shell: 5.7.1 - /bin/zsh
  Binaries:
    Node: 12.14.1 - ~/.nvm/versions/node/v12.14.1/bin/node
    Yarn: 1.22.4 - /usr/local/bin/yarn
    npm: 6.13.7 - ~/.nvm/versions/node/v12.14.1/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  Managers:
    CocoaPods: 1.8.4 - /usr/local/bin/pod
  SDKs:
    iOS SDK:
      Platforms: iOS 13.5, DriverKit 19.0, macOS 10.15, tvOS 13.4, watchOS 6.2
    Android SDK: Not Found
  IDEs:
    Android Studio: 4.0 AI-193.6911.18.40.6514223
    Xcode: 11.5/11E608c - /usr/bin/xcodebuild
  Languages:
    Java: 9.0.4 - /usr/bin/javac
    Python: 3.7.2 - /Users/federico/miniconda3/bin/python
  npmPackages:
    @react-native-community/cli: Not Found
    react: 16.9.0 => 16.9.0
    react-native: 0.62.2 => 0.62.2
  npmGlobalPackages:
    *react-native*: Not Found

Library version: "^4.0.0",

Steps to reproduce

const ViewPagerScreen = (props) => {

    const pages = [
      <View>
        <View style={{flex: 1, backgroundColor: 'green'}}>
          <SafeAreaView style={{flex: 1}}>
            <Text style={{fontSize: 24}}>Title text</Text>
          </SafeAreaView>
        </View>
      </View>
    ];

    return (
      <>
        <View style={{...StyleSheet.absoluteFillObject, backgroundColor: 'black'}} />

        <ViewPager initialPage={0} showPageIndicator={false}
          orientation="horizontal"
          style={{flex: 1}}
        >
          {pages}
        </ViewPager>

        // if you remove this problematic footer view, all works as expected
        <SafeAreaView>
          <View style={{position: "absolute", bottom: 0, left: 0, right: 0}}>
            <View style={styles.footer}>
              <View style={styles.footerSubContLeft}>
                <Button title="Home" color='black' onPress={() => {}} />
              </View>
              <View style={styles.footerSubContRight}>
                <Button title="Next" color='black' onPress={() => {}} />
              </View>
            </View>
          </View>
        </SafeAreaView>

      </>
    );
}

const styles = StyleSheet.create({
  footer: {
    flexDirection: "row",
    marginBottom: 20,
    backgroundColor: 'yellow'
  },
  footerSubContLeft: {
    flex: 1,
    alignItems: "flex-start",
  },
  footerSubContRight: {
    flex: 1,
    alignItems: "flex-end",
  }
});
image

Describe what you expected to happen:

The text view should be inside the SafeArea. If I remove the yellow view (footer), this is respected.

image
troZee commented 4 years ago

Hey 👋 Thank you for reporting an issue. Can you try to remove childrenWithOverriddenStyle in your node_modules ?

federicoparroni commented 4 years ago

No, that happens also after having removed childrenWithOverriddenStyles :/

CrnogoracIvan commented 4 years ago

Is there any news regarding to this issue? :(

CrnogoracIvan commented 4 years ago

@keyblade95, you can bypass problem by removing absolute layout and setting negative margin on element which will be in front.

federicoparroni commented 4 years ago

I don’t know if I understood well.. should I remove the absolute layout from the SafeArea child view? Can you provide a minimal example, please?

troZee commented 4 years ago

Can you try style={{width: "100%", height:"100%"}} instead of flex:1 ? Additional, can you use SafeArea instead of Fragment ? ViewPager's parent here is fragment, so view inset can be wrong setup. Please add backgroundColor: "pink" and check the safe area for this view

federicoparroni commented 4 years ago

I cannot use SafeArea as the top parent because I want to achieve the following effect: the ViewPager pages have a background image and I want that to cover the entire screen. So, I set the pages to be fullscreen and the footer to be inside the safe area. Anyway, I will try style={{width: "100%", height:"100%"}} as soon as possible.

CrnogoracIvan commented 4 years ago

@keyblade95 , in your footer, remove absolute in style, and then add marginTop: -50 for example. That will do the job.

 <SafeAreaView>
          <View style={{marginTop: -50}}>
            <View style={styles.footer}>
              <View style={styles.footerSubContLeft}>
                <Button title="Home" color='black' onPress={() => {}} />
              </View>
              <View style={styles.footerSubContRight}>
                <Button title="Next" color='black' onPress={() => {}} />
              </View>
            </View>
          </View>
        </SafeAreaView>
ivantanakaa commented 3 years ago

Is there any news to this?

stesvis commented 2 years ago

I still have this issue on iOS in 2022. Was there any solution?