diff options
| -rw-r--r-- | ios/MullvadVPN/AutomaticKeyboardResponder.swift | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/ios/MullvadVPN/AutomaticKeyboardResponder.swift b/ios/MullvadVPN/AutomaticKeyboardResponder.swift index f427b71bd0..d5d7c18cd2 100644 --- a/ios/MullvadVPN/AutomaticKeyboardResponder.swift +++ b/ios/MullvadVPN/AutomaticKeyboardResponder.swift @@ -7,6 +7,7 @@ // import UIKit +import Logging class AutomaticKeyboardResponder { weak var targetView: UIView? @@ -15,6 +16,7 @@ class AutomaticKeyboardResponder { private var showsKeyboard = false private var lastKeyboardRect: CGRect? + private let logger = Logger(label: "AutomaticKeyboardResponder") private var presentationFrameObserver: NSKeyValueObservation? init<T: UIView>(targetView: T, handler: @escaping (T, CGFloat) -> Void) { @@ -65,16 +67,17 @@ class AutomaticKeyboardResponder { } private func addPresentationControllerObserver() { + guard isFormSheetPresentation else { return } + // Presentation controller follows the keyboard on iPad. // Install the observer to listen for the container view frame and adjust the target view // accordingly. - guard let containerView = parentViewController?.presentationController?.containerView, isFormSheetPresentation else { return } - - let containingView = containerView.subviews.first { (subview) -> Bool in - return targetView?.isDescendant(of: subview) ?? false + guard let containerView = presentationContainerView else { + logger.warning("Cannot determine the container view in form sheet presentation.") + return } - presentationFrameObserver = containingView?.observe(\.frame, options: [.new], changeHandler: { [weak self] (containingView, change) in + presentationFrameObserver = containerView.observe(\.frame, options: [.new], changeHandler: { [weak self] (containingView, change) in guard let self = self, let keyboardFrameValue = self.lastKeyboardRect else { return } self.adjustContentInsets(keyboardRect: keyboardFrameValue) @@ -93,6 +96,21 @@ class AutomaticKeyboardResponder { return iterator.first { $0 is UIViewController } as? UIViewController } + private var presentationContainerView: UIView? { + var currentView = parentViewController?.view + let iterator = AnyIterator { () -> UIView? in + let next = currentView?.superview + currentView = next + return next + } + + // Find the container view that private `_UIFormSheetPresentationController` moves + // along with the keyboard. + return iterator.first { (view) -> Bool in + return view.description.starts(with: "<UIDropShadowView") + } + } + private var isFormSheetPresentation: Bool { return UIDevice.current.userInterfaceIdiom == .pad && parentViewController?.modalPresentationStyle == .formSheet |
