From 075e4fc9d21a4b337ee403b8adb9098ad2d146e4 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Tue, 11 May 2021 13:23:02 -0300 Subject: [PATCH 1/2] Scroll continuity: keyboard animations vs. landing loads. --- .../ConversationView/CV/CVLoadCoordinator.swift | 8 +++++++- .../ConversationView/CVViewState.swift | 3 +++ .../ConversationView/ConversationViewController.m | 14 ++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/Signal/src/ViewControllers/ConversationView/CV/CVLoadCoordinator.swift b/Signal/src/ViewControllers/ConversationView/CV/CVLoadCoordinator.swift index 4d782e48e0..f208a07f4d 100644 --- a/Signal/src/ViewControllers/ConversationView/CV/CVLoadCoordinator.swift +++ b/Signal/src/ViewControllers/ConversationView/CV/CVLoadCoordinator.swift @@ -542,7 +542,13 @@ public class CVLoadCoordinator: NSObject { let (loadPromise, loadResolver) = Promise.pending() func canLandLoad() -> Bool { - return !delegate.isLayoutApplyingUpdate && !delegate.areCellsAnimating + AssertIsOnMainThread() + if let lastKeyboardAnimationDate = viewState.lastKeyboardAnimationDate, + lastKeyboardAnimationDate.isAfterNow { + return false + } + let result = !delegate.isLayoutApplyingUpdate && !delegate.areCellsAnimating + return result } func tryToResolve() { diff --git a/Signal/src/ViewControllers/ConversationView/CVViewState.swift b/Signal/src/ViewControllers/ConversationView/CVViewState.swift index a5a014ed97..b85b56d495 100644 --- a/Signal/src/ViewControllers/ConversationView/CVViewState.swift +++ b/Signal/src/ViewControllers/ConversationView/CVViewState.swift @@ -151,6 +151,9 @@ public class CVViewState: NSObject { @objc public var currentVoiceMessageModel: VoiceMessageModel? + @objc + public var lastKeyboardAnimationDate: Date? + // MARK: - @objc diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m index db1864fd10..1ff6fd4a93 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m @@ -3803,11 +3803,25 @@ typedef enum : NSUInteger { - (void)handleKeyboardStateChange:(NSTimeInterval)animationDuration animationCurve:(UIViewAnimationCurve)animationCurve { + OWSAssertIsOnMainThread(); + if (self.transitionCoordinator.isInteractive) { return; } if (self.shouldAnimateKeyboardChanges && animationDuration > 0) { + // Make note of when the keyboard animation will block + // loads from landing during the keyboard animation. + // It isn't safe to block loads for long, so we cap + // how long they will be blocked for. + NSTimeInterval keyboardAnimationBlockLoadInterval = kSecondInterval * 1.0; + NSDate *animationCompletionDate = [[NSDate new] dateByAddingTimeInterval:keyboardAnimationBlockLoadInterval]; + if (self.viewState.lastKeyboardAnimationDate == nil || + [self.viewState.lastKeyboardAnimationDate isBeforeDate:animationCompletionDate]) { + self.viewState.lastKeyboardAnimationDate = animationCompletionDate; + self.scrollContinuity = ScrollContinuityBottom; + } + // The animation curve provided by the keyboard notifications // is a private value not represented in UIViewAnimationOptions. // We don't use a block based animation here because it's not From 5d12ce0de2f7f8c26e4efa464b7168102b2fd6e4 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Tue, 11 May 2021 13:27:40 -0300 Subject: [PATCH 2/2] Scroll continuity: keyboard animations vs. landing loads. --- .../ConversationView/ConversationViewController.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m index 1ff6fd4a93..044668183d 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m @@ -3816,8 +3816,9 @@ typedef enum : NSUInteger { // how long they will be blocked for. NSTimeInterval keyboardAnimationBlockLoadInterval = kSecondInterval * 1.0; NSDate *animationCompletionDate = [[NSDate new] dateByAddingTimeInterval:keyboardAnimationBlockLoadInterval]; + NSDate *lastKeyboardAnimationDate = [[NSDate new] dateByAddingTimeInterval:-1.0]; if (self.viewState.lastKeyboardAnimationDate == nil || - [self.viewState.lastKeyboardAnimationDate isBeforeDate:animationCompletionDate]) { + [self.viewState.lastKeyboardAnimationDate isBeforeDate:lastKeyboardAnimationDate]) { self.viewState.lastKeyboardAnimationDate = animationCompletionDate; self.scrollContinuity = ScrollContinuityBottom; }