Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ScrollView] contentInset bug if content height on initial mount is larger than the viewport #1878

Closed
orktes opened this issue Jul 6, 2015 · 12 comments
Labels
Resolution: Locked This issue was locked by the bot.

Comments

@orktes
Copy link

orktes commented Jul 6, 2015

It seems that contentInset only works properly if the ScrollView is first mounted without content (or with less content than the viewport height). If content height overflows the scrollview viewport height the contentInset only takes effect after first scroll.

Example of the issue (using ListView)
https://rnplay.org/apps/SdfSNw

  • Two identical ListView
  • ListView on the left receives items on initial mount. (contentInset only works after scrolling)
  • ListView on the right receives items one frame after initial mount. (contentInset works like it should)
@orktes
Copy link
Author

orktes commented Jul 6, 2015

Most likely related #1641

@brentvatne
Copy link
Collaborator

thanks for the report @orktes, cc @tadeuzagallo @nicklockwood

@felixakiragreen
Copy link
Contributor

👍

@MikaelCarpenter
Copy link

@orktes have you found a way to make this work yet? I'm still seeing this issue for ScrollView

@ide
Copy link
Contributor

ide commented Sep 4, 2015

As a workaround I've just been scrolling to -topInset on mount.

@MikaelCarpenter
Copy link

To clarify ide's comment, if you have a contentInset of -10, then you can do

_insetWorkaround: function(scrollView) {
  if(scrollView) {
    return scrollView.scrollWithoutAnimationTo(10);
  }
},
render: function() {
  return(
    <ScrollView
      ref={@_insetWorkaround}
      contentInset={top: -10}>
  )
}

@ide
Copy link
Contributor

ide commented Sep 8, 2015

If you do it in the ref handler, define a separate autobound function so that the same function is passed into <ScrollView> after each render. Otherwise every time ScrollView is rendered, it will compare the old and new ref functions, see that they are not equal, and call the new function.

@mkonicek
Copy link
Contributor

Hi there! This issue is being closed because it has been inactive for a while.

But don't worry, it will live on with ProductPains! Check out its new home: https://productpains.com/post/react-native/scrollview-contentinset-bug-if-content-height-on-initial-mount-is-larger-than-the-viewport-

ProductPains helps the community prioritize the most important issues thanks to its voting feature.
It is easy to use - just login with GitHub.

Also, if this issue is a bug, please consider sending a PR with a fix. We rely on the community to provide
bugfixes as the core team is heavily focused working on performance.

@jfilter
Copy link

jfilter commented Jul 2, 2017

Here my workaround to scroll up on initial render for a FlatList.

  componentDidUpdate() {
    if (this.props.requests.length <= 20) {
      this.listRef.getNode().scrollToOffset({
        offset: -LIST_HEADER_HEIGHT,
        animated: false,
      });
    }
  }

[..]
<FlastList
  ref={ref => (this.listRef = ref)}
/>

@jesseditson
Copy link

This is a legitimate bug, and as far as I can tell is still unresolved. Why are legit bugs being moved to some feature request app? @mkonicek this should be re-opened as far as I can tell.

@mazing
Copy link

mazing commented Aug 30, 2017

How can this bug be more than 2 years old and still not resolved

@airato
Copy link

airato commented Jul 3, 2018

I have a SectionList with sticky headers, and I need to use contentInset since I have native top and bottom nav bars.
On iOS, when using contentInset prop with both top and bottom values, SectionList was rendering the header for top section lower than needed with the section items in the correct position, OR not applying top offset at all. So when I reload the app in a simulator with Cmd+R, randomly I get one or the other case...

I managed to find a solution with both working sticky headers and insets. This is RN v0.55.4

class MyScreen extends Component<AllProps> {
  listEl: SectionList<Item>;
  componentDidMount() {
    if (__IOS__) {
      (this.listEl as any).setNativeProps({
        style: {
          paddingTop: getOffsets(this.props).topOffset,
        },
      });
    }
  }

  render() {
    const sections: { title: string; data: Item[] }[] = whateverData;

    return (
      <SectionList
        style={{ flex: 1 }}
        automaticallyAdjustContentInsets={false}
        ref={view => (this.listEl = view as any)}
        contentContainerStyle={{
          paddingBottom: __IOS__ ? getOffsets(this.props).topOffset : 0,
        }}
        stickySectionHeadersEnabled
        contentInset={__IOS__? { bottom: getOffsets(this.props).bottomOffset } : undefined}
        sections={sections}
        keyExtractor={(item: Item) => item.data.id}
        renderSectionHeader={({ section: { title } }) => <MyHeader title={title} />}
        renderItem={({ item }) => <MyItem item={item} />}
        ItemSeparatorComponent={() => <Box borderBottom borderColor="transparent" />}
      />
    );
  }
}

@facebook facebook locked as resolved and limited conversation to collaborators Jul 22, 2018
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Jul 22, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests