From 30b2942a80c8efd807064d7117e9b0d5337d05ae Mon Sep 17 00:00:00 2001 From: Balazs Szamody Date: Mon, 31 Jan 2022 16:53:23 +1100 Subject: [PATCH 1/2] Fixed a height constraint issue on iPad sheets --- .../KeyboardLayoutGuide.swift | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/Sources/KeyboardLayoutGuide/KeyboardLayoutGuide.swift b/Sources/KeyboardLayoutGuide/KeyboardLayoutGuide.swift index fa36f2d..11e097f 100644 --- a/Sources/KeyboardLayoutGuide/KeyboardLayoutGuide.swift +++ b/Sources/KeyboardLayoutGuide/KeyboardLayoutGuide.swift @@ -112,6 +112,22 @@ open class KeyboardLayoutGuide: UILayoutGuide { if #available(iOS 11.0, *), usesSafeArea, height > 0, let bottom = owningView?.safeAreaInsets.bottom { height -= bottom } + + // Factor in the non full screen views (iPad sheets) + if let activeWindow = UIApplication.shared.activeWindow, let owningView = owningView, height > 0 { + // Owning view's frame in the active window + let owningFrameInRoot = owningView.convert(owningView.frame, to: activeWindow) + // We have to ignore the part of the owning view that's outside of the active window + // (Modal presentation) + let intersectionFrame = activeWindow.frame.intersection(owningFrameInRoot) + + let windowHeight = activeWindow.frame.height + let bottomDifference = windowHeight - (intersectionFrame.height + intersectionFrame.origin.y) + + height -= bottomDifference + } + + heightConstraint?.constant = height if duration > 0.0 { animate(note) @@ -178,3 +194,23 @@ func isVisible(view: UIView) -> Bool { } return isVisible(view: view, inView: view.superview) } + +extension UIApplication { + + // Finds the currently active window, This works similar to the + // deprecated `keyWindow` however it supports multi-window'd + // iPad apps + var activeWindow: UIWindow? { + if #available(iOS 13, *) { + return connectedScenes + .filter { $0.activationState == .foregroundActive } + .map { $0 as? UIWindowScene } + .compactMap { $0 } + .first?.windows + .first { $0.isKeyWindow } + } else { + return keyWindow + } + } + +} From 4fd85500ed986e9deae68106991bd8beb157b7c3 Mon Sep 17 00:00:00 2001 From: Balazs Szamody Date: Fri, 22 Apr 2022 09:55:36 +1000 Subject: [PATCH 2/2] - fixed an issue when the heightConstraint receives an infinite value --- Sources/KeyboardLayoutGuide/KeyboardLayoutGuide.swift | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Sources/KeyboardLayoutGuide/KeyboardLayoutGuide.swift b/Sources/KeyboardLayoutGuide/KeyboardLayoutGuide.swift index 11e097f..06a583e 100644 --- a/Sources/KeyboardLayoutGuide/KeyboardLayoutGuide.swift +++ b/Sources/KeyboardLayoutGuide/KeyboardLayoutGuide.swift @@ -122,12 +122,16 @@ open class KeyboardLayoutGuide: UILayoutGuide { let intersectionFrame = activeWindow.frame.intersection(owningFrameInRoot) let windowHeight = activeWindow.frame.height - let bottomDifference = windowHeight - (intersectionFrame.height + intersectionFrame.origin.y) + let bottomDifference = windowHeight - intersectionFrame.maxY height -= bottomDifference } - + guard height != .infinity else { + // When the app is running in multiple windows, it can happen that both windows are `foregroundActive` + // and the intersection frame's origin can become infinite as the owning view is in the other window and the app would crash. + return + } heightConstraint?.constant = height if duration > 0.0 { animate(note)