diff --git a/IQKeyboardManager/IQKeyboardManager.m b/IQKeyboardManager/IQKeyboardManager.m index 72325eab..a5a6a3ad 100644 --- a/IQKeyboardManager/IQKeyboardManager.m +++ b/IQKeyboardManager/IQKeyboardManager.m @@ -664,7 +664,17 @@ -(void)adjustPosition // Converting Rectangle according to window bounds. CGRect textFieldViewRectInWindow = [[textFieldView superview] convertRect:textFieldView.frame toView:keyWindow]; - CGRect textFieldViewRectInRootSuperview = [[textFieldView superview] convertRect:textFieldView.frame toView:rootController.view.superview]; + CGRect textFieldViewRectInRootSuperview; + + // For modal presentations, rootController.view.superview can be nil or point to an incorrect coordinate space + // Convert to window coordinates and then to rootController.view coordinates to ensure proper positioning + if (rootController.view.superview != nil) { + textFieldViewRectInRootSuperview = [[textFieldView superview] convertRect:textFieldView.frame toView:rootController.view.superview]; + } else { + // When superview is nil (common in modal presentations), convert to window then to root view + CGRect rectInWindow = [[textFieldView superview] convertRect:textFieldView.frame toView:keyWindow]; + textFieldViewRectInRootSuperview = [keyWindow convertRect:rectInWindow toView:rootController.view]; + } // Getting RootView origin. CGPoint rootViewOrigin = rootController.view.frame.origin; @@ -962,7 +972,13 @@ -(void)adjustPosition CGRect previousCellRect = [tableView rectForRowAtIndexPath:previousIndexPath]; if (CGRectIsEmpty(previousCellRect) == NO) { - CGRect previousCellRectInRootSuperview = [tableView convertRect:previousCellRect toView:rootController.view.superview]; + CGRect previousCellRectInRootSuperview; + if (rootController.view.superview != nil) { + previousCellRectInRootSuperview = [tableView convertRect:previousCellRect toView:rootController.view.superview]; + } else { + CGRect rectInWindow = [tableView convertRect:previousCellRect toView:keyWindow]; + previousCellRectInRootSuperview = [keyWindow convertRect:rectInWindow toView:rootController.view]; + } moveUp = MIN(0, CGRectGetMaxY(previousCellRectInRootSuperview) - topLayoutGuide); } } @@ -987,7 +1003,13 @@ -(void)adjustPosition CGRect previousCellRect = attributes.frame; if (CGRectIsEmpty(previousCellRect) == NO) { - CGRect previousCellRectInRootSuperview = [collectionView convertRect:previousCellRect toView:rootController.view.superview]; + CGRect previousCellRectInRootSuperview; + if (rootController.view.superview != nil) { + previousCellRectInRootSuperview = [collectionView convertRect:previousCellRect toView:rootController.view.superview]; + } else { + CGRect rectInWindow = [collectionView convertRect:previousCellRect toView:keyWindow]; + previousCellRectInRootSuperview = [keyWindow convertRect:rectInWindow toView:rootController.view]; + } moveUp = MIN(0, CGRectGetMaxY(previousCellRectInRootSuperview) - topLayoutGuide); } } @@ -1167,7 +1189,13 @@ -(void)adjustPosition CGFloat keyboardYPosition = CGRectGetHeight(keyWindow.frame)-originalKbSize.height; - CGRect rootSuperViewFrameInWindow = [rootController.view.superview convertRect:rootController.view.superview.bounds toView:keyWindow]; + CGRect rootSuperViewFrameInWindow; + if (rootController.view.superview != nil) { + rootSuperViewFrameInWindow = [rootController.view.superview convertRect:rootController.view.superview.bounds toView:keyWindow]; + } else { + // Use the window frame as a fallback for modal presentations + rootSuperViewFrameInWindow = keyWindow.frame; + } CGFloat keyboardOverlapping = CGRectGetMaxY(rootSuperViewFrameInWindow) - keyboardYPosition; diff --git a/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+Position.swift b/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+Position.swift index 478aa439..fca93122 100644 --- a/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+Position.swift +++ b/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+Position.swift @@ -124,8 +124,17 @@ import IQKeyboardCore } let textInputViewRectInWindow: CGRect = superview.convert(textInputView.frame, to: window) - let textInputViewRectInRootSuperview: CGRect = superview.convert(textInputView.frame, - to: rootController.view.superview) + let textInputViewRectInRootSuperview: CGRect = { + // For modal presentations, rootController.view.superview can be nil or point to an incorrect coordinate space + // Convert to window coordinates and then to rootController.view coordinates to ensure proper positioning + if let rootSuperview = rootController.view.superview { + return superview.convert(textInputView.frame, to: rootSuperview) + } else { + // When superview is nil (common in modal presentations), convert to window then to root view + let rectInWindow = superview.convert(textInputView.frame, to: window) + return window.convert(rectInWindow, to: rootController.view) + } + }() // Getting RootViewOrigin. let rootViewOrigin: CGPoint = rootController.view.frame.origin