From 18c890bb95164845cbffe1604ec9f285d4dc9a45 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Fri, 11 Jan 2019 09:24:24 -0500 Subject: [PATCH 1/2] Fix input toolbar margins issue. --- Signal/Signal-Info.plist | 2 +- .../ConversationInputToolbar.h | 4 +- .../ConversationInputToolbar.m | 53 +++++++++++++++++-- .../ConversationViewController.m | 23 ++++++++ SignalShareExtension/Info.plist | 2 +- 5 files changed, 78 insertions(+), 6 deletions(-) diff --git a/Signal/Signal-Info.plist b/Signal/Signal-Info.plist index 2a975b708..d3ad20f63 100644 --- a/Signal/Signal-Info.plist +++ b/Signal/Signal-Info.plist @@ -47,7 +47,7 @@ CFBundleVersion - 2.34.0.14 + 2.34.0.20 ITSAppUsesNonExemptEncryption LOGS_EMAIL diff --git a/Signal/src/ViewControllers/ConversationView/ConversationInputToolbar.h b/Signal/src/ViewControllers/ConversationView/ConversationInputToolbar.h index a50cd464a..8801a2633 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationInputToolbar.h +++ b/Signal/src/ViewControllers/ConversationView/ConversationInputToolbar.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // NS_ASSUME_NONNULL_BEGIN @@ -53,6 +53,8 @@ NS_ASSUME_NONNULL_BEGIN - (void)updateFontSizes; +- (void)updateLayoutWithIsLandscape:(BOOL)isLandscape safeAreaInsets:(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 8423b5add..4bdc4efc7 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationInputToolbar.m +++ b/Signal/src/ViewControllers/ConversationView/ConversationInputToolbar.m @@ -1,5 +1,5 @@ // -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // #import "ConversationInputToolbar.h" @@ -53,6 +53,9 @@ const CGFloat kMaxTextViewHeight = 98; @property (nonatomic, nullable) UILabel *recordingLabel; @property (nonatomic) BOOL isRecordingVoiceMemo; @property (nonatomic) CGPoint voiceMemoGestureStartLocation; +@property (nonatomic, nullable) NSArray *layoutContraints; +@property (nonatomic) BOOL isLandscapeLayout; +@property (nonatomic) UIEdgeInsets receivedSafeAreaInsets; @end @@ -68,7 +71,9 @@ const CGFloat kMaxTextViewHeight = 98; self = [super initWithFrame:CGRectZero]; _conversationStyle = conversationStyle; - + _isLandscapeLayout = NO; + _receivedSafeAreaInsets = UIEdgeInsetsZero; + if (self) { [self createContents]; } @@ -163,7 +168,18 @@ const CGFloat kMaxTextViewHeight = 98; self.contentRows.axis = UILayoutConstraintAxisVertical; [self addSubview:self.contentRows]; - [self.contentRows autoPinEdgesToSuperviewEdges]; + [self.contentRows autoPinEdgeToSuperviewEdge:ALEdgeTop]; + [self.contentRows autoPinEdgeToSuperviewSafeArea:ALEdgeBottom]; + + // See comments on updateContentLayout:. + if (@available(iOS 11, *)) { + self.contentRows.insetsLayoutMarginsFromSafeArea = NO; + self.composeRow.insetsLayoutMarginsFromSafeArea = NO; + self.insetsLayoutMarginsFromSafeArea = NO; + } + self.contentRows.preservesSuperviewLayoutMargins = NO; + self.composeRow.preservesSuperviewLayoutMargins = NO; + self.preservesSuperviewLayoutMargins = NO; [self ensureShouldShowVoiceMemoButtonAnimated:NO doLayout:NO]; } @@ -322,6 +338,37 @@ 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.contentRows autoPinEdgeToSuperviewEdge:ALEdgeLeft withInset:self.receivedSafeAreaInsets.left], + [self.contentRows autoPinEdgeToSuperviewEdge:ALEdgeRight withInset:self.receivedSafeAreaInsets.right], + ]; +} + +- (void)updateLayoutWithIsLandscape:(BOOL)isLandscape safeAreaInsets:(UIEdgeInsets)safeAreaInsets +{ + BOOL didChange = (self.isLandscapeLayout != isLandscape + || !UIEdgeInsetsEqualToEdgeInsets(self.receivedSafeAreaInsets, safeAreaInsets)); + BOOL hasLayout = self.layoutContraints != nil; + + self.isLandscapeLayout = isLandscape; + 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 798311d1a..ac8ecfdb6 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 @@ -1249,6 +1250,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, @@ -4844,6 +4847,8 @@ typedef enum : NSUInteger { // new size. [strongSelf resetForSizeOrOrientationChange]; + [strongSelf updateInputToolbarLayout]; + if (lastVisibleIndexPath) { [strongSelf.collectionView scrollToItemAtIndexPath:lastVisibleIndexPath atScrollPosition:UICollectionViewScrollPositionBottom @@ -4876,6 +4881,24 @@ 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 +{ + BOOL isLandscape = self.view.width > self.view.height; + UIEdgeInsets safeAreaInsets = UIEdgeInsetsZero; + if (@available(iOS 11, *)) { + safeAreaInsets = self.view.safeAreaInsets; + } + [self.inputToolbar updateLayoutWithIsLandscape:isLandscape safeAreaInsets:safeAreaInsets]; } @end diff --git a/SignalShareExtension/Info.plist b/SignalShareExtension/Info.plist index d28911298..371ecdeb4 100644 --- a/SignalShareExtension/Info.plist +++ b/SignalShareExtension/Info.plist @@ -19,7 +19,7 @@ CFBundleShortVersionString 2.34.0 CFBundleVersion - 2.34.0.14 + 2.34.0.20 ITSAppUsesNonExemptEncryption NSAppTransportSecurity From b8e2cb6267cdffa87fffcb8dba9858f135f189f1 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Tue, 15 Jan 2019 16:33:54 -0500 Subject: [PATCH 2/2] Respond to CR. --- .../ConversationView/ConversationInputToolbar.h | 2 +- .../ConversationView/ConversationInputToolbar.m | 8 ++------ .../ConversationView/ConversationViewController.m | 3 +-- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/Signal/src/ViewControllers/ConversationView/ConversationInputToolbar.h b/Signal/src/ViewControllers/ConversationView/ConversationInputToolbar.h index 8801a2633..eaed1c481 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationInputToolbar.h +++ b/Signal/src/ViewControllers/ConversationView/ConversationInputToolbar.h @@ -53,7 +53,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)updateFontSizes; -- (void)updateLayoutWithIsLandscape:(BOOL)isLandscape safeAreaInsets:(UIEdgeInsets)safeAreaInsets; +- (void)updateLayoutWithSafeAreaInsets:(UIEdgeInsets)safeAreaInsets; #pragma mark - Voice Memo diff --git a/Signal/src/ViewControllers/ConversationView/ConversationInputToolbar.m b/Signal/src/ViewControllers/ConversationView/ConversationInputToolbar.m index 4bdc4efc7..7420c9a67 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationInputToolbar.m +++ b/Signal/src/ViewControllers/ConversationView/ConversationInputToolbar.m @@ -54,7 +54,6 @@ const CGFloat kMaxTextViewHeight = 98; @property (nonatomic) BOOL isRecordingVoiceMemo; @property (nonatomic) CGPoint voiceMemoGestureStartLocation; @property (nonatomic, nullable) NSArray *layoutContraints; -@property (nonatomic) BOOL isLandscapeLayout; @property (nonatomic) UIEdgeInsets receivedSafeAreaInsets; @end @@ -71,7 +70,6 @@ const CGFloat kMaxTextViewHeight = 98; self = [super initWithFrame:CGRectZero]; _conversationStyle = conversationStyle; - _isLandscapeLayout = NO; _receivedSafeAreaInsets = UIEdgeInsetsZero; if (self) { @@ -355,13 +353,11 @@ const CGFloat kMaxTextViewHeight = 98; ]; } -- (void)updateLayoutWithIsLandscape:(BOOL)isLandscape safeAreaInsets:(UIEdgeInsets)safeAreaInsets +- (void)updateLayoutWithSafeAreaInsets:(UIEdgeInsets)safeAreaInsets { - BOOL didChange = (self.isLandscapeLayout != isLandscape - || !UIEdgeInsetsEqualToEdgeInsets(self.receivedSafeAreaInsets, safeAreaInsets)); + BOOL didChange = !UIEdgeInsetsEqualToEdgeInsets(self.receivedSafeAreaInsets, safeAreaInsets); BOOL hasLayout = self.layoutContraints != nil; - self.isLandscapeLayout = isLandscape; self.receivedSafeAreaInsets = safeAreaInsets; if (didChange || !hasLayout) { diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m index ac8ecfdb6..08e8c1488 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m @@ -4893,12 +4893,11 @@ typedef enum : NSUInteger { - (void)updateInputToolbarLayout { - BOOL isLandscape = self.view.width > self.view.height; UIEdgeInsets safeAreaInsets = UIEdgeInsetsZero; if (@available(iOS 11, *)) { safeAreaInsets = self.view.safeAreaInsets; } - [self.inputToolbar updateLayoutWithIsLandscape:isLandscape safeAreaInsets:safeAreaInsets]; + [self.inputToolbar updateLayoutWithSafeAreaInsets:safeAreaInsets]; } @end