mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-24 04:16:00 +08:00
Fix a bug with ListView with sticky headers + RefreshControl
Summary:The bug is caused by a weird race condition. What happens is that when calling `UIRefreshControl#endRefreshing` the `UIScrollView` delegate `scrollViewDidScroll` function is called synchronously and then `dockClosestSectionHeader` crashes because the sticky header indexes are updated but not the contentView children. I fixed it by adding an updating property on `RCTRefreshControl` and setting it before calling `endRefreshing` so we can know not to call `dockClosestSectionHeader` at that moment. Tested with both `RefreshControl` and `onRefreshStart` prop. I reproduced the bug by replacing ListViewExample.js in UIExplorer with https://gist.github.com/janicduplessis/05fc58e852f3e80e51b9 Fixes #5440 cc nicklockwood Closes https://github.com/facebook/react-native/pull/5445 Differential Revision: D2953984 Pulled By: nicklockwood fb-gh-sync-id: c17a6a75ab31ef54d478706ed17a8115a11d734e shipit-source-id: c17a6a75ab31ef54d478706ed17a8115a11d734e
This commit is contained in:
committed by
facebook-github-bot-6
parent
183d6a088c
commit
671b975d92
@@ -30,7 +30,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[super layoutSubviews];
|
||||
|
||||
|
||||
// If the control is refreshing when mounted we need to call
|
||||
// beginRefreshing in layoutSubview or it doesn't work.
|
||||
if (_isInitialRender && _initialRefreshingState) {
|
||||
@@ -46,9 +46,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
|
||||
CGPoint offset = {scrollView.contentOffset.x, scrollView.contentOffset.y - self.frame.size.height};
|
||||
// Don't animate when the prop is set initialy.
|
||||
if (_isInitialRender) {
|
||||
// Must use `[scrollView setContentOffset:offset animated:NO]` instead of just setting
|
||||
// `scrollview.contentOffset` or it doesn't work, don't ask me why!
|
||||
[scrollView setContentOffset:offset animated:NO];
|
||||
scrollView.contentOffset = offset;
|
||||
[super beginRefreshing];
|
||||
} else {
|
||||
// `beginRefreshing` must be called after the animation is done. This is why it is impossible
|
||||
|
||||
Reference in New Issue
Block a user