diff --git a/IQKeyboardManagerSwift/IQKeyboardManager/Configuration/IQActiveConfiguration.swift b/IQKeyboardManagerSwift/IQKeyboardManager/Configuration/IQActiveConfiguration.swift index 502f714d..d44fd286 100644 --- a/IQKeyboardManagerSwift/IQKeyboardManager/Configuration/IQActiveConfiguration.swift +++ b/IQKeyboardManagerSwift/IQKeyboardManager/Configuration/IQActiveConfiguration.swift @@ -75,7 +75,8 @@ internal final class IQActiveConfiguration: NSObject { private func sendEvent() { guard let rootConfiguration = rootConfiguration, - rootConfiguration.isReady else { return } + rootConfiguration.isReady, + rootConfiguration.rootController != nil else { return } if keyboardInfo.isVisible { if lastEvent == .hide { @@ -105,11 +106,16 @@ internal final class IQActiveConfiguration: NSObject { // Also the interactiveGesture becomes inactive (genuinely it's state is .possible) // At this moment. rootController.view.publisher(for: \.frame) - .sink(receiveValue: { [weak self] frame in - guard let self = self else { return } + .sink(receiveValue: { [weak self, weak rootController] frame in + guard let self = self, + let rootController = rootController else { return } print(frame) - guard frame.origin == .zero, - !rootConfiguration.isInteractiveGestureActive else { return } + + // Ensure we have a valid root configuration and the controller hasn't been deallocated + guard let currentRootConfig = self.rootConfiguration, + currentRootConfig.rootController === rootController, + frame.origin == .zero, + !currentRootConfig.isInteractiveGestureActive else { return } self.cancellable.forEach { $0.cancel() } self.cancellable.removeAll() @@ -135,6 +141,7 @@ internal final class IQActiveConfiguration: NSObject { guard let textInputView: UIView = textInputView, let controller: UIViewController = textInputView.iq.parentContainerViewController() else { + // Safely restore any existing configuration before clearing it if let rootConfiguration = rootConfiguration, rootConfiguration.hasChanged { animate(alongsideTransition: { @@ -147,7 +154,13 @@ internal final class IQActiveConfiguration: NSObject { let newConfiguration = IQRootControllerConfiguration(rootController: controller) - guard newConfiguration.rootController?.view.window != rootConfiguration?.rootController?.view.window || + // Ensure both configurations have valid root controllers before comparing + guard let newRootController = newConfiguration.rootController else { + rootConfiguration = nil + return + } + + guard newRootController.view.window != rootConfiguration?.rootController?.view.window || newConfiguration.beginOrientation != rootConfiguration?.beginOrientation else { return } if rootConfiguration?.rootController != newConfiguration.rootController { diff --git a/IQKeyboardManagerSwift/IQKeyboardManager/Configuration/IQRootControllerConfiguration.swift b/IQKeyboardManagerSwift/IQKeyboardManager/Configuration/IQRootControllerConfiguration.swift index 4980b73e..de3199b9 100644 --- a/IQKeyboardManagerSwift/IQKeyboardManager/Configuration/IQRootControllerConfiguration.swift +++ b/IQKeyboardManagerSwift/IQKeyboardManager/Configuration/IQRootControllerConfiguration.swift @@ -48,8 +48,9 @@ internal struct IQRootControllerConfiguration { } var currentOrientation: UIInterfaceOrientation { + guard let rootController = rootController else { return .unknown } let interfaceOrientation: UIInterfaceOrientation - if let scene = rootController?.view.window?.windowScene { + if let scene = rootController.view.window?.windowScene { interfaceOrientation = scene.interfaceOrientation } else { interfaceOrientation = .unknown @@ -58,11 +59,13 @@ internal struct IQRootControllerConfiguration { } var isReady: Bool { - return rootController?.view.window != nil + guard let rootController = rootController else { return false } + return rootController.view.window != nil } var hasChanged: Bool { - let origin: CGPoint = rootController?.view.frame.origin ?? .zero + guard let rootController = rootController else { return false } + let origin: CGPoint = rootController.view.frame.origin return !origin.equalTo(beginOrigin) } diff --git a/IQKeyboardManagerSwift/IQKeyboardManager/UIKitExtensions/UIView+Parent.swift b/IQKeyboardManagerSwift/IQKeyboardManager/UIKitExtensions/UIView+Parent.swift index cf2e63c5..461389e4 100644 --- a/IQKeyboardManagerSwift/IQKeyboardManager/UIKitExtensions/UIView+Parent.swift +++ b/IQKeyboardManagerSwift/IQKeyboardManager/UIKitExtensions/UIView+Parent.swift @@ -82,10 +82,16 @@ public extension IQKeyboardExtension where Base: UIView { parentContainerViewController = matchController } - if let controller: UIViewController = parentContainerViewController?.iq_parentContainerViewController() { - return controller + // Safely call the parent container method with additional nil checks + if let parentController = parentContainerViewController { + // Ensure the controller is still valid before calling the method + if let finalController = parentController.iq_parentContainerViewController() { + return finalController + } else { + return parentController + } } else { - return parentContainerViewController + return nil } } }