瀏覽代碼

Fixed delayed text entry for OTP codes on iOS (thanks @pipiwoaini!)

Fixes https://github.com/libsdl-org/SDL/issues/13717
Sam Lantinga 5 天之前
父節點
當前提交
113c7e8a58
共有 1 個文件被更改,包括 18 次插入15 次删除
  1. 18 15
      src/video/uikit/SDL_uikitviewcontroller.m

+ 18 - 15
src/video/uikit/SDL_uikitviewcontroller.m

@@ -79,6 +79,7 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
     BOOL rotatingOrientation;
     NSString *committedText;
     NSString *obligateForBackspace;
+    BOOL isOTPMode;
 #endif
 }
 
@@ -280,6 +281,7 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
 
     textField.hidden = YES;
     textFieldFocused = NO;
+    isOTPMode = NO;
 
     NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
 #ifndef SDL_PLATFORM_TVOS
@@ -477,6 +479,10 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
     if (SDL_TextInputActive(window)) {
         [textField becomeFirstResponder];
     }
+
+    isOTPMode =
+        (SDL_GetTextInputType(props) == SDL_TEXTINPUT_TYPE_NUMBER_PASSWORD_HIDDEN) ||
+        (SDL_GetTextInputType(props) == SDL_TEXTINPUT_TYPE_NUMBER_PASSWORD_VISIBLE);
 }
 
 /* requests the SDL text field to become focused and accept text input.
@@ -490,6 +496,12 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
         return true;
     }
 
+    if (isOTPMode) {
+        if (textField.text.length == 64 && [textField.text isEqualToString:[@"" stringByPaddingToLength:64 withString:@" " startingAtIndex:0]]) {
+            textField.text = @"";
+            committedText  = @"";
+        }
+    }
     return [textField becomeFirstResponder];
 }
 
@@ -554,14 +566,6 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
 
 - (void)textFieldTextDidChange:(NSNotification *)notification
 {
-    // When opening a password manager overlay to select a password and have it auto-filled,
-    // text input becomes stopped as a result of the keyboard being hidden or the text field losing focus.
-    // As a workaround, ensure text input is activated on any changes to the text field.
-    bool startTextInputMomentarily = !SDL_TextInputActive(window);
-
-    if (startTextInputMomentarily)
-        SDL_StartTextInput(window);
-
     if (textField.markedTextRange == nil) {
         NSUInteger compareLength = SDL_min(textField.text.length, committedText.length);
         NSUInteger matchLength;
@@ -596,9 +600,6 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
         }
         committedText = textField.text;
     }
-
-    if (startTextInputMomentarily)
-        SDL_StopTextInput(window);
 }
 
 - (void)updateKeyboard
@@ -643,8 +644,8 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
 // UITextFieldDelegate method.  Invoked when user types something.
 - (BOOL)textField:(UITextField *)_textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
 {
-    if (textField.markedTextRange == nil) {
-        if ([string length] == 0 && textField.text.length < 16) {
+    if (!isOTPMode) {
+        if (textField.markedTextRange == nil && textField.text.length < 16) {
             [self resetTextState];
         }
     }
@@ -664,8 +665,10 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
 
 - (void)resetTextState
 {
-    textField.text = obligateForBackspace;
-    committedText = textField.text;
+    if (!isOTPMode) {
+        textField.text = obligateForBackspace;
+        committedText = textField.text;
+    }
 }
 
 #endif