Skip to content

Commit

Permalink
fix: height of software keyboard when using hardware keyboard on iOS
Browse files Browse the repository at this point in the history
UIKeyboardDidShowNotification on iOS 18.2 returns an incorrect end frame
origin when opening the on-screen keyboard with a hardware keyboard
attached.

Instead of relying on this incorrect frame, return the height of the
keyboard view in response to UIKeyboardDidShowNotification and 0 in
response to UIKeyboardDidHideNotification.

State changes are now completely handled in response to notifications,
and updateKeyboardFrame is only responsible for animation tracking.
  • Loading branch information
mhoran committed Jan 6, 2025
1 parent 9f6b546 commit 5a6a72f
Showing 1 changed file with 28 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -173,22 +173,11 @@ - (float)getAnimatingKeyboardHeight

- (void)updateKeyboardFrame
{
CGFloat keyboardHeight = 0;
bool isKeyboardAnimationRunning = [self hasAnyAnimation:_measuringView];
if (isKeyboardAnimationRunning) {
keyboardHeight = [self getAnimatingKeyboardHeight];
} else {
// measuring view is no longer running an animation, we should settle in OPEN/CLOSE state
if (_state == OPENING || _state == CLOSING) {
_state = _state == OPENING ? OPEN : CLOSED;
}
if (_state == OPEN || _state == CLOSED) {
keyboardHeight = _targetKeyboardHeight;
}
// stop display link updates if no animation is running
[[self getDisplayLink] setPaused:YES];
CGFloat keyboardHeight = [self getAnimatingKeyboardHeight];
[self runListeners:keyboardHeight];
}
[self runListeners:keyboardHeight];
}

- (void)keyboardWillChangeFrame:(NSNotification *)notification
Expand Down Expand Up @@ -237,8 +226,6 @@ - (void)keyboardWillChangeFrame:(NSNotification *)notification
self->_measuringView.frame = CGRectMake(0, -1, 0, self->_targetKeyboardHeight);
}];
[self runUpdater];
} else {
[self runListeners:_targetKeyboardHeight];
}
}

Expand Down Expand Up @@ -266,6 +253,10 @@ - (int)subscribeForKeyboardEvents:(KeyboardEventListenerBlock)listener
selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
[notificationCenter addObserver:self
selector:@selector(keyboardDidHide:)
name:UIKeyboardDidHideNotification
object:nil];
}

[self->_listeners setObject:listener forKey:listenerId];
Expand All @@ -283,6 +274,7 @@ - (void)unsubscribeFromKeyboardEvents:(int)listenerId
[notificationCenter removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[notificationCenter removeObserver:self name:UIKeyboardDidShowNotification object:nil];
[notificationCenter removeObserver:self name:UIKeyboardWillHideNotification object:nil];
[notificationCenter removeObserver:self name:UIKeyboardDidHideNotification object:nil];
}
});
}
Expand All @@ -305,10 +297,21 @@ - (void)keyboardWillShow:(NSNotification *)notification

- (void)keyboardDidShow:(NSNotification *)notification
{
[[self getDisplayLink] setPaused:YES];

auto window = [[[UIApplication sharedApplication] delegate] window];
CGSize windowSize = window.frame.size;
auto keyboardView = [self getKeyboardView];
if (keyboardView) {
_targetKeyboardHeight = windowSize.height - keyboardView.frame.origin.y;
}
_state = OPEN;
[self runListeners:_targetKeyboardHeight];

if (_isKeyboardObserverAttached) {
return;
}
if (auto keyboardView = [self getKeyboardView]) {
if (keyboardView) {
[_keyboardView addObserver:self
forKeyPath:@"center"
options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew
Expand All @@ -328,6 +331,15 @@ - (void)keyboardWillHide:(NSNotification *)notification
[self keyboardWillChangeFrame:notification];
}

- (void)keyboardDidHide:(NSNotification *)notification
{
[[self getDisplayLink] setPaused:YES];

_targetKeyboardHeight = 0;
_state = CLOSED;
[self runListeners:_targetKeyboardHeight];
}

- (void)updateKeyboardHeightDuringInteractiveDismiss:(CGPoint)oldKeyboardFrame
newKeyboardFrame:(CGPoint)newKeyboardFrame
{
Expand Down

0 comments on commit 5a6a72f

Please sign in to comment.