Description
When IQKeyboardManager is enabled, switching from a taller keyboard to a shorter keyboard while the keyboard remains visible does not correctly restore the root view controller's vertical position.
For example, switching from the Chinese Pinyin 9-key keyboard to the shorter English keyboard reduces the keyboard height, but the root view remains close to the offset used by the taller keyboard.
As a result, an unnecessary blank area remains between the input view and the keyboard, and the entire page stays shifted upward.
Environment
- IQKeyboardManagerSwift:
8.0.3
- iOS:
18.x
- Device: iPhone
- Integration: CocoaPods
IQKeyboardManager.shared.isEnabled = true
Steps to Reproduce
- Enable
IQKeyboardManager.
- Open a screen containing a text input near the bottom.
- Focus the text input.
- Switch to the Chinese Pinyin 9-key keyboard.
- While the keyboard remains visible, switch to the shorter English keyboard.
- Observe the root view controller's vertical position.
Expected Behavior
When the keyboard height decreases, the root view controller should move downward by the corresponding keyboard height difference.
For example, if the keyboard height changes from 374 points to 335 points, the root view should move downward by approximately 39 points.
The input view should remain correctly attached to the top of the current keyboard without leaving an extra blank area.
Actual Behavior
The keyboard frame notification correctly reports the new, shorter keyboard height, but the root view is restored by only a few points.
In the following example:
- The original keyboard height is
374.
- The new keyboard height is
335.
- The expected downward restoration is approximately
39.
- The calculated
moveUp value is only -5.
The root view therefore remains near the position used for the taller keyboard.
Debug Logs
Initial taller keyboard
[IQKeyboard][frame] oldHeight: 0.0 newHeight: 374.0
oldFrame: (0.0, 852.0, 393.0, 0.0)
newFrame: (0.0, 478.0, 393.0, 374.0)
[IQKeyboard][beforeScroll]
keyboardHeight: 374.0
rootOrigin: (0.0, 0.0)
rootBeginOrigin: (0.0, 0.0)
inputRectInWindow: (64.0, 744.0, 223.0, 40.0)
moveUp: 384.0
[IQKeyboard][adjustRoot]
moveUp: 384.0
currentOrigin: (0.0, 0.0)
beginOrigin: (0.0, 0.0)
keyboardHeight: 374.0
After this adjustment, the root view origin becomes approximately:
Switching to the shorter keyboard
[IQKeyboard][frame] oldHeight: 374.0 newHeight: 335.0
oldFrame: (0.0, 478.0, 393.0, 374.0)
newFrame: (0.0, 517.0, 393.0, 335.0)
[IQKeyboard][beforeScroll]
keyboardHeight: 335.0
rootOrigin: (0.0, -374.0)
rootBeginOrigin: (0.0, 0.0)
inputRectInWindow: (64.0, 428.0, 223.0, 40.0)
moveUp: -5.0
[IQKeyboard][adjustRoot]
moveUp: -5.0
currentOrigin: (0.0, -374.0)
beginOrigin: (0.0, 0.0)
keyboardHeight: 335.0
The root view moves downward by only 5 points and remains at approximately:
The expected root view origin is approximately:
Suspected Cause
When the keyboard remains visible and its height decreases, the negative moveUp value appears to be calculated mainly from the current text input position.
However, the root view has already been shifted upward using the previous, taller keyboard height.
The current calculation does not appear to include the difference between the previous keyboard height and the new keyboard height. Consequently, the root view is not fully restored when changing from a taller keyboard to a shorter one.
This appears to happen around the root-controller adjustment logic in:
IQKeyboardManager+Position.swift
Specifically, the negative moveUp branch restores only the newly calculated value instead of also accounting for the keyboard height reduction.
Suggested Solution
When:
- the keyboard was already visible,
- the new keyboard is shorter than the previous keyboard, and
- the root view is currently shifted upward,
the downward restoration distance should be at least the difference between the previous and current keyboard heights.
Conceptually:
let keyboardHeightReduction = max(
0,
previousKeyboardHeight - currentKeyboardHeight
)
let downwardDistance = max(
abs(moveUp),
keyboardHeightReduction
)
let adjustedMoveUp = -downwardDistance
The adjusted value can then be used by the existing negative moveUp branch.
With the example above:
previousKeyboardHeight = 374
currentKeyboardHeight = 335
keyboardHeightReduction = 39
moveUp = -5
adjustedMoveUp = -39
This restores the root view from approximately -374 to -335, matching the shorter keyboard height.
Additional Notes
- Keyboard frame notifications are received correctly.
- The issue occurs while the keyboard remains visible.
- Switching from a shorter keyboard to a taller keyboard works as expected.
- The issue is most visible when switching from Chinese Pinyin 9-key to the English keyboard.
- The same behavior may occur with other keyboard or input-view transitions where the new input view is shorter than the previous one.
- This issue is independent of the IQKeyboardToolbarManager toolbar.
Description
When
IQKeyboardManageris enabled, switching from a taller keyboard to a shorter keyboard while the keyboard remains visible does not correctly restore the root view controller's vertical position.For example, switching from the Chinese Pinyin 9-key keyboard to the shorter English keyboard reduces the keyboard height, but the root view remains close to the offset used by the taller keyboard.
As a result, an unnecessary blank area remains between the input view and the keyboard, and the entire page stays shifted upward.
Environment
8.0.318.xSteps to Reproduce
IQKeyboardManager.Expected Behavior
When the keyboard height decreases, the root view controller should move downward by the corresponding keyboard height difference.
For example, if the keyboard height changes from
374points to335points, the root view should move downward by approximately39points.The input view should remain correctly attached to the top of the current keyboard without leaving an extra blank area.
Actual Behavior
The keyboard frame notification correctly reports the new, shorter keyboard height, but the root view is restored by only a few points.
In the following example:
374.335.39.moveUpvalue is only-5.The root view therefore remains near the position used for the taller keyboard.
Debug Logs
Initial taller keyboard
After this adjustment, the root view origin becomes approximately:
Switching to the shorter keyboard
The root view moves downward by only
5points and remains at approximately:The expected root view origin is approximately:
Suspected Cause
When the keyboard remains visible and its height decreases, the negative
moveUpvalue appears to be calculated mainly from the current text input position.However, the root view has already been shifted upward using the previous, taller keyboard height.
The current calculation does not appear to include the difference between the previous keyboard height and the new keyboard height. Consequently, the root view is not fully restored when changing from a taller keyboard to a shorter one.
This appears to happen around the root-controller adjustment logic in:
Specifically, the negative
moveUpbranch restores only the newly calculated value instead of also accounting for the keyboard height reduction.Suggested Solution
When:
the downward restoration distance should be at least the difference between the previous and current keyboard heights.
Conceptually:
The adjusted value can then be used by the existing negative
moveUpbranch.With the example above:
This restores the root view from approximately
-374to-335, matching the shorter keyboard height.Additional Notes