You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

登录界面UITextField在API响应后自动弹出键盘问题求助

解决登录后键盘自动弹出的问题

看起来你的问题出在同步网络请求阻塞主线程,加上UI操作的时机不对,导致之前的endEditing:YES没有真正生效,或者请求完成后文本框意外重新获得焦点。我来一步步帮你修复:

问题根源分析

  1. 同步请求阻塞主线程:你使用的[NSURLConnection sendSynchronousRequest:]是同步方法,会卡住主线程。这意味着[self.view endEditing:YES]的UI更新被延迟,甚至在请求完成后,系统可能因为主线程刚恢复,错误地让文本框重新成为第一响应者。
  2. performSelector延迟的副作用:虽然afterDelay:0.01很短,但主线程被同步请求卡住后,这个延迟执行的方法会和键盘收起的操作产生时机冲突。
  3. UIAlertView的交互影响:当用户点击Alert的"Ok"按钮时,如果没有明确控制第一响应者,系统可能自动让之前的文本框重新获取焦点,导致键盘弹出。

解决方案

1. 替换同步请求为异步请求(核心修复)

同步请求是iOS开发的大忌,不仅会导致键盘问题,还会让App在请求期间完全无响应。我们用NSURLSession(苹果推荐的网络API,NSURLConnection已废弃)来实现异步请求:

- (void)API_Login {
    NSString *userEmail = _TXT_email.text;
    NSString *userPWD = _TXT_password.text;
    
    // 主动让文本框放弃第一响应者,确保键盘收起
    [_TXT_email resignFirstResponder];
    [_TXT_password resignFirstResponder];
    
    NSString *post = [NSString stringWithFormat:@"username=%@&password=%@",userEmail,userPWD];
    NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
    NSString *postLength = [NSString stringWithFormat:@"%lu",(unsigned long)[postData length]];
    NSString *urlGetuser =[NSString stringWithFormat:@"%@loginApi",SERVER_URL];
    NSURL *urlProducts=[NSURL URLWithString:urlGetuser];
    
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:urlProducts];
    [request setHTTPMethod:@"POST"];
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
    [request setHTTPBody:postData];
    [request setHTTPShouldHandleCookies:NO];
    
    // 用NSURLSession发起异步请求
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        // 所有UI操作必须回到主线程执行
        dispatch_async(dispatch_get_main_queue(), ^{
            [activityIndicatorView stopAnimating];
            VW_overlay.hidden = YES;
            
            if (data) {
                NSError *jsonError;
                NSMutableDictionary *json_DATA = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError];
                
                if (!jsonError) {
                    NSLog(@"The response %@",json_DATA);
                    if ([[json_DATA valueForKey:@"status"]isEqualToString:@"success"]) {
                        [[NSUserDefaults standardUserDefaults] setValue:[json_DATA valueForKey:@"driver_id"] forKey:@"driver_id"];
                        [[NSUserDefaults standardUserDefaults] synchronize];
                        
                        // 用UIAlertController替代已废弃的UIAlertView(iOS8+推荐)
                        UIAlertController *alert = [UIAlertController alertControllerWithTitle:[json_DATA valueForKey:@"status"] message:[json_DATA valueForKey:@"msg"] preferredStyle:UIAlertControllerStyleAlert];
                        UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                            // 点击Ok后再跳转页面,避免交互干扰
                            [self order_details_page];
                        }];
                        [alert addAction:okAction];
                        [self presentViewController:alert animated:YES completion:nil];
                    } else {
                        UIAlertController *alert = [UIAlertController alertControllerWithTitle:[json_DATA valueForKey:@"status"] message:[json_DATA valueForKey:@"msg"] preferredStyle:UIAlertControllerStyleAlert];
                        UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:nil];
                        [alert addAction:okAction];
                        [self presentViewController:alert animated:YES completion:nil];
                    }
                } else {
                    NSLog(@"JSON解析错误:%@", jsonError);
                    // 可添加解析错误提示
                }
            } else {
                NSLog(@"Error %@\nResponse %@",error,response);
                // 可添加网络错误提示
            }
        });
    }];
    [task resume];
}

2. 调整初始调用逻辑

去掉performSelector:afterDelay,直接调用API_Login,因为异步请求不会阻塞主线程,键盘收起的操作会立即生效:

[self.view endEditing:YES];
VW_overlay.hidden = NO;
[activityIndicatorView startAnimating];
[self API_Login]; // 直接调用,无需延迟

3. 额外保障:跳转页面时再次确认键盘收起

在页面跳转前再执行一次键盘收起操作,彻底避免键盘跟随页面切换弹出:

-(void)order_details_page {
    [self.view endEditing:YES];
    [self performSegueWithIdentifier:@"login_order" sender:self];
}

修复逻辑说明

  • 异步请求不会阻塞主线程,endEditing:YES能立即生效,键盘正常收起。
  • 所有UI操作都在主线程执行,避免线程冲突导致的UI异常。
  • 在Alert的点击回调里触发页面跳转,确保用户交互完成后再执行切换,不会触发文本框重新获取焦点。

内容的提问来源于stack exchange,提问作者Jayasabeen Appukuttan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:56:24