Commit bdec94b5 authored by adamta's avatar adamta Committed by Chromium LUCI CQ

[iOS] Better handling of content suggestions height changes in NTP

Uses the content suggestions content height to adjust the feed inset and
offset correctly. This revealed that the content suggestions height was
not taking the safe area insets into consideration, so they are now
handled across the refactored NTP.

Also fixes occasional crash when changing between NTPs by ensuring that
the fake omnibox doesn't have multiple parent views/VCs at once.

Bug: 1114792
Change-Id: I458365dc5c494fcc3155cff53e9a368988d83538
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2635450
Commit-Queue: Adam Trudeau-Arcaro <adamta@google.com>
Reviewed-by: default avatarSergio Collazos <sczs@chromium.org>
Cr-Commit-Position: refs/heads/master@{#845411}
parent f405a5e6
...@@ -137,7 +137,9 @@ layoutAttributesForSupplementaryViewOfKind:(NSString*)kind ...@@ -137,7 +137,9 @@ layoutAttributesForSupplementaryViewOfKind:(NSString*)kind
attributes.zIndex = NSIntegerMax; attributes.zIndex = NSIntegerMax;
// Prevent the fake omnibox from scrolling up off of the screen. // Prevent the fake omnibox from scrolling up off of the screen.
CGFloat topSafeArea = self.collectionView.safeAreaInsets.top; CGFloat topSafeArea = IsRefactoredNTP() && [self isFeedVisible]
? self.parentCollectionView.safeAreaInsets.top
: self.collectionView.safeAreaInsets.top;
CGFloat minY = CGFloat minY =
headerHeight - ntp_header::kFakeOmniboxScrolledToTopMargin - headerHeight - ntp_header::kFakeOmniboxScrolledToTopMargin -
ToolbarExpandedHeight( ToolbarExpandedHeight(
......
...@@ -404,8 +404,11 @@ ...@@ -404,8 +404,11 @@
- (CGFloat)headerInsetForOverscrollActionsController: - (CGFloat)headerInsetForOverscrollActionsController:
(OverscrollActionsController*)controller { (OverscrollActionsController*)controller {
CGFloat topInset =
self.discoverFeedWrapperViewController.view.safeAreaInsets.top;
return self.contentSuggestionsCoordinator.viewController.collectionView return self.contentSuggestionsCoordinator.viewController.collectionView
.contentSize.height; .contentSize.height +
topInset;
} }
- (CGFloat)headerHeightForOverscrollActionsController: - (CGFloat)headerHeightForOverscrollActionsController:
......
...@@ -140,31 +140,25 @@ const CGFloat kOffsetToPinOmnibox = 100; ...@@ -140,31 +140,25 @@ const CGFloat kOffsetToPinOmnibox = 100;
- (void)viewDidLayoutSubviews { - (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews]; [super viewDidLayoutSubviews];
// Sets an inset to the Discover feed equal to the content suggestions height,
// so that the content suggestions could act as the feed header.
// TODO(crbug.com/1114792): Handle landscape/iPad layout.
UICollectionView* collectionView =
self.contentSuggestionsViewController.collectionView;
self.contentSuggestionsViewController.view.frame =
CGRectMake(0, -collectionView.contentSize.height,
self.view.frame.size.width, collectionView.contentSize.height);
self.discoverFeedWrapperViewController.feedCollectionView.contentInset =
UIEdgeInsetsMake(collectionView.contentSize.height, 0, 0, 0);
self.headerSynchronizer.additionalOffset = collectionView.contentSize.height;
// If scroll position was not set from the saved scroll position, and content // The scroll position should not be set if
// suggestions collection height has increased, then set the content offset to // |initialContentOffsetFromContentSuggestions| is NaN, because this means
// reach the top of the page. // that it was already set from the saved web state. The scroll position
// should only be adjutsed until the feed inset is correctly set, because this
// signifies that the view has appeared.
if (!isnan(self.initialContentOffsetFromContentSuggestions) && if (!isnan(self.initialContentOffsetFromContentSuggestions) &&
-collectionView.contentSize.height < self.discoverFeedWrapperViewController.feedCollectionView.contentInset
self.initialContentOffsetFromContentSuggestions) { .top != [self adjustedContentSuggestionsHeight]) {
[self setContentOffset:-collectionView.contentSize.height [self setContentOffset:-[self adjustedContentSuggestionsHeight]
fromSavedState:NO]; fromSavedState:NO];
} }
} }
- (void)viewWillAppear:(BOOL)animated { - (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated]; [super viewWillAppear:animated];
[self updateFeedInsetsForContentSuggestions];
self.headerSynchronizer.showing = YES; self.headerSynchronizer.showing = YES;
// Reload data to ensure the Most Visited tiles and fake omnibox are correctly // Reload data to ensure the Most Visited tiles and fake omnibox are correctly
// positioned, in particular during a rotation while a ViewController is // positioned, in particular during a rotation while a ViewController is
...@@ -188,7 +182,8 @@ const CGFloat kOffsetToPinOmnibox = 100; ...@@ -188,7 +182,8 @@ const CGFloat kOffsetToPinOmnibox = 100;
// Only get the bottom safe area inset. // Only get the bottom safe area inset.
UIEdgeInsets insets = UIEdgeInsetsZero; UIEdgeInsets insets = UIEdgeInsetsZero;
insets.bottom = self.view.safeAreaInsets.bottom; insets.bottom = self.view.safeAreaInsets.bottom;
self.collectionView.contentInset = insets; self.discoverFeedWrapperViewController.feedCollectionView.contentInset =
insets;
[self.headerSynchronizer [self.headerSynchronizer
updateFakeOmniboxOnNewWidth:self.collectionView.bounds.size.width]; updateFakeOmniboxOnNewWidth:self.collectionView.bounds.size.width];
...@@ -234,6 +229,12 @@ const CGFloat kOffsetToPinOmnibox = 100; ...@@ -234,6 +229,12 @@ const CGFloat kOffsetToPinOmnibox = 100;
#pragma mark - UIScrollViewDelegate #pragma mark - UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView*)scrollView { - (void)scrollViewDidScroll:(UIScrollView*)scrollView {
// Scroll events should not be handled until the content suggestions have been
// layed out.
if (!self.contentSuggestionsViewController.collectionView.contentSize
.height) {
return;
}
[self.overscrollActionsController scrollViewDidScroll:scrollView]; [self.overscrollActionsController scrollViewDidScroll:scrollView];
[self.headerSynchronizer updateFakeOmniboxOnCollectionScroll]; [self.headerSynchronizer updateFakeOmniboxOnCollectionScroll];
self.scrolledToTop = self.scrolledToTop =
...@@ -248,11 +249,9 @@ const CGFloat kOffsetToPinOmnibox = 100; ...@@ -248,11 +249,9 @@ const CGFloat kOffsetToPinOmnibox = 100;
// Changes ownership of fake omnibox view based on scroll position. // Changes ownership of fake omnibox view based on scroll position.
if (!self.isScrolledIntoFeed && if (!self.isScrolledIntoFeed &&
scrollView.contentOffset.y > -kOffsetToPinOmnibox) { scrollView.contentOffset.y > -kOffsetToPinOmnibox) {
[self setIsScrolledIntoFeed:YES];
[self stickFakeOmniboxToTop]; [self stickFakeOmniboxToTop];
} else if (self.isScrolledIntoFeed && } else if (self.isScrolledIntoFeed &&
scrollView.contentOffset.y <= -kOffsetToPinOmnibox) { scrollView.contentOffset.y <= -kOffsetToPinOmnibox) {
[self setIsScrolledIntoFeed:NO];
[self resetFakeOmnibox]; [self resetFakeOmnibox];
} }
} }
...@@ -322,7 +321,13 @@ const CGFloat kOffsetToPinOmnibox = 100; ...@@ -322,7 +321,13 @@ const CGFloat kOffsetToPinOmnibox = 100;
// Lets this view own the fake omnibox and sticks it to the top of the NTP. // Lets this view own the fake omnibox and sticks it to the top of the NTP.
- (void)stickFakeOmniboxToTop { - (void)stickFakeOmniboxToTop {
[self setIsScrolledIntoFeed:YES];
[self.headerController removeFromParentViewController];
[self.headerController.view removeFromSuperview];
[self.view addSubview:self.headerController.view]; [self.view addSubview:self.headerController.view];
[NSLayoutConstraint activateConstraints:@[ [NSLayoutConstraint activateConstraints:@[
[self.headerController.view.topAnchor [self.headerController.view.topAnchor
constraintEqualToAnchor:self.discoverFeedWrapperViewController.view constraintEqualToAnchor:self.discoverFeedWrapperViewController.view
...@@ -344,7 +349,11 @@ const CGFloat kOffsetToPinOmnibox = 100; ...@@ -344,7 +349,11 @@ const CGFloat kOffsetToPinOmnibox = 100;
// Gives content suggestions collection view ownership of the fake omnibox for // Gives content suggestions collection view ownership of the fake omnibox for
// the width animation. // the width animation.
- (void)resetFakeOmnibox { - (void)resetFakeOmnibox {
[self setIsScrolledIntoFeed:NO];
[self.headerController removeFromParentViewController];
[self.headerController.view removeFromSuperview]; [self.headerController.view removeFromSuperview];
// Reload the content suggestions so that the fake omnibox goes back where it // Reload the content suggestions so that the fake omnibox goes back where it
// belongs. This can probably be optimized by just reloading the header, if // belongs. This can probably be optimized by just reloading the header, if
// that doesn't mess up any collection/header interactions. // that doesn't mess up any collection/header interactions.
...@@ -361,6 +370,30 @@ const CGFloat kOffsetToPinOmnibox = 100; ...@@ -361,6 +370,30 @@ const CGFloat kOffsetToPinOmnibox = 100;
CGPointMake(0, offset); CGPointMake(0, offset);
self.initialContentOffsetFromContentSuggestions = self.initialContentOffsetFromContentSuggestions =
isFromSavedState ? NAN : offset; isFromSavedState ? NAN : offset;
self.scrolledIntoFeed =
self.discoverFeedWrapperViewController.feedCollectionView.contentOffset
.y > kOffsetToPinOmnibox;
}
// Sets an inset to the Discover feed equal to the content suggestions height,
// so that the content suggestions could act as the feed header.
- (void)updateFeedInsetsForContentSuggestions {
CGFloat contentSuggestionsHeight =
self.contentSuggestionsViewController.collectionView.contentSize.height;
// TODO(crbug.com/1114792): Handle landscape/iPad layout.
self.contentSuggestionsViewController.view.frame =
CGRectMake(0, -contentSuggestionsHeight, self.view.frame.size.width,
contentSuggestionsHeight);
self.discoverFeedWrapperViewController.feedCollectionView.contentInset =
UIEdgeInsetsMake([self adjustedContentSuggestionsHeight], 0, 0, 0);
self.headerSynchronizer.additionalOffset = contentSuggestionsHeight;
}
// Content suggestions height adjusted with the safe area top insets.
- (CGFloat)adjustedContentSuggestionsHeight {
return self.contentSuggestionsViewController.collectionView.contentSize
.height +
self.view.safeAreaInsets.top;
} }
#pragma mark - Setters #pragma mark - Setters
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment