From 57a9f464dae3f89a51ae75a0d3c1984cef5dcd45 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Mon, 28 Jan 2019 13:06:10 -0500 Subject: [PATCH] Revert "Remove safe area insets hack in conversation input toolbar." This reverts commit 70775e78526e4fad789b9f112d0ea2bdc63666f4. --- .../ConversationInputToolbar.h | 2 ++ .../ConversationInputToolbar.m | 34 +++++++++++++++++-- .../ConversationViewController.m | 22 ++++++++++++ 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/Signal/src/ViewControllers/ConversationView/ConversationInputToolbar.h b/Signal/src/ViewControllers/ConversationView/ConversationInputToolbar.h index dc1d0754f..adebf8e83 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationInputToolbar.h +++ b/Signal/src/ViewControllers/ConversationView/ConversationInputToolbar.h @@ -54,6 +54,8 @@ NS_ASSUME_NONNULL_BEGIN - (void)updateFontSizes; +- (void)updateLayoutWithSafeAreaInsets:(UIEdgeInsets)safeAreaInsets; + #pragma mark - Voice Memo - (void)ensureTextViewHeight; diff --git a/Signal/src/ViewControllers/ConversationView/ConversationInputToolbar.m b/Signal/src/ViewControllers/ConversationView/ConversationInputToolbar.m index 75015ce8e..64a9d9b31 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationInputToolbar.m +++ b/Signal/src/ViewControllers/ConversationView/ConversationInputToolbar.m @@ -69,6 +69,8 @@ const CGFloat kMaxTextViewHeight = 98; @property (nonatomic, nullable) UILabel *recordingLabel; @property (nonatomic) BOOL isRecordingVoiceMemo; @property (nonatomic) CGPoint voiceMemoGestureStartLocation; +@property (nonatomic, nullable) NSArray *layoutContraints; +@property (nonatomic) UIEdgeInsets receivedSafeAreaInsets; @property (nonatomic, nullable) InputLinkPreview *inputLinkPreview; @property (nonatomic) BOOL wasLinkPreviewCancelled; @property (nonatomic, nullable, weak) LinkPreviewView *linkPreviewView; @@ -84,6 +86,7 @@ const CGFloat kMaxTextViewHeight = 98; self = [super initWithFrame:CGRectZero]; _conversationStyle = conversationStyle; + _receivedSafeAreaInsets = UIEdgeInsetsZero; if (self) { [self createContents]; @@ -199,8 +202,6 @@ const CGFloat kMaxTextViewHeight = 98; [self addSubview:self.hStack]; [self.hStack autoPinEdgeToSuperviewEdge:ALEdgeTop]; [self.hStack autoPinEdgeToSuperviewSafeArea:ALEdgeBottom]; - [self.hStack autoPinEdgeToSuperviewSafeArea:ALEdgeLeading]; - [self.hStack autoPinEdgeToSuperviewSafeArea:ALEdgeTrailing]; [self.hStack setContentHuggingHorizontalLow]; [self.hStack setCompressionResistanceHorizontalLow]; @@ -370,6 +371,35 @@ const CGFloat kMaxTextViewHeight = 98; } } +// iOS doesn't always update the safeAreaInsets correctly & in a timely +// way for the inputAccessoryView after a orientation change. The best +// workaround appears to be to use the safeAreaInsets from +// ConversationViewController's view. ConversationViewController updates +// this input toolbar using updateLayoutWithIsLandscape:. +- (void)updateContentLayout +{ + if (self.layoutContraints) { + [NSLayoutConstraint deactivateConstraints:self.layoutContraints]; + } + + self.layoutContraints = @[ + [self.hStack autoPinEdgeToSuperviewEdge:ALEdgeLeft withInset:self.receivedSafeAreaInsets.left], + [self.hStack autoPinEdgeToSuperviewEdge:ALEdgeRight withInset:self.receivedSafeAreaInsets.right], + ]; +} + +- (void)updateLayoutWithSafeAreaInsets:(UIEdgeInsets)safeAreaInsets +{ + BOOL didChange = !UIEdgeInsetsEqualToEdgeInsets(self.receivedSafeAreaInsets, safeAreaInsets); + BOOL hasLayout = self.layoutContraints != nil; + + self.receivedSafeAreaInsets = safeAreaInsets; + + if (didChange || !hasLayout) { + [self updateContentLayout]; + } +} + - (void)handleLongPress:(UIGestureRecognizer *)sender { switch (sender.state) { diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m index bcd06a9a2..2c3d14173 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m @@ -747,6 +747,7 @@ typedef enum : NSUInteger { NSTimeInterval appearenceDuration = CACurrentMediaTime() - self.viewControllerCreatedAt; OWSLogVerbose(@"First viewWillAppear took: %.2fms", appearenceDuration * 1000); } + [self updateInputToolbarLayout]; } - (NSArray> *)viewItems @@ -1231,6 +1232,8 @@ typedef enum : NSUInteger { // Clear the "on open" state after the view has been presented. self.actionOnOpen = ConversationViewActionNone; + + [self updateInputToolbarLayout]; } // `viewWillDisappear` is called whenever the view *starts* to disappear, @@ -4841,6 +4844,8 @@ typedef enum : NSUInteger { // new size. [strongSelf resetForSizeOrOrientationChange]; + [strongSelf updateInputToolbarLayout]; + if (lastVisibleIndexPath) { [strongSelf.collectionView scrollToItemAtIndexPath:lastVisibleIndexPath atScrollPosition:UICollectionViewScrollPositionBottom @@ -4873,6 +4878,23 @@ typedef enum : NSUInteger { // Try to update the lastKnownDistanceFromBottom; the content size may have changed. [self updateLastKnownDistanceFromBottom]; } + [self updateInputToolbarLayout]; +} + +- (void)viewSafeAreaInsetsDidChange +{ + [super viewSafeAreaInsetsDidChange]; + + [self updateInputToolbarLayout]; +} + +- (void)updateInputToolbarLayout +{ + UIEdgeInsets safeAreaInsets = UIEdgeInsetsZero; + if (@available(iOS 11, *)) { + safeAreaInsets = self.view.safeAreaInsets; + } + [self.inputToolbar updateLayoutWithSafeAreaInsets:safeAreaInsets]; } @end