註冊 `UITextFieldTextDidBeginEditingNotification`,多個文本框共用一個處理方法,如何知道是哪個 `textField` 觸發?
// 註冊時 object 為 nil,表示接收所有文本框通知
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(textFieldDidBegin:)
name:UITextFieldTextDidBeginEditingNotification
object:nil];
- (void)textFieldDidBegin:(NSNotification *)notification {
UITextField *textField = notification.object; // 關鍵:發送者就是文本框本身
if (textField == self.textField1) {
// 處理 textField1
} else if (textField == self.textField2) {
// 處理 textField2
}
}
// 僅接收 textField1 的通知
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(textField1DidBegin:)
name:UITextFieldTextDidBeginEditingNotification
object:self.textField1];
- (void)textField1DidBegin:(NSNotification *)notification {
// 這裡確定是 textField1
UITextField *tf = notification.object;
}
// 設置 delegate
self.textField1.delegate = self;
self.textField2.delegate = self;
// 實現 UITextFieldDelegate
- (void)textFieldDidBeginEditing:(UITextField *)textField {
// 直接獲得觸發的 textField,無需通知中心
if (textField == self.textField1) { ... }
}
| 方案 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| Notification + object=nil | 鬆耦合、可跨層級傳遞 | 需手動判斷、易忘記移除觀察者 | 非直接關聯對象間通信 |
| Notification + object=textField | 自動過濾、方法專一 | 每個文本框需單獨註冊 | 少量固定文本框 |
| Delegate | 類型安全、編譯期檢查、生命周期自動管理 | 強耦合、單播 | **文本框輸入控制首選** |
// NotificationCenter
NotificationCenter.default.addObserver(self,
selector: #selector(textFieldDidBegin(_:)),
name: UITextField.textDidBeginEditingNotification,
object: nil)
@objc func textFieldDidBegin(_ notification: Notification) {
guard let textField = notification.object as? UITextField else { return }
// 判斷 textField
}
// Delegate (推薦)
textField1.delegate = self
textField2.delegate = self
func textFieldDidBeginEditing(_ textField: UITextField) {
// 直接判斷
}
通知機制中 `notification.object` 就是發送通知的 `UITextField` 實例。但**文本框輸入控制首選 Delegate 模式**,更安全、更符合 Apple 設計規範。