summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAndrej Mihajlov <and@mullvad.net>2021-04-14 11:34:50 +0200
committerAndrej Mihajlov <and@mullvad.net>2021-04-29 15:43:38 +0200
commit69a13855a0c739121bb2c740f4d4be5d4707db07 (patch)
treecced4e73b9ebcd428782870bb20a23fb25345e5f
parent3f9204e4af119b85c8edcce709b05ca09d32973f (diff)
downloadmullvadvpn-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.swift28
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