diff --git a/src/video/uikit/SDL_uikitvideo.m b/src/video/uikit/SDL_uikitvideo.m index 4866de9785..d492178b81 100644 --- a/src/video/uikit/SDL_uikitvideo.m +++ b/src/video/uikit/SDL_uikitvideo.m @@ -97,8 +97,8 @@ static SDL_VideoDevice *UIKit_CreateDevice(void) #ifdef SDL_IPHONE_KEYBOARD device->HasScreenKeyboardSupport = UIKit_HasScreenKeyboardSupport; - device->ShowScreenKeyboard = UIKit_ShowScreenKeyboard; - device->HideScreenKeyboard = UIKit_HideScreenKeyboard; + device->StartTextInput = UIKit_StartTextInput; + device->StopTextInput = UIKit_StopTextInput; device->IsScreenKeyboardShown = UIKit_IsScreenKeyboardShown; device->UpdateTextInputArea = UIKit_UpdateTextInputArea; #endif diff --git a/src/video/uikit/SDL_uikitviewcontroller.h b/src/video/uikit/SDL_uikitviewcontroller.h index b66258c1f0..dd22e780c7 100644 --- a/src/video/uikit/SDL_uikitviewcontroller.h +++ b/src/video/uikit/SDL_uikitviewcontroller.h @@ -69,8 +69,8 @@ #endif #ifdef SDL_IPHONE_KEYBOARD -- (void)showKeyboard; -- (void)hideKeyboard; +- (bool)startTextInput; +- (bool)stopTextInput; - (void)initKeyboard; - (void)deinitKeyboard; @@ -79,7 +79,7 @@ - (void)updateKeyboard; -@property(nonatomic, assign, getter=isKeyboardVisible) BOOL keyboardVisible; +@property(nonatomic, assign, getter=isTextFieldFocused) BOOL textFieldFocused; @property(nonatomic, assign) SDL_Rect textInputRect; @property(nonatomic, assign) int keyboardHeight; #endif @@ -88,8 +88,8 @@ #ifdef SDL_IPHONE_KEYBOARD bool UIKit_HasScreenKeyboardSupport(SDL_VideoDevice *_this); -void UIKit_ShowScreenKeyboard(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID props); -void UIKit_HideScreenKeyboard(SDL_VideoDevice *_this, SDL_Window *window); +bool UIKit_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID props); +bool UIKit_StopTextInput(SDL_VideoDevice *_this, SDL_Window *window); bool UIKit_IsScreenKeyboardShown(SDL_VideoDevice *_this, SDL_Window *window); bool UIKit_UpdateTextInputArea(SDL_VideoDevice *_this, SDL_Window *window); #endif diff --git a/src/video/uikit/SDL_uikitviewcontroller.m b/src/video/uikit/SDL_uikitviewcontroller.m index 3c3cae8555..832ee33ecb 100644 --- a/src/video/uikit/SDL_uikitviewcontroller.m +++ b/src/video/uikit/SDL_uikitviewcontroller.m @@ -80,7 +80,6 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char #ifdef SDL_IPHONE_KEYBOARD SDLUITextField *textField; - BOOL showingKeyboard; BOOL hidingKeyboard; BOOL rotatingOrientation; NSString *committedText; @@ -97,7 +96,6 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char #ifdef SDL_IPHONE_KEYBOARD [self initKeyboard]; - showingKeyboard = NO; hidingKeyboard = NO; rotatingOrientation = NO; #endif @@ -264,7 +262,7 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char @synthesize textInputRect; @synthesize keyboardHeight; -@synthesize keyboardVisible; +@synthesize textFieldFocused; // Set ourselves up as a UITextFieldDelegate - (void)initKeyboard @@ -277,7 +275,7 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char committedText = textField.text; textField.hidden = YES; - keyboardVisible = NO; + textFieldFocused = NO; NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; #ifndef SDL_PLATFORM_TVOS @@ -285,10 +283,6 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; - [center addObserver:self - selector:@selector(keyboardDidShow:) - name:UIKeyboardDidShowNotification - object:nil]; [center addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification @@ -343,8 +337,10 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char [view addSubview:textField]; - if (keyboardVisible) { - [self showKeyboard]; + if (textFieldFocused) { + /* startTextInput has been called before the text field was added to the view, + * call it again for the text field to actually become first responder. */ + [self startTextInput]; } } @@ -367,9 +363,6 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char [center removeObserver:self name:UIKeyboardWillShowNotification object:nil]; - [center removeObserver:self - name:UIKeyboardDidShowNotification - object:nil]; [center removeObserver:self name:UIKeyboardWillHideNotification object:nil]; @@ -382,7 +375,7 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char object:nil]; } -- (void)setKeyboardProperties:(SDL_PropertiesID) props +- (void)setTextFieldProperties:(SDL_PropertiesID) props { textField.secureTextEntry = NO; @@ -479,43 +472,36 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char } } -// reveal onscreen virtual keyboard -- (void)showKeyboard +/* requests the SDL text field to become focused and accept text input. + * also shows the onscreen virtual keyboard if no hardware keyboard is attached. */ +- (bool)startTextInput { - if (keyboardVisible) { - return; + textFieldFocused = YES; + if (!textField.window) { + /* textField has not been added to the view yet, + * we will try again when that happens. */ + return true; } - keyboardVisible = YES; - if (textField.window) { - showingKeyboard = YES; - [textField becomeFirstResponder]; - } + return [textField becomeFirstResponder]; } -// hide onscreen virtual keyboard -- (void)hideKeyboard +/* requests the SDL text field to lose focus and stop accepting text input. + * also hides the onscreen virtual keyboard if no hardware keyboard is attached. */ +- (bool)stopTextInput { - if (!keyboardVisible) { - return; + textFieldFocused = NO; + if (!textField.window) { + /* textField has not been added to the view yet, + * we will try again when that happens. */ + return true; } - keyboardVisible = NO; - if (textField.window) { - hidingKeyboard = YES; - [textField resignFirstResponder]; - } + return [textField resignFirstResponder]; } - (void)keyboardWillShow:(NSNotification *)notification { - BOOL shouldStartTextInput = NO; - - if (!SDL_TextInputActive(window) && !hidingKeyboard && !rotatingOrientation) { - shouldStartTextInput = YES; - } - - showingKeyboard = YES; #ifndef SDL_PLATFORM_TVOS CGRect kbrect = [[notification userInfo][UIKeyboardFrameEndUserInfoKey] CGRectValue]; @@ -526,28 +512,29 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char [self setKeyboardHeight:(int)kbrect.size.height]; #endif - if (shouldStartTextInput) { + /* A keyboard hide transition has been interrupted with a show (keyboardWillHide has been called but keyboardDidHide didn't). + * since text input was stopped by the hide, we have to start it again. */ + if (hidingKeyboard) { SDL_StartTextInput(window); + hidingKeyboard = NO; } } -- (void)keyboardDidShow:(NSNotification *)notification -{ - showingKeyboard = NO; -} - - (void)keyboardWillHide:(NSNotification *)notification { - BOOL shouldStopTextInput = NO; - - if (SDL_TextInputActive(window) && !showingKeyboard && !rotatingOrientation) { - shouldStopTextInput = YES; - } - hidingKeyboard = YES; [self setKeyboardHeight:0]; - if (shouldStopTextInput) { + /* When the user dismisses the software keyboard by the "hide" button in the bottom right corner, + * we want to reflect that on SDL_TextInputActive by calling SDL_StopTextInput...on certain conditions */ + if (SDL_TextInputActive(window) + /* keyboardWillHide gets called when a hardware keyboard is attached, + * keep text input state active if hiding while there is a hardware keyboard. + * if the hardware keyboard gets detached, the software keyboard will appear anyway. */ + && !SDL_HasKeyboard() + /* When the device changes orientation, a sequence of hide and show transitions are triggered. + * keep text input state active in this case. */ + && !rotatingOrientation) { SDL_StopTextInput(window); } } @@ -630,7 +617,6 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char - (void)setKeyboardHeight:(int)height { - keyboardVisible = height > 0; keyboardHeight = height; [self updateKeyboard]; } @@ -651,7 +637,7 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char - (BOOL)textFieldShouldReturn:(UITextField *)_textField { SDL_SendKeyboardKeyAutoRelease(0, SDL_SCANCODE_RETURN); - if (keyboardVisible && + if (textFieldFocused && SDL_GetHintBoolean(SDL_HINT_RETURN_KEY_HIDES_IME, false)) { SDL_StopTextInput(window); } @@ -682,20 +668,20 @@ bool UIKit_HasScreenKeyboardSupport(SDL_VideoDevice *_this) return true; } -void UIKit_ShowScreenKeyboard(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID props) +bool UIKit_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID props) { @autoreleasepool { SDL_uikitviewcontroller *vc = GetWindowViewController(window); - [vc setKeyboardProperties:props]; - [vc showKeyboard]; + [vc setTextFieldProperties:props]; + return [vc startTextInput]; } } -void UIKit_HideScreenKeyboard(SDL_VideoDevice *_this, SDL_Window *window) +bool UIKit_StopTextInput(SDL_VideoDevice *_this, SDL_Window *window) { @autoreleasepool { SDL_uikitviewcontroller *vc = GetWindowViewController(window); - [vc hideKeyboard]; + return [vc stopTextInput]; } } @@ -704,7 +690,7 @@ bool UIKit_IsScreenKeyboardShown(SDL_VideoDevice *_this, SDL_Window *window) @autoreleasepool { SDL_uikitviewcontroller *vc = GetWindowViewController(window); if (vc != nil) { - return vc.keyboardVisible; + return vc.textFieldFocused; } return false; } @@ -717,7 +703,7 @@ bool UIKit_UpdateTextInputArea(SDL_VideoDevice *_this, SDL_Window *window) if (vc != nil) { vc.textInputRect = window->text_input_rect; - if (vc.keyboardVisible) { + if (vc.textFieldFocused) { [vc updateKeyboard]; } }