diff options
| author | Andrej Mihajlov <and@mullvad.net> | 2021-04-14 11:34:50 +0200 |
|---|---|---|
| committer | Andrej Mihajlov <and@mullvad.net> | 2021-04-29 15:43:38 +0200 |
| commit | 69a13855a0c739121bb2c740f4d4be5d4707db07 (patch) | |
| tree | cced4e73b9ebcd428782870bb20a23fb25345e5f | |
| parent | 3f9204e4af119b85c8edcce709b05ca09d32973f (diff) | |
| download | mullvadvpn-69a13855a0c739121bb2c740f4d4be5d4707db07.tar.xz mullvadvpn-69a13855a0c739121bb2c740f4d4be5d4707db07.zip | |
Keyboard: determine the presentation container view by traversing the view hierarchy to address the missing reference to containerView on iOS 14.4
Additionally log errors to obtain the container view.
| -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 |
