From e1c01ddc89c4a55a9be4a1e0a2dc72a1229e6dab Mon Sep 17 00:00:00 2001 From: Dominic Go <18517029+dominicstop@users.noreply.github.com> Date: Wed, 21 Jun 2023 06:55:52 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=92=AB=20Update:=20Exp=20-=20`AdaptiveMod?= =?UTF-8?q?al`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: Update experiment/test - `swift-programmatic-modal/AdaptiveModal`. --- .../AdaptiveModal/AdaptiveModalManager.swift | 31 +++++++++---- .../RNILayout/RNILayoutKeyboardValues.swift | 15 +++++++ .../RNILayout/RNILayoutValueContext.swift | 45 +++++++++++++++++-- .../project.pbxproj | 2 +- 4 files changed, 80 insertions(+), 13 deletions(-) diff --git a/experiments/swift-programmatic-modal/AdaptiveModal/AdaptiveModalManager.swift b/experiments/swift-programmatic-modal/AdaptiveModal/AdaptiveModalManager.swift index e8e33dbc..0dd52723 100644 --- a/experiments/swift-programmatic-modal/AdaptiveModal/AdaptiveModalManager.swift +++ b/experiments/swift-programmatic-modal/AdaptiveModal/AdaptiveModalManager.swift @@ -65,15 +65,25 @@ class AdaptiveModalManager: NSObject { private var layoutKeyboardValues: RNILayoutKeyboardValues?; private var layoutValueContext: RNILayoutValueContext { - if let targetVC = self.targetViewController { - return .init(fromTargetViewController: targetVC) ?? .default; - }; - - if let targetView = self.targetView { - return .init(fromTargetView: targetView) ?? .default; - }; + let context: RNILayoutValueContext? = { + if let targetVC = self.targetViewController { + return .init( + fromTargetViewController: targetVC, + keyboardValues: self.layoutKeyboardValues + ); + }; + + if let targetView = self.targetView { + return .init( + fromTargetView: targetView, + keyboardValues: self.layoutKeyboardValues + ); + }; + + return nil; + }(); - return .default; + return context ?? .default; }; // MARK: - Properties - Config Interpolation Points @@ -608,6 +618,10 @@ class AdaptiveModalManager: NSObject { self.modalAnimator = nil; }; + private func clearLayoutKeyboardValues(){ + self.layoutKeyboardValues = nil; + }; + private func removeObservers(){ let notificationNames = [ UIResponder.keyboardWillShowNotification, @@ -669,6 +683,7 @@ class AdaptiveModalManager: NSObject { private func cleanup() { self.clearGestureValues(); self.clearAnimators(); + self.clearLayoutKeyboardValues(); self.cleanupViews(); self.cleanupSnapPointOverride(); diff --git a/experiments/swift-programmatic-modal/RNILayout/RNILayoutKeyboardValues.swift b/experiments/swift-programmatic-modal/RNILayout/RNILayoutKeyboardValues.swift index 2fa2c30d..2c91a86b 100644 --- a/experiments/swift-programmatic-modal/RNILayout/RNILayoutKeyboardValues.swift +++ b/experiments/swift-programmatic-modal/RNILayout/RNILayoutKeyboardValues.swift @@ -13,6 +13,21 @@ struct RNILayoutKeyboardValues { var animationDuration: CGFloat; var animationCurve: UIView.AnimationCurve; + + func computeKeyboardSize(relativeToView targetView: UIView) -> CGSize? { + guard let window = targetView.window else { return nil }; + + // Get keyboard height. + let keyboardFrameInView = targetView.convert( + self.frameEnd, + from: window + ); + + let intersection = targetView.bounds.intersection(keyboardFrameInView); + + guard !intersection.isNull else { return nil }; + return intersection.size; + }; }; extension RNILayoutKeyboardValues { diff --git a/experiments/swift-programmatic-modal/RNILayout/RNILayoutValueContext.swift b/experiments/swift-programmatic-modal/RNILayout/RNILayoutValueContext.swift index 34b9281c..1ebb972b 100644 --- a/experiments/swift-programmatic-modal/RNILayout/RNILayoutValueContext.swift +++ b/experiments/swift-programmatic-modal/RNILayout/RNILayoutValueContext.swift @@ -8,11 +8,14 @@ import UIKit public struct RNILayoutValueContext { + static let `default`: Self = .init( targetRect: .zero, windowSize: nil, currentSize: nil, - safeAreaInsets: nil + safeAreaInsets: nil, + keyboardScreenRect: nil, + keyboardRelativeSize: nil ); let targetRect: CGRect; @@ -22,6 +25,9 @@ public struct RNILayoutValueContext { let safeAreaInsets: UIEdgeInsets?; + let keyboardScreenRect: CGRect?; + let keyboardRelativeSize: CGSize?; + var targetSize: CGSize { self.targetRect.size; }; @@ -31,25 +37,46 @@ public struct RNILayoutValueContext { }; }; +// MARK: - Init +// ------------ + extension RNILayoutValueContext { + init( derivedFrom prev: Self, + targetView: UIView? = nil, targetRect: CGRect? = nil, windowSize: CGSize? = nil, currentSize: CGSize? = nil, - safeAreaInsets: UIEdgeInsets? = nil + safeAreaInsets: UIEdgeInsets? = nil, + keyboardValues: RNILayoutKeyboardValues? = nil ) { self.targetRect = targetRect ?? prev.targetRect; - self.windowSize = windowSize ?? prev.windowSize; self.currentSize = currentSize ?? prev.currentSize; self.safeAreaInsets = safeAreaInsets ?? prev.safeAreaInsets; + self.keyboardScreenRect = keyboardValues?.frameEnd ?? prev.keyboardScreenRect; + + self.keyboardRelativeSize = { + guard let targetView = targetView, + let keyboardValues = keyboardValues + else { + return prev.keyboardRelativeSize; + }; + + let keyboardSize = keyboardValues.computeKeyboardSize( + relativeToView: targetView + ); + + return keyboardSize ?? prev.keyboardRelativeSize; + }(); }; init?( fromTargetViewController targetVC: UIViewController, + keyboardValues: RNILayoutKeyboardValues? = nil, currentSize: CGSize? = nil ) { guard let targetView = targetVC.view else { return nil }; @@ -58,12 +85,17 @@ extension RNILayoutValueContext { self.windowSize = targetView.window?.bounds.size; self.safeAreaInsets = targetView.window?.safeAreaInsets; - self.currentSize = currentSize; + + self.keyboardScreenRect = keyboardValues?.frameEnd; + + self.keyboardRelativeSize = + keyboardValues?.computeKeyboardSize(relativeToView: targetView); }; init?( fromTargetView targetView: UIView, + keyboardValues: RNILayoutKeyboardValues? = nil, currentSize: CGSize? = nil ) { self.targetRect = targetView.frame; @@ -71,5 +103,10 @@ extension RNILayoutValueContext { self.safeAreaInsets = targetView.window?.safeAreaInsets; self.currentSize = currentSize; + + self.keyboardScreenRect = keyboardValues?.frameEnd; + + self.keyboardRelativeSize = + keyboardValues?.computeKeyboardSize(relativeToView: targetView); }; }; diff --git a/experiments/swift-programmatic-modal/swift-programmatic-modal.xcodeproj/project.pbxproj b/experiments/swift-programmatic-modal/swift-programmatic-modal.xcodeproj/project.pbxproj index 81629eb6..227c7c66 100644 --- a/experiments/swift-programmatic-modal/swift-programmatic-modal.xcodeproj/project.pbxproj +++ b/experiments/swift-programmatic-modal/swift-programmatic-modal.xcodeproj/project.pbxproj @@ -432,11 +432,11 @@ 88D017D72A1B302F004664D2 /* RNILayout.swift */, 88E8C01B2A23203E008C2FF8 /* RNILayoutPreset.swift */, 886AFCAA2A31FF40004AC9FB /* RNILayoutValue.swift */, + 887AA0562A4253050089F517 /* RNILayoutKeyboardValues.swift */, 886AFCB02A325B6F004AC9FB /* RNILayoutValueContext.swift */, 886AFCAC2A3209D5004AC9FB /* RNILayoutValueMode.swift */, 886AFCAE2A320DED004AC9FB /* RNILayoutValuePercentTarget.swift */, 8849B6A62A3F7A7700A5F412 /* RNILayoutValue+StaticInit.swift */, - 887AA0562A4253050089F517 /* RNILayoutKeyboardValues.swift */, ); path = RNILayout; sourceTree = "";