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