diff --git a/submodules/Display/Source/KeyboardManager.swift b/submodules/Display/Source/KeyboardManager.swift index 83fd35fb88..ca9e798f7c 100644 --- a/submodules/Display/Source/KeyboardManager.swift +++ b/submodules/Display/Source/KeyboardManager.swift @@ -127,13 +127,6 @@ class KeyboardManager { } } -private func endAnimations(view: UIView) { - view.layer.removeAllAnimations() - for subview in view.subviews { - endAnimations(view: subview) - } -} - public func viewTreeContainsFirstResponder(view: UIView) -> Bool { if view.isFirstResponder { return true @@ -149,6 +142,7 @@ public func viewTreeContainsFirstResponder(view: UIView) -> Bool { public final class KeyboardViewManager { private let host: StatusBarHost + var willDismissEditingWithoutAnimation: (() -> Void)? init(host: StatusBarHost) { self.host = host @@ -156,11 +150,9 @@ public final class KeyboardViewManager { public func dismissEditingWithoutAnimation(view: UIView) { if viewTreeContainsFirstResponder(view: view) { - view.endEditing(true) - if let keyboardWindow = self.host.keyboardWindow { - for view in keyboardWindow.subviews { - endAnimations(view: view) - } + self.willDismissEditingWithoutAnimation?() + UIView.performWithoutAnimation { + view.endEditing(true) } } } diff --git a/submodules/Display/Source/Navigation/NavigationContainer.swift b/submodules/Display/Source/Navigation/NavigationContainer.swift index a590968359..f503d984ed 100644 --- a/submodules/Display/Source/Navigation/NavigationContainer.swift +++ b/submodules/Display/Source/Navigation/NavigationContainer.swift @@ -233,6 +233,8 @@ public final class NavigationContainer: ASDisplayNode, ASGestureRecognizerDelega return } + topController.cancelInteractiveKeyboardGestures() + topController.isBeingInteractivelyPopped = true topController.viewWillDisappear(true) let topNode = topController.displayNode var bottomControllerLayout = layout @@ -299,6 +301,7 @@ public final class NavigationContainer: ASDisplayNode, ASGestureRecognizerDelega strongSelf.state.transition = nil strongSelf.controllerRemoved(top.value) + topController.isBeingInteractivelyPopped = false strongSelf.ignoreInputHeight = false }) } else { @@ -307,7 +310,8 @@ public final class NavigationContainer: ASDisplayNode, ASGestureRecognizerDelega return } strongSelf.state.transition = nil - + + top.value.isBeingInteractivelyPopped = false top.value.viewDidAppear(true) transition.previous.value.viewDidDisappear(true) }) diff --git a/submodules/Display/Source/ViewController.swift b/submodules/Display/Source/ViewController.swift index 413d8a6de0..b40ac00682 100644 --- a/submodules/Display/Source/ViewController.swift +++ b/submodules/Display/Source/ViewController.swift @@ -234,6 +234,7 @@ public protocol CustomViewControllerNavigationDataSummary: AnyObject { private weak var activeInputView: UIResponder? open var hasActiveInput: Bool = false + public internal(set) var isBeingInteractivelyPopped: Bool = false open var overlayWantsToBeBelowKeyboard: Bool { return false @@ -657,6 +658,10 @@ public protocol CustomViewControllerNavigationDataSummary: AnyObject { open func viewWillLeaveNavigation() { } + open func cancelInteractiveKeyboardGestures() { + self.view.windowHost?.cancelInteractiveKeyboardGestures() + } + open override func viewDidAppear(_ animated: Bool) { self.activeInputView = nil diff --git a/submodules/Display/Source/WindowContent.swift b/submodules/Display/Source/WindowContent.swift index 6db27aa7c4..e98e3a378c 100644 --- a/submodules/Display/Source/WindowContent.swift +++ b/submodules/Display/Source/WindowContent.swift @@ -293,6 +293,7 @@ public class Window1 { private var statusBarHidden = false private var shouldNotAnimateLikelyKeyboardAutocorrectionSwitch: Bool = false + private var suppressNextKeyboardHideAnimationUntil: Double? public private(set) var forceInCallStatusBarText: String? = nil public var inCallNavigate: (() -> Void)? @@ -477,6 +478,10 @@ public class Window1 { self.topPresentationContext.containerLayoutUpdated(containedLayoutForWindowLayout(self.windowLayout, deviceMetrics: self.deviceMetrics), transition: .immediate) self.overlayPresentationContext.containerLayoutUpdated(containedLayoutForWindowLayout(self.windowLayout, deviceMetrics: self.deviceMetrics), transition: .immediate) + self.keyboardViewManager?.willDismissEditingWithoutAnimation = { [weak self] in + self?.suppressNextKeyboardHideAnimationUntil = CACurrentMediaTime() + 1.0 + } + //TODO:release check old iOS /*self.statusBarChangeObserver = NotificationCenter.default.addObserver(forName: UIApplication.willChangeStatusBarFrameNotification, object: nil, queue: OperationQueue.main, using: { [weak self] notification in if let strongSelf = self, strongSelf.statusBarHost != nil { @@ -648,6 +653,9 @@ public class Window1 { transition = .immediate } } + if strongSelf.shouldSuppressNextKeyboardHideAnimation(keyboardHeight: keyboardHeight) { + transition = .immediate + } strongSelf.updateLayout { $0.update(inputHeight: keyboardHeight.isLessThanOrEqualTo(0.0) ? nil : keyboardHeight, transition: transition, overrideTransition: false) } } @@ -717,6 +725,21 @@ public class Window1 { self.hostView.containerView.addGestureRecognizer(recognizer) self.hostView.containerView.addSubview(self.badgeView) } + + private func shouldSuppressNextKeyboardHideAnimation(keyboardHeight: CGFloat) -> Bool { + guard let suppressNextKeyboardHideAnimationUntil = self.suppressNextKeyboardHideAnimationUntil else { + return false + } + if suppressNextKeyboardHideAnimationUntil < CACurrentMediaTime() { + self.suppressNextKeyboardHideAnimationUntil = nil + return false + } + if keyboardHeight.isLessThanOrEqualTo(0.0) { + self.suppressNextKeyboardHideAnimationUntil = nil + return true + } + return false + } public required init(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index 70f4ac306d..a1cfcb43ff 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -7967,12 +7967,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G override public func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) - if #available(iOS 18.0, *) { - } else { - //TODO:release - } - UIView.performWithoutAnimation { - self.view.endEditing(true) + if !self.isBeingInteractivelyPopped { + UIView.performWithoutAnimation { + self.view.endEditing(true) + } } self.chatDisplayNode.historyNode.canReadHistory.set(.single(false)) @@ -8048,6 +8046,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G self.chatDisplayNode.willNavigateAway() } + override public func cancelInteractiveKeyboardGestures() { + super.cancelInteractiveKeyboardGestures() + self.chatDisplayNode.cancelInteractiveKeyboardGestures() + } + override public func inFocusUpdated(isInFocus: Bool) { self.disableStickerAnimationsPromise.set(!isInFocus) self.chatDisplayNode.inFocusUpdated(isInFocus: isInFocus)