diff --git a/Signal/src/ViewControllers/ConversationView/ConversationCollectionView.h b/Signal/src/ViewControllers/ConversationView/ConversationCollectionView.h index d6d34b35c..419c4574e 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationCollectionView.h +++ b/Signal/src/ViewControllers/ConversationView/ConversationCollectionView.h @@ -1,13 +1,13 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // NS_ASSUME_NONNULL_BEGIN @protocol ConversationCollectionViewDelegate -- (void)collectionViewWillChangeLayout; -- (void)collectionViewDidChangeLayout; +- (void)collectionViewWillChangeSizeFrom:(CGSize)oldSize to:(CGSize)newSize; +- (void)collectionViewDidChangeSizeFrom:(CGSize)oldSize to:(CGSize)newSize; @end diff --git a/Signal/src/ViewControllers/ConversationView/ConversationCollectionView.m b/Signal/src/ViewControllers/ConversationView/ConversationCollectionView.m index a2efe2cf9..a6aad672f 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationCollectionView.m +++ b/Signal/src/ViewControllers/ConversationView/ConversationCollectionView.m @@ -1,5 +1,5 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // #import "ConversationCollectionView.h" @@ -24,13 +24,15 @@ NS_ASSUME_NONNULL_BEGIN // hacks in the conversation view's code. return; } - BOOL isChanging = !CGSizeEqualToSize(frame.size, self.frame.size); + CGSize oldSize = self.frame.size; + CGSize newSize = frame.size; + BOOL isChanging = !CGSizeEqualToSize(oldSize, newSize); if (isChanging) { - [self.layoutDelegate collectionViewWillChangeLayout]; + [self.layoutDelegate collectionViewWillChangeSizeFrom:oldSize to:newSize]; } [super setFrame:frame]; if (isChanging) { - [self.layoutDelegate collectionViewDidChangeLayout]; + [self.layoutDelegate collectionViewDidChangeSizeFrom:oldSize to:newSize]; } } @@ -48,13 +50,15 @@ NS_ASSUME_NONNULL_BEGIN // hacks in the conversation view's code. return; } - BOOL isChanging = !CGSizeEqualToSize(bounds.size, self.bounds.size); + CGSize oldSize = self.bounds.size; + CGSize newSize = bounds.size; + BOOL isChanging = !CGSizeEqualToSize(oldSize, newSize); if (isChanging) { - [self.layoutDelegate collectionViewWillChangeLayout]; + [self.layoutDelegate collectionViewWillChangeSizeFrom:oldSize to:newSize]; } [super setBounds:bounds]; if (isChanging) { - [self.layoutDelegate collectionViewDidChangeLayout]; + [self.layoutDelegate collectionViewDidChangeSizeFrom:oldSize to:newSize]; } } diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m index d07c6d6c4..fa93b149d 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m @@ -563,6 +563,9 @@ typedef enum : NSUInteger { self.layout.delegate = self; // We use the root view bounds as the initial frame for the collection // view so that its contents can be laid out immediately. + // + // TODO: To avoid relayout, it'd be better to take into account safeAreaInsets, + // but they're not yet set when this method is called. _collectionView = [[ConversationCollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:self.layout]; self.collectionView.layoutDelegate = self; @@ -1621,11 +1624,8 @@ typedef enum : NSUInteger { { OWSLogInfo(@"didChangePreferredContentSize"); - // Evacuate cached cell sizes. - for (id viewItem in self.viewItems) { - [viewItem clearCachedLayoutState]; - } - [self resetContentAndLayout]; + [self resetForSizeOrOrientationChange]; + [self.inputToolbar updateFontSizes]; } @@ -4218,18 +4218,18 @@ typedef enum : NSUInteger { #pragma mark - ConversationCollectionViewDelegate -- (void)collectionViewWillChangeLayout +- (void)collectionViewWillChangeSizeFrom:(CGSize)oldSize to:(CGSize)newSize { OWSAssertIsOnMainThread(); } -- (void)collectionViewDidChangeLayout +- (void)collectionViewDidChangeSizeFrom:(CGSize)oldSize to:(CGSize)newSize { OWSAssertIsOnMainThread(); [self updateLastVisibleSortId]; - self.conversationStyle.viewWidth = self.collectionView.width; - [self.collectionView.collectionViewLayout invalidateLayout]; + + [self resetForSizeOrOrientationChange]; } #pragma mark - View Items @@ -4764,13 +4764,14 @@ typedef enum : NSUInteger { { [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; - self.conversationStyle.viewWidth = size.width; - - for (id viewItem in self.viewItems) { - [viewItem clearCachedLayoutState]; - } - - [self resetContentAndLayout]; + __weak ConversationViewController *weakSelf = self; + [coordinator + animateAlongsideTransition:^(id context) { + // Do nothing. + } + completion:^(id context) { + [weakSelf resetForSizeOrOrientationChange]; + }]; // TODO: Ensure scroll state continuity? } @@ -4783,6 +4784,23 @@ typedef enum : NSUInteger { [self ensureBannerState]; } +- (void)resetForSizeOrOrientationChange +{ + self.scrollContinuity = kScrollContinuityBottom; + + self.conversationStyle.viewWidth = self.collectionView.width; + // Evacuate cached cell sizes. + for (id viewItem in self.viewItems) { + [viewItem clearCachedLayoutState]; + } + [self.collectionView.collectionViewLayout invalidateLayout]; + [self.collectionView reloadData]; + if (self.viewHasEverAppeared) { + // Try to update the lastKnownDistanceFromBottom; the content size may have changed. + [self updateLastKnownDistanceFromBottom]; + } +} + @end NS_ASSUME_NONNULL_END