之前章节介绍过目标-动作(Target-Action)设计模式。目标-动作是UIKit中常用的设计模式之一,第1章在编写Quiz应用时,曾经针对UIButton对象使用过这种设计模式。目标-动作的工作方式为:当某个特定的事件发生时(例如按下按钮),发生事件的一方会向指定的目标对象发送一个之前设定好的动作消息。
在目标-动作中,针对不同的事件,需要创建不同的动作消息。UIButton对象的事件比较简单,通常只需要处理点击事件;相反,像UITextField这类事件复杂的对象,Apple使用委托设计模式。UITextField对象具有一个委托属性,通过为UITextField对象设置委托,UITextField对象会在发生事件时向委托发送相应的消息,由委托处理该事件。例如,对于编辑UITextField对象文本内容的事件,有以下两个对应的委托方法:
- (void)textFieldDidEndEditing:(UITextField *)textField;
- (void)textFieldDidBeginEditing:(UITextField *)textField;
还有一类带有返回值的委托方法,用于从委托中查询需要的信息,例如,
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField;
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField;
- (BOOL)textFieldShouldClear:(UITextField *)textField;
- (BOOL)textFieldShouldReturn:(UITextField *)textField;
注意,在委托方法中,通常应该将对象自身作为第一个参数。多个对象可能具有相同的委托,当委托收到消息时,需要根据该参数判断发送该消息的对象。例如,如果某个视图控制器中包含多个UITextField对象,它们的委托都是该视图控制器,那么视图控制器就需要根据textField参数获取相应的UITextField对象并执行不同的操作。
下面就将UITextField对象所位于的视图控制器——BNRHypnosisViewController设置为它的委托,并实现textFieldShouldReturn:委托方法,当用户点击Done按钮时,UITextField对象就会调用该方法。
打开BNRHypnosisViewController.m,修改loadView方法,将UITextField对象的委托属性设置为BNRHypnosisViewController自身。
- (void)loadView
{
CGRect frame = [UIScreen mainScreen].bounds;
BNRHypnosisView *backgroundView =
[[BNRHypnosisView alloc] initWithFrame:frame];
CGRect textFieldRect = CGRectMake(40, 70, 240, 30);
UITextField *textField = [[UITextField alloc] initWithFrame:textFieldRect];
// 设置UITextField对象的边框样式,便于查看它在屏幕上的位置
textField.borderStyle = UITextBorderStyleRoundedRect;
textField.placeholder = @"Hypnotize me";
textField.returnKeyType = UIReturnKeyDone;
// 这里Xcode会提示一处警告信息,下一节将介绍原因并消除该警告
textField.delegate = self;
[backgroundView addSubview:textField];
self.view = backgroundView;
}
textFieldShouldReturn:只有一个参数,就是用户点击换行键的相应UITextField对象。目前,应用只会向控制台输出UITextField对象的文本内容。
接下来在BNRHypnosisViewController.m中实现textFieldShouldReturn:方法。建议读者从书中复制方法声明,确保方法与UITextField对象的委托方法完全一致,否则UITextField对象不会调用该方法。
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
NSLog(@"%@", textField.text);
return YES;
}
构建并运行应用,在UITextField对象中输入一些文字,然后点击Done,这时控制台中会输出这些文字。
请注意,BNRHypnosisViewController不需要实现UITextField对象的所有委托方法,UITextField对象会在运行时检查委托是否实现了某个方法,如果没有实现,UITextField对象就不会调用该方法。