Fixed bug 2212 - SDL_SetTextInputRect has no effect on iOS
authorSam Lantinga <slouken@libsdl.org>
Mon, 11 Nov 2013 20:51:19 -0800
changeset 7962e4d2f3375868
parent 7961 c629882e0a81
child 7963 f06bbd9cd708
Fixed bug 2212 - SDL_SetTextInputRect has no effect on iOS

philhassey

Overview: While SDL_SetTextInputRect works perfectly to move my window out of the way of the virtual keyboard using SDL2/Android, on iOS this function has no effect.

Steps to Reproduce: Call SDL_SetTextInputRect with a rect near the bottom of the screen before calling SDL_StartTextInput.

Actual Results: The iOS virtual keyboard is displayed after calling SDL_StartTextInput, but the screen is not shifted to reveal the TextInputRect region.

Expected Results: The screen should be shifted to reveal the TextInputRect region (like with SDL2/Android.)

This patch implements SDL_SetTextInputRect for uikit/iOS.

It sets up notification handlers to respond to changes in the display of the keyboard. These handlers then change the frame of the view so it is moved out of the way of the keyboard as per SetTextInputRect.
src/video/uikit/SDL_uikitvideo.m
src/video/uikit/SDL_uikitview.h
src/video/uikit/SDL_uikitview.m
     1.1 --- a/src/video/uikit/SDL_uikitvideo.m	Mon Nov 11 20:42:59 2013 -0800
     1.2 +++ b/src/video/uikit/SDL_uikitvideo.m	Mon Nov 11 20:51:19 2013 -0800
     1.3 @@ -89,6 +89,7 @@
     1.4      device->ShowScreenKeyboard = UIKit_ShowScreenKeyboard;
     1.5      device->HideScreenKeyboard = UIKit_HideScreenKeyboard;
     1.6      device->IsScreenKeyboardShown = UIKit_IsScreenKeyboardShown;
     1.7 +    device->SetTextInputRect = UIKit_SetTextInputRect;
     1.8  #endif
     1.9  
    1.10      /* OpenGL (ES) functions */
     2.1 --- a/src/video/uikit/SDL_uikitview.h	Mon Nov 11 20:42:59 2013 -0800
     2.2 +++ b/src/video/uikit/SDL_uikitview.h	Mon Nov 11 20:51:19 2013 -0800
     2.3 @@ -45,6 +45,8 @@
     2.4  #if SDL_IPHONE_KEYBOARD
     2.5      UITextField *textField;
     2.6      BOOL keyboardVisible;
     2.7 +    SDL_Rect textInputRect;
     2.8 +    int keyboardHeight;
     2.9  #endif
    2.10  
    2.11  @public
    2.12 @@ -60,11 +62,14 @@
    2.13  - (void)hideKeyboard;
    2.14  - (void)initializeKeyboard;
    2.15  @property (readonly) BOOL keyboardVisible;
    2.16 +@property (nonatomic,assign) SDL_Rect textInputRect;
    2.17 +@property (nonatomic,assign) int keyboardHeight;
    2.18  
    2.19  SDL_bool UIKit_HasScreenKeyboardSupport(_THIS);
    2.20  void UIKit_ShowScreenKeyboard(_THIS, SDL_Window *window);
    2.21  void UIKit_HideScreenKeyboard(_THIS, SDL_Window *window);
    2.22  SDL_bool UIKit_IsScreenKeyboardShown(_THIS, SDL_Window *window);
    2.23 +void UIKit_SetTextInputRect(_THIS, SDL_Rect *rect);
    2.24  
    2.25  #endif
    2.26  
     3.1 --- a/src/video/uikit/SDL_uikitview.m	Mon Nov 11 20:42:59 2013 -0800
     3.2 +++ b/src/video/uikit/SDL_uikitview.m	Mon Nov 11 20:51:19 2013 -0800
     3.3 @@ -35,6 +35,8 @@
     3.4  #include "SDL_uikitmodes.h"
     3.5  #include "SDL_uikitwindow.h"
     3.6  
     3.7 +void _uikit_keyboard_init() ;
     3.8 +
     3.9  @implementation SDL_uikitview
    3.10  
    3.11  - (void)dealloc
    3.12 @@ -197,6 +199,9 @@
    3.13  */
    3.14  #if SDL_IPHONE_KEYBOARD
    3.15  
    3.16 +@synthesize textInputRect = textInputRect;
    3.17 +@synthesize keyboardHeight = keyboardHeight;
    3.18 +
    3.19  /* Is the iPhone virtual keyboard visible onscreen? */
    3.20  - (BOOL)keyboardVisible
    3.21  {
    3.22 @@ -225,6 +230,8 @@
    3.23      /* add the UITextField (hidden) to our view */
    3.24      [self addSubview: textField];
    3.25      [textField release];
    3.26 +    
    3.27 +    _uikit_keyboard_init();
    3.28  }
    3.29  
    3.30  /* reveal onscreen virtual keyboard */
    3.31 @@ -352,6 +359,103 @@
    3.32      return view.keyboardVisible;
    3.33  }
    3.34  
    3.35 +
    3.36 +void _uikit_keyboard_update() {
    3.37 +    SDL_Window *window = SDL_GetFocusWindow();
    3.38 +    if (!window) { return; }
    3.39 +    SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
    3.40 +    if (!data) { return; }
    3.41 +    SDL_uikitview *view = data->view;
    3.42 +    if (!view) { return; }
    3.43 +    
    3.44 +    SDL_Rect r = view.textInputRect;
    3.45 +    int height = view.keyboardHeight;
    3.46 +    int offsetx = 0;
    3.47 +    int offsety = 0;
    3.48 +    if (height) {
    3.49 +        int sw,sh;
    3.50 +        SDL_GetWindowSize(window,&sw,&sh);
    3.51 +        int bottom = (r.y + r.h);
    3.52 +        int kbottom = sh - height;
    3.53 +        if (kbottom < bottom) {
    3.54 +            offsety = kbottom-bottom;
    3.55 +        }
    3.56 +    }
    3.57 +    UIInterfaceOrientation ui_orient = [[UIApplication sharedApplication] statusBarOrientation];
    3.58 +    if (ui_orient == UIInterfaceOrientationLandscapeLeft) {
    3.59 +        int tmp = offsetx; offsetx = offsety; offsety = tmp;
    3.60 +    }
    3.61 +    if (ui_orient == UIInterfaceOrientationLandscapeRight) {
    3.62 +        offsety = -offsety;
    3.63 +        int tmp = offsetx; offsetx = offsety; offsety = tmp;
    3.64 +    }
    3.65 +    if (ui_orient == UIInterfaceOrientationPortraitUpsideDown) {
    3.66 +        offsety = -offsety;
    3.67 +    }
    3.68 +    if ([[UIScreen mainScreen] respondsToSelector:@selector(displayLinkWithTarget:selector:)]) {
    3.69 +        float scale = [UIScreen mainScreen].scale;
    3.70 +        offsetx /= scale;
    3.71 +        offsety /= scale;
    3.72 +    }
    3.73 +    view.frame = CGRectMake(offsetx,offsety,view.frame.size.width,view.frame.size.height);
    3.74 +}
    3.75 +
    3.76 +void _uikit_keyboard_set_height(int height) {
    3.77 +    SDL_uikitview *view = getWindowView(SDL_GetFocusWindow());
    3.78 +    if (view == nil) {
    3.79 +        return ;
    3.80 +    }
    3.81 +    
    3.82 +    view.keyboardHeight = height;
    3.83 +    _uikit_keyboard_update();
    3.84 +}
    3.85 +
    3.86 +void _uikit_keyboard_init() {
    3.87 +    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    3.88 +    NSOperationQueue *queue = [NSOperationQueue mainQueue];
    3.89 +    [center addObserverForName:UIKeyboardWillShowNotification
    3.90 +                        object:nil
    3.91 +                         queue:queue
    3.92 +                    usingBlock:^(NSNotification *notification) {
    3.93 +                        int height = 0;
    3.94 +                        CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
    3.95 +                        height = keyboardSize.height;
    3.96 +                        UIInterfaceOrientation ui_orient = [[UIApplication sharedApplication] statusBarOrientation];
    3.97 +                        if (ui_orient == UIInterfaceOrientationLandscapeRight || ui_orient == UIInterfaceOrientationLandscapeLeft) {
    3.98 +                            height = keyboardSize.width;
    3.99 +                        }
   3.100 +                        if ([[UIScreen mainScreen] respondsToSelector:@selector(displayLinkWithTarget:selector:)]) {
   3.101 +                            height *= [UIScreen mainScreen].scale;
   3.102 +                        }
   3.103 +                        _uikit_keyboard_set_height(height);
   3.104 +                    }
   3.105 +     ];
   3.106 +    [center addObserverForName:UIKeyboardDidHideNotification
   3.107 +                        object:nil
   3.108 +                         queue:queue
   3.109 +                    usingBlock:^(NSNotification *notification) {
   3.110 +                        _uikit_keyboard_set_height(0);
   3.111 +                    }
   3.112 +     ];
   3.113 +}
   3.114 +
   3.115 +void
   3.116 +UIKit_SetTextInputRect(_THIS, SDL_Rect *rect)
   3.117 +{
   3.118 +    if (!rect) {
   3.119 +        SDL_InvalidParamError("rect");
   3.120 +        return;
   3.121 +    }
   3.122 +    
   3.123 +    SDL_uikitview *view = getWindowView(SDL_GetFocusWindow());
   3.124 +    if (view == nil) {
   3.125 +        return ;
   3.126 +    }
   3.127 +
   3.128 +    view.textInputRect = *rect;
   3.129 +}
   3.130 +
   3.131 +
   3.132  #endif /* SDL_IPHONE_KEYBOARD */
   3.133  
   3.134  #endif /* SDL_VIDEO_DRIVER_UIKIT */