Improve scroll state continuity during conversation view rotations.

pull/1/head
Matthew Chen 7 years ago
parent 1fc90974fc
commit 9dda2fa8c0

@ -4347,23 +4347,34 @@ typedef enum : NSUInteger {
targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset
{ {
if (self.scrollContinuity == kScrollContinuityBottom && self.lastKnownDistanceFromBottom) { if (self.scrollContinuity == kScrollContinuityBottom && self.lastKnownDistanceFromBottom) {
// Adjust the content offset to reflect the "last known" distance NSValue *_Nullable contentOffset =
// from the bottom of the content. [self contentOffsetForLastKnownDistanceFromBottom:self.lastKnownDistanceFromBottom.floatValue];
CGFloat contentOffsetYBottom = self.maxContentOffsetY; if (contentOffset) {
CGFloat contentOffsetY = contentOffsetYBottom - MAX(0, self.lastKnownDistanceFromBottom.floatValue); proposedContentOffset = contentOffset.CGPointValue;
CGFloat minContentOffsetY;
if (@available(iOS 11, *)) {
minContentOffsetY = -self.collectionView.safeAreaInsets.top;
} else {
minContentOffsetY = 0.f;
} }
contentOffsetY = MAX(minContentOffsetY, contentOffsetY);
proposedContentOffset.y = contentOffsetY;
} }
return proposedContentOffset; return proposedContentOffset;
} }
// We use this hook to ensure scroll state continuity. As the collection
// view's content size changes, we want to keep the same cells in view.
- (nullable NSValue *)contentOffsetForLastKnownDistanceFromBottom:(CGFloat)lastKnownDistanceFromBottom
{
// Adjust the content offset to reflect the "last known" distance
// from the bottom of the content.
CGFloat contentOffsetYBottom = self.maxContentOffsetY;
CGFloat contentOffsetY = contentOffsetYBottom - MAX(0, lastKnownDistanceFromBottom);
CGFloat minContentOffsetY;
if (@available(iOS 11, *)) {
minContentOffsetY = -self.collectionView.safeAreaInsets.top;
} else {
minContentOffsetY = 0.f;
}
contentOffsetY = MAX(minContentOffsetY, contentOffsetY);
return [NSValue valueWithCGPoint:CGPointMake(0, contentOffsetY)];
}
#pragma mark - Scroll State #pragma mark - Scroll State
- (BOOL)isScrolledToBottom - (BOOL)isScrolledToBottom
@ -4811,18 +4822,34 @@ typedef enum : NSUInteger {
{ {
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
// Update and snapshot the "last known distance from bottom".
[self updateLastKnownDistanceFromBottom];
NSNumber *_Nullable lastKnownDistanceFromBottom = self.lastKnownDistanceFromBottom;
__weak ConversationViewController *weakSelf = self; __weak ConversationViewController *weakSelf = self;
[coordinator [coordinator
animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) { animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
// Do nothing. // Do nothing.
} }
completion:^(id<UIViewControllerTransitionCoordinatorContext> context) { completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
ConversationViewController *strongSelf = weakSelf;
if (!strongSelf) {
return;
}
// When transition animation is complete, update layout to reflect // When transition animation is complete, update layout to reflect
// new size. // new size.
[weakSelf resetForSizeOrOrientationChange]; [strongSelf resetForSizeOrOrientationChange];
if (lastKnownDistanceFromBottom) {
NSValue *_Nullable contentOffsetValue =
[strongSelf contentOffsetForLastKnownDistanceFromBottom:lastKnownDistanceFromBottom.floatValue];
if (contentOffsetValue) {
CGPoint contentOffset = contentOffsetValue.CGPointValue;
[strongSelf.collectionView setContentOffset:contentOffset animated:NO];
}
}
}]; }];
// TODO: Ensure scroll state continuity?
} }
- (void)traitCollectionDidChange:(nullable UITraitCollection *)previousTraitCollection - (void)traitCollectionDidChange:(nullable UITraitCollection *)previousTraitCollection

Loading…
Cancel
Save