Overview
IQRootControllerConfiguration is an internal struct that captures and maintains the layout state of the root view controller containing an active text input view. It records the initial state when a text input becomes active and provides methods to detect changes and restore the original layout.
Purpose
The root controller configuration:- Captures the initial frame origin of the root view controller’s view
- Records the initial safe area insets
- Tracks the device orientation when the text input became active
- Detects whether the view has been moved by keyboard adjustments
- Provides restoration functionality to return views to their original position
- Monitors interactive pop gestures that might affect view positioning
Properties
rootController
A weak reference to the root view controller containing the active text input view. This is stored weakly to avoid retain cycles.
beginOrigin
The original frame origin of the root controller’s view when the text input became active. This value is captured during initialization and used for restoration.
beginSafeAreaInsets
The initial safe area insets of the root controller’s view. Stored for reference during layout calculations.
beginOrientation
The device interface orientation when the configuration was created. Used to detect orientation changes that require configuration updates.Possible values:
.portrait.portraitUpsideDown.landscapeLeft.landscapeRight.unknown
currentOrientation
The current device interface orientation. This computed property queries the window scene to determine the current orientation.
isReady
Indicates whether the root controller’s view is in a window and ready for adjustments.Returns
true when rootController?.view.window != nil, ensuring the view is part of the active view hierarchy.hasChanged
Indicates whether the root controller’s view origin has been moved from its initial position.Returns
true when the current frame origin doesn’t match beginOrigin, signaling that keyboard adjustments have been applied.isInteractiveGestureActive
Indicates whether an interactive pop gesture (swipe to go back) is currently active.Returns
true when the navigation controller’s interactivePopGestureRecognizer is in the .began or .changed state.Why this matters:
Interactive pop gestures manipulate view controller frames, which can conflict with keyboard adjustments. The configuration monitors this state to avoid premature restoration during gesture interactions.Initialization
Methods
restore()
Restores the root controller’s view to its original frame origin.Returns
true if the frame was changed (restoration occurred), false if the frame was already at the original position or the root controller is nil.Lifecycle
When Configuration is Created
A newIQRootControllerConfiguration is created when:
- A text input view becomes active (begins editing)
- The keyboard appears or changes
- The orientation changes while a text input is active
When Configuration is Updated
The configuration is replaced with a new instance when:- The active text input’s root controller changes (e.g., navigation to a new screen)
- The device orientation changes from portrait to landscape or vice versa
- A new text input in a different view controller becomes active
When Configuration is Restored
Therestore() method is called when:
- The keyboard is dismissed
- A text input resigns first responder
- The keyboard manager is disabled
- An orientation change completes
- An interactive pop gesture completes successfully
Orientation Handling
The configuration includes special logic for orientation changes:Interactive Gesture Handling
The configuration plays a crucial role in handling interactive navigation gestures. During a swipe-to-go-back gesture, the view frames are manipulated, but the keyboard adjustment should only be reverted if the gesture completes (not if it’s cancelled).
isInteractiveGestureActive property helps coordinate this:
Thread Safety
The struct is marked with
@MainActor, ensuring all property access and method calls occur on the main thread. This is essential since it manipulates view frames and queries the view hierarchy.Value Type Benefits
Using a struct (value type) instead of a class provides important benefits:- Immutable State: Once created, the
beginOrigin,beginSafeAreaInsets, andbeginOrientationcannot be changed - Simple Lifecycle: No need to manage deinitialization or cleanup
- Clear Ownership: The struct is owned by
IQActiveConfigurationwith clear lifecycle boundaries
Usage in Active Configuration
See Also
- IQActiveConfiguration - Owner of root controller configuration
- IQKeyboardManager - Main keyboard manager class
- IQScrollViewConfiguration - Scroll view state tracking