diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-03-06 14:44:17 +0200 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-03-06 14:44:17 +0200 |
commit | eddc86b7b0795fe7c7a82d86f6ee151ccdca229f (patch) | |
tree | 7eea8ac70aa37d068adfc2d06dc066367a10572c /src/ios.m | |
parent | 7fa64b95d0c63b243f50b23c5551a7e04fe90c30 (diff) |
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.
Diffstat (limited to 'src/ios.m')
-rw-r--r-- | src/ios.m | 69 |
1 files changed, 53 insertions, 16 deletions
@@ -31,28 +31,63 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | |||
31 | static iBool isSystemDarkMode_ = iFalse; | 31 | static iBool isSystemDarkMode_ = iFalse; |
32 | static iBool isPhone_ = iFalse; | 32 | static iBool isPhone_ = iFalse; |
33 | 33 | ||
34 | static UIViewController *viewController_(iWindow *window) { | ||
35 | SDL_SysWMinfo wm; | ||
36 | SDL_VERSION(&wm.version); | ||
37 | if (SDL_GetWindowWMInfo(window->win, &wm)) { | ||
38 | return wm.info.uikit.window.rootViewController; | ||
39 | } | ||
40 | iAssert(false); | ||
41 | return NULL; | ||
42 | } | ||
43 | |||
44 | @interface KeyboardObserver : NSObject | ||
45 | -(void)keyboardOnScreen:(NSNotification *)notification; | ||
46 | @end | ||
47 | |||
48 | @implementation KeyboardObserver | ||
49 | -(void)keyboardOnScreen:(NSNotification *)notification { | ||
50 | NSDictionary *info = notification.userInfo; | ||
51 | NSValue *value = info[UIKeyboardFrameEndUserInfoKey]; | ||
52 | CGRect rawFrame = [value CGRectValue]; | ||
53 | UIView *view = [viewController_(get_Window()) view]; | ||
54 | CGRect keyboardFrame = [view convertRect:rawFrame fromView:nil]; | ||
55 | // NSLog(@"keyboardFrame: %@", NSStringFromCGRect(keyboardFrame)); | ||
56 | iWindow *window = get_Window(); | ||
57 | const iInt2 rootSize = rootSize_Window(window); | ||
58 | const int keyTop = keyboardFrame.origin.y * window->pixelRatio; | ||
59 | setKeyboardHeight_Window(window, rootSize.y - keyTop); | ||
60 | } | ||
61 | |||
62 | -(void)keyboardOffScreen:(NSNotification *)notification { | ||
63 | setKeyboardHeight_Window(get_Window(), 0); | ||
64 | } | ||
65 | @end | ||
66 | |||
34 | static void enableMouse_(iBool yes) { | 67 | static void enableMouse_(iBool yes) { |
35 | SDL_EventState(SDL_MOUSEBUTTONDOWN, yes); | 68 | SDL_EventState(SDL_MOUSEBUTTONDOWN, yes); |
36 | SDL_EventState(SDL_MOUSEMOTION, yes); | 69 | SDL_EventState(SDL_MOUSEMOTION, yes); |
37 | SDL_EventState(SDL_MOUSEBUTTONUP, yes); | 70 | SDL_EventState(SDL_MOUSEBUTTONUP, yes); |
38 | } | 71 | } |
39 | 72 | ||
73 | KeyboardObserver *keyObs_; | ||
74 | |||
40 | void setupApplication_iOS(void) { | 75 | void setupApplication_iOS(void) { |
41 | enableMouse_(iFalse); | 76 | enableMouse_(iFalse); |
42 | NSString *deviceModel = [[UIDevice currentDevice] model]; | 77 | NSString *deviceModel = [[UIDevice currentDevice] model]; |
43 | if ([deviceModel isEqualToString:@"iPhone"]) { | 78 | if ([deviceModel isEqualToString:@"iPhone"]) { |
44 | isPhone_ = iTrue; | 79 | isPhone_ = iTrue; |
45 | } | 80 | } |
46 | } | 81 | keyObs_ = [[KeyboardObserver alloc] init]; |
47 | 82 | NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; | |
48 | static UIViewController *viewController_(iWindow *window) { | 83 | [center addObserver:keyObs_ |
49 | SDL_SysWMinfo wm; | 84 | selector:@selector(keyboardOnScreen:) |
50 | SDL_VERSION(&wm.version); | 85 | name:UIKeyboardWillShowNotification |
51 | if (SDL_GetWindowWMInfo(window->win, &wm)) { | 86 | object:nil]; |
52 | return wm.info.uikit.window.rootViewController; | 87 | [center addObserver:keyObs_ |
53 | } | 88 | selector:@selector(keyboardOffScreen:) |
54 | iAssert(false); | 89 | name:UIKeyboardWillHideNotification |
55 | return NULL; | 90 | object:nil]; |
56 | } | 91 | } |
57 | 92 | ||
58 | static iBool isDarkMode_(iWindow *window) { | 93 | static iBool isDarkMode_(iWindow *window) { |
@@ -71,13 +106,15 @@ void safeAreaInsets_iOS(float *left, float *top, float *right, float *bottom) { | |||
71 | UIViewController *ctl = viewController_(window); | 106 | UIViewController *ctl = viewController_(window); |
72 | if (@available(iOS 11.0, *)) { | 107 | if (@available(iOS 11.0, *)) { |
73 | const UIEdgeInsets safe = ctl.view.safeAreaInsets; | 108 | const UIEdgeInsets safe = ctl.view.safeAreaInsets; |
74 | *left = safe.left * window->pixelRatio; | 109 | if (left) *left = safe.left * window->pixelRatio; |
75 | *top = safe.top * window->pixelRatio; | 110 | if (top) *top = safe.top * window->pixelRatio; |
76 | *right = safe.right * window->pixelRatio; | 111 | if (right) *right = safe.right * window->pixelRatio; |
77 | *bottom = safe.bottom * window->pixelRatio; | 112 | if (bottom) *bottom = safe.bottom * window->pixelRatio; |
78 | } else { | 113 | } else { |
79 | // Fallback on earlier versions | 114 | if (left) *left = 0.0f; |
80 | *left = *top = *right = *bottom = 0.0f; | 115 | if (top) *top = 0.0f; |
116 | if (right) *right = 0.0f; | ||
117 | if (bottom) *bottom = 0.0f; | ||
81 | } | 118 | } |
82 | } | 119 | } |
83 | 120 | ||