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 /ios | |
| 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.
Diffstat (limited to 'ios')
| -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 |
