internal final class IQActiveConfiguration { // Keyboard state var keyboardInfo: IQKeyboardInfo { get } // Active text input var textInputView: (any IQTextInputView)? { get } var textInputViewInfo: IQTextInputViewInfo? { get } // Root controller state var rootConfiguration: IQRootControllerConfiguration? // Ready when all components initialized var isReady: Bool { get }}
internal struct IQRootControllerConfiguration { weak var rootController: UIViewController? // Initial state captured at keyboard show let beginOrigin: CGPoint let beginSafeAreaInsets: UIEdgeInsets let beginOrientation: UIInterfaceOrientation}
// Current device orientationvar currentOrientation: UIInterfaceOrientation { get }// Whether controller is in a windowvar isReady: Bool { get }// Whether view origin has changedvar hasChanged: Bool { get }// Whether interactive pop gesture is activevar isInteractiveGestureActive: Bool { get }
func restore() -> Bool { guard let rootController = rootController, !rootController.view.frame.origin.equalTo(beginOrigin) else { return false } var rect = rootController.view.frame rect.origin = beginOrigin rootController.view.frame = rect return true}
IQRootControllerConfiguration is created when a text input becomes active and stores the original layout state to enable restoration when the keyboard dismisses.
internal struct IQScrollViewConfiguration { let scrollView: UIScrollView let startingContentOffset: CGPoint let startingScrollIndicatorInsets: UIEdgeInsets let startingContentInset: UIEdgeInsets private let canRestoreContentOffset: Bool}
Override the global keyboard distance for specific views:
// Use custom distancetextField.iq.distanceFromKeyboard = 50.0// Revert to global settingtextField.iq.distanceFromKeyboard = UIView.defaultKeyboardDistance
Implementation:
public extension IQKeyboardExtension where Base: IQTextInputView { var distanceFromKeyboard: CGFloat { get { if let base = base { if let value = objc_getAssociatedObject(base, &AssociatedKeys.distanceFromKeyboard) as? CGFloat { return value } } return UIView.defaultKeyboardDistance } set(newValue) { if let base = base { objc_setAssociatedObject(base, &AssociatedKeys.distanceFromKeyboard, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) } if newValue < 0 { IQKeyboardManager.shared.showLog("Warning: distanceFromKeyboard shouldn't be negative.") } } }}
// Use global setting (default)textField.iq.enableMode = .default// Force enable for this viewtextField.iq.enableMode = .enabled// Force disable for this viewtextField.iq.enableMode = .disabled
Enable modes:
public enum IQEnableMode: Int { case `default` // Use global isEnabled setting case enabled // Always enable for this view case disabled // Always disable for this view}
Enable mode priority
IQKeyboardManager evaluates enable state in this order:
View-specific enable mode (.iq.enableMode)
.enabled → Always enabled
.disabled → Always disabled
.default → Continue to next check
View controller class lists
If in disabledDistanceHandlingClasses → Disabled
If in enabledDistanceHandlingClasses → Enabled
Otherwise → Use global setting
Global setting (IQKeyboardManager.shared.isEnabled)
// From IQKeyboardManager+Internal.swiftfunc privateIsEnabled() -> Bool { guard let textInputView = activeConfiguration.textInputView else { return isEnabled } switch textInputView.internalEnableMode { case .default: // Check controller classes... // Fall back to global isEnabled case .enabled: return true case .disabled: return false }}
Set global defaults, then override per-view as needed:
// Global defaultIQKeyboardManager.shared.keyboardDistance = 10.0// Override for specific text fieldslargeTextField.iq.distanceFromKeyboard = 30.0compactTextField.iq.distanceFromKeyboard = 5.0