From eddc86b7b0795fe7c7a82d86f6ee151ccdca229f Mon Sep 17 00:00:00 2001 From: Jaakko Keränen Date: Sat, 6 Mar 2021 14:44:17 +0200 Subject: Mobile: Dealing with keyboard height The software keyboard obstructs part of the UI, so need to offset the view if the focused input widget would not be visible. --- src/ios.m | 69 ++++++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 53 insertions(+), 16 deletions(-) (limited to 'src/ios.m') diff --git a/src/ios.m b/src/ios.m index 5abf87df..4d1aac37 100644 --- a/src/ios.m +++ b/src/ios.m @@ -31,28 +31,63 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ static iBool isSystemDarkMode_ = iFalse; static iBool isPhone_ = iFalse; +static UIViewController *viewController_(iWindow *window) { + SDL_SysWMinfo wm; + SDL_VERSION(&wm.version); + if (SDL_GetWindowWMInfo(window->win, &wm)) { + return wm.info.uikit.window.rootViewController; + } + iAssert(false); + return NULL; +} + +@interface KeyboardObserver : NSObject +-(void)keyboardOnScreen:(NSNotification *)notification; +@end + +@implementation KeyboardObserver +-(void)keyboardOnScreen:(NSNotification *)notification { + NSDictionary *info = notification.userInfo; + NSValue *value = info[UIKeyboardFrameEndUserInfoKey]; + CGRect rawFrame = [value CGRectValue]; + UIView *view = [viewController_(get_Window()) view]; + CGRect keyboardFrame = [view convertRect:rawFrame fromView:nil]; +// NSLog(@"keyboardFrame: %@", NSStringFromCGRect(keyboardFrame)); + iWindow *window = get_Window(); + const iInt2 rootSize = rootSize_Window(window); + const int keyTop = keyboardFrame.origin.y * window->pixelRatio; + setKeyboardHeight_Window(window, rootSize.y - keyTop); +} + +-(void)keyboardOffScreen:(NSNotification *)notification { + setKeyboardHeight_Window(get_Window(), 0); +} +@end + static void enableMouse_(iBool yes) { SDL_EventState(SDL_MOUSEBUTTONDOWN, yes); SDL_EventState(SDL_MOUSEMOTION, yes); SDL_EventState(SDL_MOUSEBUTTONUP, yes); } +KeyboardObserver *keyObs_; + void setupApplication_iOS(void) { enableMouse_(iFalse); NSString *deviceModel = [[UIDevice currentDevice] model]; if ([deviceModel isEqualToString:@"iPhone"]) { isPhone_ = iTrue; } -} - -static UIViewController *viewController_(iWindow *window) { - SDL_SysWMinfo wm; - SDL_VERSION(&wm.version); - if (SDL_GetWindowWMInfo(window->win, &wm)) { - return wm.info.uikit.window.rootViewController; - } - iAssert(false); - return NULL; + keyObs_ = [[KeyboardObserver alloc] init]; + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + [center addObserver:keyObs_ + selector:@selector(keyboardOnScreen:) + name:UIKeyboardWillShowNotification + object:nil]; + [center addObserver:keyObs_ + selector:@selector(keyboardOffScreen:) + name:UIKeyboardWillHideNotification + object:nil]; } static iBool isDarkMode_(iWindow *window) { @@ -71,13 +106,15 @@ void safeAreaInsets_iOS(float *left, float *top, float *right, float *bottom) { UIViewController *ctl = viewController_(window); if (@available(iOS 11.0, *)) { const UIEdgeInsets safe = ctl.view.safeAreaInsets; - *left = safe.left * window->pixelRatio; - *top = safe.top * window->pixelRatio; - *right = safe.right * window->pixelRatio; - *bottom = safe.bottom * window->pixelRatio; + if (left) *left = safe.left * window->pixelRatio; + if (top) *top = safe.top * window->pixelRatio; + if (right) *right = safe.right * window->pixelRatio; + if (bottom) *bottom = safe.bottom * window->pixelRatio; } else { - // Fallback on earlier versions - *left = *top = *right = *bottom = 0.0f; + if (left) *left = 0.0f; + if (top) *top = 0.0f; + if (right) *right = 0.0f; + if (bottom) *bottom = 0.0f; } } -- cgit v1.2.3