react-navigation标头中有淡淡的行

时间:2018-07-05 00:13:09

标签: react-native

这变成了一次巨大的冒险,随后又变成了一个非常大而混乱的帖子,因此,为了使您不必阅读下面我键盘发far的混乱情况,以下是摘要:

主要目标:找到一种方法在我的应用中选择性地显示导航栏,而不必另外选择性地移除安全区域填充以防止我的内容被iPhone X槽口夹住。

为什么要按照我的方式做:我想尝试使用导航栏的内置安全区域填充而不是react-native的<SafeAreaView>,因为{{1} }会干扰内置的填充并导致标头不必要地过高。

不按标准方式进行操作的副作用:标头(在图片中显示为<SafeAreaView>)和标头之间存在一条细线,当标头和内容同时出现时,该内容清晰可见都是相同的颜色

thin line on iPhone X simulator

我尝试过的事情

  • 使用height: 0
  • 不使用<SafeAreaView>而是尝试使用<SafeAreaView>(又称“推荐的方式”)
  • 使用标题选项播放以使标题消失而不会导致剪切的内容。作为副作用(引自下面的扩展帖子)

      

    我还发现header: null在功能上与   我后来发现的header: null也是   在功能上与headerTransparent: 'true'相同。似乎都是   制作整个标题,安全区域填充以及所有内容的有效方法,   消失。

  • display: 'none'borderColor以确定它是否是边界(事后我应该更彻底地做到这一点)

  • 玩“不透明”
  • 使用borderWidth来移动标题和内容
  • 在Xcode中重新创建问题以查看是否为iOS问题(后见之明:我做错了此事)

这很清楚地将答案引向了答案,因此我将其截断并继续回答。


冗长而令人困惑的原始版本

我在我的react-native项目(使用CRNA创建)中使用react-navigation,我想我已经找到了一种样式position: 'relative', top: 6的标题的方法,以便iOS可以为您,并消除了使用StackNavigator的需要(它干扰了其他屏幕的标题)。

我的应用程序的排列方式使得第一个屏幕有点像带有一个按钮网格的主屏幕,这些按钮最终将在<SafeAreaView>中拥有各自的页面。在此主屏幕上,我想禁用标题栏,因为没有导航到的内容,它只是将内容向下移动,但是,在其他屏幕上,我希望显示标题栏以显示后退按钮。使用StackNavigator时,我只能得到上面提到的两个之一,或者主屏幕被iPhone X上的缺口剪断,或者<SafeAreaView>向下移动了其他屏幕上的导航/标题栏并占用空间。

但是,我发现通过完全抛弃<SafeAreaView>,我能够使用react-navigation中的标题样式重新创建我想要的内容:

App.js

<SafeAreaView>

HomeScreen.js

const Navigation = createStackNavigator({
    Home: HomeScreen,
    Test: PageScreen,
},
{
  headerMode: 'screen',
  navigationOptions: {
    headerStyle: { backgroundColor: colors.background},
    headerTintColor: colors.headerTint,
    headerTitleStyle: {
      fontWeight: 'bold',
    },
  }
});

这很好用,因为它可以有效地从主屏幕中删除标题,但仍保留标题创建的安全区域填充。但是,现在有一条细线将标题与主屏幕内容分开,我不确定如何使它消失。这是唯一让我头疼的事,并有损于用户体验的东西。

这是我在说的: thin line on iPhone X simulator

这不会影响我希望标题可见的其他屏幕:显然,实际上,颜色只是掩盖了它...

Other screens unaffected

nevermind they actually are

在使用expo测试应用程序时,此行也出现在我的iPhone 8上,尽管由于该设备上状态栏较小,所以它并没有那么远。

我已经尝试过更改 static navigationOptions = { headerStyle: { height: 0, backgroundColor: colors.background //had to re-color it here too because otherwise the header would be white??? }, }; 中的headerTintColor,因为我认为在我设置的背景颜色后面可能有某种背景颜色,但显然可以控制文本和后退按钮的颜色。互联网似乎也没有太多的相关信息,我可以立即告诉navigationOptions,有关隐藏标题,无法隐藏标题以及如何自定义标题的结果。 有人知道这行是什么以及我如何删除它吗?还是失败了,如何使header line react-navigation<SafeAreaView>的导航标题配合使用?

编辑:我也已经尝试过StackNavigator解决方案,但是,通过删除应用首页上的标头,没有其他问题会导致{{1 }},其中header: null,的安全区域添加到iOS头文件已经内置的区域中,导致该头文件比其应有的要大得多,这就是为什么我选择使用<SafeAreaView>的原因,因为它使标头有效地不可见,但仍保持其安全区域。

编辑2 :在使用标题的<SafeAreaView>height: 0之后,我确定该行不是边框...

borderColor

Result of code above

编辑3 :更多发现。在使用CSS之后,我发现设置borderWidth会在导航栏后面显示一个白色层……也许比导航栏本身大一点?

另外,似乎headerStyle: { height: 400, backgroundColor: 'green', borderColor: 'red', borderWidth: 150, }, 在功能上与后来发现的opacity: 0相同,在功能上也与header: null相同。所有这些似乎都是使整个标头,安全区域填充等全部消失的有效方法。

使用headerTransparent: 'true'进行移动似乎也无法解决问题

编辑4 : 由于我已经确定该行实际上并非仅出现在将标题高度设置为0的屏幕上,而是出现在所有屏幕上,因此我认为这是iOS特有的内置功能,以区分页面内容的标题。

编辑4a 为了确认这一理论,我创建了一个纯本机的xcode项目,并尝试通过将导航栏和视图设置为黑色来重新创建此项目,这与我的预期相反,问题并没有重现。因此,这的确是由react-native而非iOS内置的东西,我再次得到纠正... How to remove navigation bar border/shadow?

screenshot

9 个答案:

答案 0 :(得分:5)

从问题开始处的摘要继续...

一旦我意识到我的Xcode测试存在缺陷,便开始在StackOverflow上针对iOS上的帖子(存在相同问题)进行谷歌搜索

由于这些都是iOS本机解决方案,所以我开始寻找以反应方式重新创建它们的方法。然后,这导致我寻找相同的iOS唯一问题,但是找到解决方案时却带有react关键字:

How do I hide the shadow under react-navigation headers?

虽然这个问题似乎是针对android的,但答案也提到了iOS:

  

elevation: 0, // remove shadow on Android shadowOpacity: 0, // remove shadow on iOS

来源:https://stackoverflow.com/a/42709731

我尝试过了。它没有用。

然后再往下an answer说:

  

headerStyle: { elevation: 0, shadowOpacity: 0, borderBottomWidth: 0, }

尝试过:可行。


TL; DR

如果要在现代版本的本机React中使用StackNavigator时隐藏标题,而不必使用<SafeAreaView>,请在createStackNavigator({...})或屏幕中使用以下代码班级的static navigationOptions = {...}

headerStyle: {
        backgroundColor: colors.background,
        borderBottomWidth: 0,
        height: 0,
    },

答案 1 :(得分:2)

使用{ elevation: 0 }作为headerStyle的屏幕选项。我确认这可以在React Navigation V5中使用。我认为这个(或类似的)也可以在React Navigation V4中使用。

<Stack.Navigator
  screenOptions={{
    headerStyle: { elevation: 0 }
  }}
  <Stack.Screen
    name="Home"
    component={HomeScreen} 
  />
</Stack.Navigator>

答案 2 :(得分:1)

headerStyle:{海拔高度0,}

工作正常

答案 3 :(得分:1)

我知道这是一个老问题,答案已被接受,但我想补充一点清晰度,因为它让我感到困惑。如果您嵌套了 Navigator,则需要确保将 screenOptions 放在正确的位置上,以便查看更改。

我的设置是:

        <NavigationContainer>
            <Stack.Navigator>
                {isLoading ? (
                    // We haven't finished checking for the token yet
                    <Stack.Screen name='Splash' component={SplashScreen} />
                ) : userToken == null ? (
                    // No token found, user isn't signed in
                    <Stack.Screen
                        name='SignIn'
                        component={SignInScreen}
                        options={{
                            // When logging out, a pop animation feels intuitive
                            animationTypeForReplace: isSignout ? 'pop' : 'push',
                            title: 'Sign in',
                            // headerStyle: {
                            //  backgroundColor: theme.secondaryBackground,
                            // },
                            headerShown: false,
                        }}
                    />
                ) : (
                    // User is signed in
                    <Stack.Screen name='Homie' component={AuthenticatedAppNavigator} />
                )}
            </Stack.Navigator>
        </NavigationContainer>

我试图在作为嵌套导航器的 AuthenticatedAppNavigator 组件上设置选项。一旦我将选项移动到父导航器,边框就会隐藏,如下所示:

        <NavigationContainer>
            <Stack.Navigator
                screenOptions={{
                    headerStyle: {
                        shadowOpacity: 0,
                        elevation: 0,
                    },
                }}
            >
                {isLoading ? (
                    // We haven't finished checking for the token yet
                    <Stack.Screen name='Splash' component={SplashScreen} />
                ) : userToken == null ? (
                    // No token found, user isn't signed in
                    <Stack.Screen
                        name='SignIn'
                        component={SignInScreen}
                        options={{
                            // When logging out, a pop animation feels intuitive
                            animationTypeForReplace: isSignout ? 'pop' : 'push',
                            title: 'Sign in',
                            // headerStyle: {
                            //  backgroundColor: theme.secondaryBackground,
                            // },
                            headerShown: false,
                        }}
                    />
                ) : (
                    // User is signed in
                    <Stack.Screen name='Homie' component={AuthenticatedAppNavigator} />
                )}
            </Stack.Navigator>
        </NavigationContainer>

此外,elevation 属性仅适用于 Android,因此 iOS 需要 shadowOpacity

答案 4 :(得分:0)

将解决此问题,并按照以下步骤操作,

  1. 从“ react-native”导入{SafeAreaView}
  2. render(){  返回(     ) }

  3. const样式= StyleSheet.create({ safeArea:{  弹性:1,  backgroundColor:“白色” })

答案 5 :(得分:0)

作为v5的更新,对我有用的是headerHideShadow: true

因此,在上下文中:

<LibraryStack.Navigator
  screenOptions={{
    headerHideShadow: true
  }}
>

更新: 这仅适用于native-stack(即'createNativeStackNavigator')。万一使用native-stack的人仍然落在这个问题上,就不要理会这个问题。

更多信息(native-stackstack的所有信息)https://github.com/react-navigation/react-navigation/issues/6899

答案 6 :(得分:0)

在导航v5中,在堆栈屏幕中添加选项对象:

 <Stack.Screen
      name="Whatever"
      component={SomeScreen}
      options={{
        title: "Whatever",
        headerTitleStyle: { fontSize: 22, color: "#fff" },
        headerStyle: { shadowColor: "transparent" } // This is the important bit
    }}
    // whatever else you need in the screen header
  />

答案 7 :(得分:-1)

我有点困惑...您要隐藏标题吗?

如果这样,只需将header设置为null。

HomeScreen.js

static navigationOptions = {
  header: null
};

答案 8 :(得分:-1)

海拔:0

<Stack.Navigator
      screenOptions={{
        headerStyle: {
          backgroundColor: '#F7F8FB',
          elevation: 0,
        },
        headerTintColor: 'white',
        headerBackTitle: 'Back',
        cardStyle: {
          backgroundColor: '#F7F8FB',
        },
      }}>

elevation:0 帮我搞定了