ios React Native:在 ScrollView contentContainerStyle 上设置 flex:1 会导致组件重叠

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33674789/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 08:13:20  来源:igfitidea点击:

React Native: Setting flex:1 on a ScrollView contentContainerStyle causes overlapping of components

iosflexboxreact-native

提问by David Avikasis

Problem:

问题:

I have a ScrollView with 2 subviews and I want the first of them (lets call it ViewA) to have {flex: 1} so the other one (ViewB) will stick to the bottom of the screen - but only if their total height is smaller that the screen. Of course that if they are higher than the screen I want it to scroll as usual.

我有一个带有 2 个子视图的 ScrollView,我希望它们中的第一个(我们称之为 ViewA)具有 {flex: 1} 所以另一个(ViewB)会粘在屏幕的底部 - 但前提是它们的总高度是比屏幕小。当然,如果它们高于屏幕,我希望它像往常一样滚动。

Case 1 (GOOD): ViewA with long text, ViewB scrolls with it. https://rnplay.org/apps/slCivA

案例 1(好):ViewA 带有长文本,ViewB 随之滚动。https://rnplay.org/apps/slCivA

Case 2 (BAD): ViewA with short text, ViewB doesn't stick to the bottom. https://rnplay.org/apps/OmQakQ

情况 2(坏):ViewA 带有短文本,ViewB 不粘在底部。https://rnplay.org/apps/OmQakQ

Tried Solution:

尝试的解决方案:

So I set the ScrollView's style AND contentContainerStyle to be flex: 1. I Also set ViewA's style to flex:1. But when I do it, the ScrollView's contentContainer view is fixed to the screen height, thus not able to scroll if needed and even worse - ViewB overlaps ViewA.

因此,我将 ScrollView 的样式和 contentContainerStyle 设置为 flex: 1。我还将 ViewA 的样式设置为 flex:1。但是当我这样做时,ScrollView 的 contentContainer 视图固定到屏幕高度,因此无法在需要时滚动,甚至更糟 - ViewB 与 ViewA 重叠。

Case 3 (BAD): ViewB sticks to the bottom, but the whole thing doesn't scroll. https://rnplay.org/apps/wZgtWA

情况 3 (BAD):ViewB 粘在底部,但整个内容不滚动。https://rnplay.org/apps/wZgtWA

If it's a bug - how to fix/workaround it? If it's the expected behaviour - how can I achieve what I've described?

如果这是一个错误 - 如何修复/解决它?如果这是预期的行为 - 我怎样才能实现我所描述的?

Thanks.

谢谢。

采纳答案by David Avikasis

Ok, so i wasn't able to get it work by styling alone, but here's how I did it:

好的,所以我无法仅通过样式来使其工作,但我是这样做的:

  1. Measure the height of the footer after it rendered (using onLayout, and measure)
  2. on the measurecallback, I add the height (if needed) to a spacer view between ViewA and ViewB in order to place ViewB on the bottom.
  3. In order to avoid showing 'jumps' to the user, I hide (with opacity) ViewB until its position is fixed.
  1. 在渲染后测量页脚的高度(使用onLayout, 和measure
  2. measure回调中,我将高度(如果需要)添加到 ViewA 和 ViewB 之间的间隔视图中,以便将 ViewB 放在底部。
  3. 为了避免向用户显示“跳跃”,我隐藏(不透明)ViewB 直到其位置固定。

my CJSX code (stripped and simplified version):

我的 CJSX 代码(精简版和简化版):

Dimensions = require('Dimensions')
windowSize = Dimensions.get('window')

MyClass = React.createClass
  mixins: [TimerMixin]

  render: ->
    <ScrollView style={styles.container} automaticallyAdjustContentInsets={false}>
      <View style={styles.mainContainer}>
        ... THIS IS VIEW A ...      
      </View>
      {
        if [email protected]
          <View>
            <ActivityIndicatorIOS/>
          </View>
      }
      <View style={[styles.spacer, {height: @state.spacerSize || 0}]}></View>
      <View onLayout={@measureFooterPosition} style={[styles.extras, {opacity: if @state.footerWasFixed then 1 else 0 }]} ref='extras'>
        ... THIS IS VIEW B ...       
      </View>
    </ScrollView>


  measureFooterPosition: ->
    @refs.extras.measure(@fixFooterPosition)

  fixFooterPosition: (ox, oy, width, height) ->
    footerPosition = Math.round(oy + height)
    diff = windowSize.height - footerPosition
    if diff > 0
      @setState(spacerSize: diff)
    if [email protected]
      @setTimeout (=>
        @setState(footerWasFixed: true)
      ), 30

styles = StyleSheet.create(
  container:
    backgroundColor: 'grey'
    flex: 1
  spacer:
    backgroundColor: 'white'
  mainContainer:
    flex: 1
    backgroundColor: 'white'
  extras:
    backgroundColor: 'white')

It's very simplified code, (my view has requirements much more specific then this..) but I hope it helps anyone.

这是非常简化的代码,(我的观点有比这更具体的要求......)但我希望它可以帮助任何人。

回答by Collin Tharp

Try feeding {flexGrow: 1}to the contentContainerStyleprop instead

试着喂{flexGrow: 1}contentContainerStyle道具代替

回答by Nader Dabit

Ok, I've made a sample here, and I think I've resolved the problem. The main thing I did was to make a main container view with two inner views, then set the inner views to flex at 80% and 20% (you can adjust to make it look the way you want).

好的,我在这里做了一个样本,我想我已经解决了这个问题。我所做的主要事情是制作一个带有两个内部视图的主容器视图,然后将内部视图设置为 80% 和 20%(您可以调整以使其看起来像您想要的那样)。

https://rnplay.org/apps/O4UxFA

https://rnplay.org/apps/O4UxFA