Refactor iOS text input activation to better work with hardware keyboards
This commit is contained in:
parent
72895a6994
commit
5d09656afa
3 changed files with 54 additions and 68 deletions
|
@ -97,8 +97,8 @@ static SDL_VideoDevice *UIKit_CreateDevice(void)
|
||||||
|
|
||||||
#ifdef SDL_IPHONE_KEYBOARD
|
#ifdef SDL_IPHONE_KEYBOARD
|
||||||
device->HasScreenKeyboardSupport = UIKit_HasScreenKeyboardSupport;
|
device->HasScreenKeyboardSupport = UIKit_HasScreenKeyboardSupport;
|
||||||
device->ShowScreenKeyboard = UIKit_ShowScreenKeyboard;
|
device->StartTextInput = UIKit_StartTextInput;
|
||||||
device->HideScreenKeyboard = UIKit_HideScreenKeyboard;
|
device->StopTextInput = UIKit_StopTextInput;
|
||||||
device->IsScreenKeyboardShown = UIKit_IsScreenKeyboardShown;
|
device->IsScreenKeyboardShown = UIKit_IsScreenKeyboardShown;
|
||||||
device->UpdateTextInputArea = UIKit_UpdateTextInputArea;
|
device->UpdateTextInputArea = UIKit_UpdateTextInputArea;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -69,8 +69,8 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SDL_IPHONE_KEYBOARD
|
#ifdef SDL_IPHONE_KEYBOARD
|
||||||
- (void)showKeyboard;
|
- (bool)startTextInput;
|
||||||
- (void)hideKeyboard;
|
- (bool)stopTextInput;
|
||||||
- (void)initKeyboard;
|
- (void)initKeyboard;
|
||||||
- (void)deinitKeyboard;
|
- (void)deinitKeyboard;
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@
|
||||||
|
|
||||||
- (void)updateKeyboard;
|
- (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) SDL_Rect textInputRect;
|
||||||
@property(nonatomic, assign) int keyboardHeight;
|
@property(nonatomic, assign) int keyboardHeight;
|
||||||
#endif
|
#endif
|
||||||
|
@ -88,8 +88,8 @@
|
||||||
|
|
||||||
#ifdef SDL_IPHONE_KEYBOARD
|
#ifdef SDL_IPHONE_KEYBOARD
|
||||||
bool UIKit_HasScreenKeyboardSupport(SDL_VideoDevice *_this);
|
bool UIKit_HasScreenKeyboardSupport(SDL_VideoDevice *_this);
|
||||||
void UIKit_ShowScreenKeyboard(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID props);
|
bool UIKit_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID props);
|
||||||
void UIKit_HideScreenKeyboard(SDL_VideoDevice *_this, SDL_Window *window);
|
bool UIKit_StopTextInput(SDL_VideoDevice *_this, SDL_Window *window);
|
||||||
bool UIKit_IsScreenKeyboardShown(SDL_VideoDevice *_this, SDL_Window *window);
|
bool UIKit_IsScreenKeyboardShown(SDL_VideoDevice *_this, SDL_Window *window);
|
||||||
bool UIKit_UpdateTextInputArea(SDL_VideoDevice *_this, SDL_Window *window);
|
bool UIKit_UpdateTextInputArea(SDL_VideoDevice *_this, SDL_Window *window);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -80,7 +80,6 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
|
||||||
|
|
||||||
#ifdef SDL_IPHONE_KEYBOARD
|
#ifdef SDL_IPHONE_KEYBOARD
|
||||||
SDLUITextField *textField;
|
SDLUITextField *textField;
|
||||||
BOOL showingKeyboard;
|
|
||||||
BOOL hidingKeyboard;
|
BOOL hidingKeyboard;
|
||||||
BOOL rotatingOrientation;
|
BOOL rotatingOrientation;
|
||||||
NSString *committedText;
|
NSString *committedText;
|
||||||
|
@ -97,7 +96,6 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
|
||||||
|
|
||||||
#ifdef SDL_IPHONE_KEYBOARD
|
#ifdef SDL_IPHONE_KEYBOARD
|
||||||
[self initKeyboard];
|
[self initKeyboard];
|
||||||
showingKeyboard = NO;
|
|
||||||
hidingKeyboard = NO;
|
hidingKeyboard = NO;
|
||||||
rotatingOrientation = NO;
|
rotatingOrientation = NO;
|
||||||
#endif
|
#endif
|
||||||
|
@ -264,7 +262,7 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
|
||||||
|
|
||||||
@synthesize textInputRect;
|
@synthesize textInputRect;
|
||||||
@synthesize keyboardHeight;
|
@synthesize keyboardHeight;
|
||||||
@synthesize keyboardVisible;
|
@synthesize textFieldFocused;
|
||||||
|
|
||||||
// Set ourselves up as a UITextFieldDelegate
|
// Set ourselves up as a UITextFieldDelegate
|
||||||
- (void)initKeyboard
|
- (void)initKeyboard
|
||||||
|
@ -277,7 +275,7 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
|
||||||
committedText = textField.text;
|
committedText = textField.text;
|
||||||
|
|
||||||
textField.hidden = YES;
|
textField.hidden = YES;
|
||||||
keyboardVisible = NO;
|
textFieldFocused = NO;
|
||||||
|
|
||||||
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
|
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
|
||||||
#ifndef SDL_PLATFORM_TVOS
|
#ifndef SDL_PLATFORM_TVOS
|
||||||
|
@ -285,10 +283,6 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
|
||||||
selector:@selector(keyboardWillShow:)
|
selector:@selector(keyboardWillShow:)
|
||||||
name:UIKeyboardWillShowNotification
|
name:UIKeyboardWillShowNotification
|
||||||
object:nil];
|
object:nil];
|
||||||
[center addObserver:self
|
|
||||||
selector:@selector(keyboardDidShow:)
|
|
||||||
name:UIKeyboardDidShowNotification
|
|
||||||
object:nil];
|
|
||||||
[center addObserver:self
|
[center addObserver:self
|
||||||
selector:@selector(keyboardWillHide:)
|
selector:@selector(keyboardWillHide:)
|
||||||
name:UIKeyboardWillHideNotification
|
name:UIKeyboardWillHideNotification
|
||||||
|
@ -343,8 +337,10 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
|
||||||
|
|
||||||
[view addSubview:textField];
|
[view addSubview:textField];
|
||||||
|
|
||||||
if (keyboardVisible) {
|
if (textFieldFocused) {
|
||||||
[self showKeyboard];
|
/* 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
|
[center removeObserver:self
|
||||||
name:UIKeyboardWillShowNotification
|
name:UIKeyboardWillShowNotification
|
||||||
object:nil];
|
object:nil];
|
||||||
[center removeObserver:self
|
|
||||||
name:UIKeyboardDidShowNotification
|
|
||||||
object:nil];
|
|
||||||
[center removeObserver:self
|
[center removeObserver:self
|
||||||
name:UIKeyboardWillHideNotification
|
name:UIKeyboardWillHideNotification
|
||||||
object:nil];
|
object:nil];
|
||||||
|
@ -382,7 +375,7 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
|
||||||
object:nil];
|
object:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setKeyboardProperties:(SDL_PropertiesID) props
|
- (void)setTextFieldProperties:(SDL_PropertiesID) props
|
||||||
{
|
{
|
||||||
textField.secureTextEntry = NO;
|
textField.secureTextEntry = NO;
|
||||||
|
|
||||||
|
@ -479,43 +472,36 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// reveal onscreen virtual keyboard
|
/* requests the SDL text field to become focused and accept text input.
|
||||||
- (void)showKeyboard
|
* also shows the onscreen virtual keyboard if no hardware keyboard is attached. */
|
||||||
|
- (bool)startTextInput
|
||||||
{
|
{
|
||||||
if (keyboardVisible) {
|
textFieldFocused = YES;
|
||||||
return;
|
if (!textField.window) {
|
||||||
|
/* textField has not been added to the view yet,
|
||||||
|
* we will try again when that happens. */
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
keyboardVisible = YES;
|
return [textField becomeFirstResponder];
|
||||||
if (textField.window) {
|
|
||||||
showingKeyboard = YES;
|
|
||||||
[textField becomeFirstResponder];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// hide onscreen virtual keyboard
|
/* requests the SDL text field to lose focus and stop accepting text input.
|
||||||
- (void)hideKeyboard
|
* also hides the onscreen virtual keyboard if no hardware keyboard is attached. */
|
||||||
|
- (bool)stopTextInput
|
||||||
{
|
{
|
||||||
if (!keyboardVisible) {
|
textFieldFocused = NO;
|
||||||
return;
|
if (!textField.window) {
|
||||||
|
/* textField has not been added to the view yet,
|
||||||
|
* we will try again when that happens. */
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
keyboardVisible = NO;
|
return [textField resignFirstResponder];
|
||||||
if (textField.window) {
|
|
||||||
hidingKeyboard = YES;
|
|
||||||
[textField resignFirstResponder];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)keyboardWillShow:(NSNotification *)notification
|
- (void)keyboardWillShow:(NSNotification *)notification
|
||||||
{
|
{
|
||||||
BOOL shouldStartTextInput = NO;
|
|
||||||
|
|
||||||
if (!SDL_TextInputActive(window) && !hidingKeyboard && !rotatingOrientation) {
|
|
||||||
shouldStartTextInput = YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
showingKeyboard = YES;
|
|
||||||
#ifndef SDL_PLATFORM_TVOS
|
#ifndef SDL_PLATFORM_TVOS
|
||||||
CGRect kbrect = [[notification userInfo][UIKeyboardFrameEndUserInfoKey] CGRectValue];
|
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];
|
[self setKeyboardHeight:(int)kbrect.size.height];
|
||||||
#endif
|
#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);
|
SDL_StartTextInput(window);
|
||||||
|
hidingKeyboard = NO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)keyboardDidShow:(NSNotification *)notification
|
|
||||||
{
|
|
||||||
showingKeyboard = NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)keyboardWillHide:(NSNotification *)notification
|
- (void)keyboardWillHide:(NSNotification *)notification
|
||||||
{
|
{
|
||||||
BOOL shouldStopTextInput = NO;
|
|
||||||
|
|
||||||
if (SDL_TextInputActive(window) && !showingKeyboard && !rotatingOrientation) {
|
|
||||||
shouldStopTextInput = YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
hidingKeyboard = YES;
|
hidingKeyboard = YES;
|
||||||
[self setKeyboardHeight:0];
|
[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);
|
SDL_StopTextInput(window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -630,7 +617,6 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
|
||||||
|
|
||||||
- (void)setKeyboardHeight:(int)height
|
- (void)setKeyboardHeight:(int)height
|
||||||
{
|
{
|
||||||
keyboardVisible = height > 0;
|
|
||||||
keyboardHeight = height;
|
keyboardHeight = height;
|
||||||
[self updateKeyboard];
|
[self updateKeyboard];
|
||||||
}
|
}
|
||||||
|
@ -651,7 +637,7 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
|
||||||
- (BOOL)textFieldShouldReturn:(UITextField *)_textField
|
- (BOOL)textFieldShouldReturn:(UITextField *)_textField
|
||||||
{
|
{
|
||||||
SDL_SendKeyboardKeyAutoRelease(0, SDL_SCANCODE_RETURN);
|
SDL_SendKeyboardKeyAutoRelease(0, SDL_SCANCODE_RETURN);
|
||||||
if (keyboardVisible &&
|
if (textFieldFocused &&
|
||||||
SDL_GetHintBoolean(SDL_HINT_RETURN_KEY_HIDES_IME, false)) {
|
SDL_GetHintBoolean(SDL_HINT_RETURN_KEY_HIDES_IME, false)) {
|
||||||
SDL_StopTextInput(window);
|
SDL_StopTextInput(window);
|
||||||
}
|
}
|
||||||
|
@ -682,20 +668,20 @@ bool UIKit_HasScreenKeyboardSupport(SDL_VideoDevice *_this)
|
||||||
return true;
|
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 {
|
@autoreleasepool {
|
||||||
SDL_uikitviewcontroller *vc = GetWindowViewController(window);
|
SDL_uikitviewcontroller *vc = GetWindowViewController(window);
|
||||||
[vc setKeyboardProperties:props];
|
[vc setTextFieldProperties:props];
|
||||||
[vc showKeyboard];
|
return [vc startTextInput];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UIKit_HideScreenKeyboard(SDL_VideoDevice *_this, SDL_Window *window)
|
bool UIKit_StopTextInput(SDL_VideoDevice *_this, SDL_Window *window)
|
||||||
{
|
{
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
SDL_uikitviewcontroller *vc = GetWindowViewController(window);
|
SDL_uikitviewcontroller *vc = GetWindowViewController(window);
|
||||||
[vc hideKeyboard];
|
return [vc stopTextInput];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -704,7 +690,7 @@ bool UIKit_IsScreenKeyboardShown(SDL_VideoDevice *_this, SDL_Window *window)
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
SDL_uikitviewcontroller *vc = GetWindowViewController(window);
|
SDL_uikitviewcontroller *vc = GetWindowViewController(window);
|
||||||
if (vc != nil) {
|
if (vc != nil) {
|
||||||
return vc.keyboardVisible;
|
return vc.textFieldFocused;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -717,7 +703,7 @@ bool UIKit_UpdateTextInputArea(SDL_VideoDevice *_this, SDL_Window *window)
|
||||||
if (vc != nil) {
|
if (vc != nil) {
|
||||||
vc.textInputRect = window->text_input_rect;
|
vc.textInputRect = window->text_input_rect;
|
||||||
|
|
||||||
if (vc.keyboardVisible) {
|
if (vc.textFieldFocused) {
|
||||||
[vc updateKeyboard];
|
[vc updateKeyboard];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue