首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

iOS 鍵盤無法收起問題:textFieldShouldReturn 失效的排查與終極解決方案

     編輯:程式設計綜合問答

現象

實現 `UITextFieldDelegate` 的 `textFieldShouldReturn:` 方法,調用 `[textField resignFirstResponder]` 但鍵盤不收起。

常見原因排查清單

原因檢查方法解決
Delegate 未設置斷點確認 `textField.delegate == self``textField.delegate = self;` 在 `viewDidLoad` 或 XIB/Storyboard 綁定
返回鍵類型非 Default屬性檢查器 `Return Key` 非 `Default` (如 `Next`, `Search`)設置為 `Default` 或在代碼中 `textField.returnKeyType = UIReturnKeyDefault;`
文本框非 First Responder調用時 `textField.isFirstResponder == NO`確保在編輯狀態下調用,或先 `[textField becomeFirstResponder]`
父視圖攔截觸摸父視圖有 `UITapGestureRecognizer` 且 `cancelsTouchesInView = YES`設置 `cancelsTouchesInView = NO` 或在手勢中調用 `view.endEditing(true)`
輸入視圖被自定義 InputView 替換`textField.inputView != nil`自定義輸入視圖需自行實現收起邏輯
文本框被移除/隱藏`textField.superview == nil` 或 `hidden = YES`收起鍵盤前確保視圖層級正常

終極解決方案:一行代碼強制收起所有鍵盤

當Delegate方法不可靠或場景複雜 (多文本框、嵌套視圖控制器) 時,使用 `UIApplication` 全局收起:


// Objective-C
[[[UIApplication sharedApplication] keyWindow] endEditing:YES];

// Swift
UIApplication.shared.keyWindow?.endEditing(true)
// 或 iOS 15+ 推薦
view.window?.endEditing(true) // 當前視圖層級窗口

原理解析

  • `endEditing:` 會遍歷窗口層級所有視圖,調用 `resignFirstResponder`。
  • 參數 `YES`/`true` 表示強制收起,即使有驗證邏輯也會忽略。
  • 不依賴特定文本框的 Delegate,適用於任何場景 (導航欄按鈕、背景點擊、鍵盤工具欄 Done 鍵等)。

最佳實踐模式


// 基類 UIViewController 分類
@implementation UIViewController (KeyboardDismiss)

- (void)addTapToDismissKeyboard {
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
    tap.cancelsTouchesInView = NO; // 不攔截其他控件點擊
    [self.view addGestureRecognizer:tap];
}

- (void)dismissKeyboard {
    [self.view endEditing:YES]; // 推薦:視圖層級收起,比 keyWindow 範圍更精確
}

@end

// 使用
- (void)viewDidLoad {
    [super viewDidLoad];
    [self addTapToDismissKeyboard];
}

Swift 版本


extension UIViewController {
    func addTapToDismissKeyboard() {
        let tap = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))
        tap.cancelsTouchesInView = false
        view.addGestureRecognizer(tap)
    }
    
    @objc func dismissKeyboard() {
        view.endEditing(true)
    }
}

總結

  • 優先排查 Delegate 設置、Return Key 類型、First Responder 狀態。
  • 通用收起:**`view.endEditing(true)`** (視圖級) 或 **`UIApplication.shared.keyWindow?.endEditing(true)`** (全局級)。
  • 添加背景點擊手勢收起是標配交互體驗。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved