第一个ios应用(4)

 为用户的姓名添加一个属性

用户的姓名由一个字符串保存着,首先要为该字符串声明一个属性,这样你的代码才能引用它。请将此声明添加到视图控制器的头文件中(即 HelloWorldViewController.h)。

属性声明是一个指令,它会告诉编译器如何为变量生成存取方法(Access method),例如这里的用来保存用户姓名的变量。(完成添加属性声明之后,你会学到什么是存取方法。)

在本教程中,你无需对故事板文件进行任何改动。接下来的代码比较多,为了给自己腾出必要的工作空间,可以点按 View 按钮中的实用工具按钮关闭实用工具区域(或者点选 View > Utilities > Hide Utilities)。

如何为用户的姓名添加属性声明…

  1. 在工程导航栏中点选 HelloWorldViewController.h
  2. 在 @end 语句之前,为字符串添加一个 @property 语句。
    属性声明语句应该是这样的:@property (copy, nonatomic) NSString *userName;你可以将这行代码拷贝并粘贴到编辑器面板中,也可以手动输入。如果你要手动输入,就能注意到 Xcode 会针对你的输入提供补全建议。比方说你开始输入 @pro… 时 Xcode 就会猜测你可能想要输入 @property,于是就会在这行语句下面显示一个建议面板,如图:inline_suggestion如果该建议是正确的(如上图的例子),则可以按回车键接受之。

    在你继续输入代码时,Xcode 也许会提供一系列建议让你挑选。比如在你输入 NSSt… 的时候,Xcode 可能会显示类似图中的补全建议:

    completion_list

    当 Xcode 显示补全列表时,按回车键就可以接受当前高亮显示的那一个语句了。如果高亮显示的并非你所需的语句(比如上图中的例子),可以按方向键在列表中选择合适的项目。

要完成 userName 属性的实现,你还需要让编译器合成相应的存取方法。存取方法是用来读取或设置对象属性的值的方法(有时,存取方法也被称作“getter”和“setter”)。

Xcode 会产生一个警告,提示你必须合成相应的存取方法。在活动查看器里会显示一个黄色的警告符号:

warning

此时,你已经知道 Xcode 的警告是什么,所以不必查看警告的详细信息。若需要查看警告信息的具体内容,你可以点按活动查看器中的黄色警告图标,并在问题导航栏中查看细节:

issue_navigator

在本篇教程里,你不会再用到问题导航栏。请点按导航选择条最左边的按钮返回工程导航栏。

接下来,你需要向视图控制器的实现文件(即 HelloWorldViewController.m)中输入代码,让编译器生成存取方法。

如何为用户的姓名属性生成存取方法…

  1. 在工程导航栏中点选 HelloWorldViewController.m
  2. 在 @implementation HelloWorldViewController 这行的下面,输入如下代码:

    @synthesize userName = _userName;

    输入这段代码之后,Xcode 就不会再警告你缺少存取方法了,于是警告图标也就从活动查看器中消失了。

当编译器遇到 @synthesize 指令时,它实际上会自动为你生成下面两个存取方法:

- (NSString *)userName
- (void)setUserName:(NSString *)newUserName

由于在 @synthesize 语句里的 userName 添加了一个下划线,编译器便知道 _userName 是 userName 属性的一个实例变量名称。而你之前没有为名为 _userName 的实例变量进行声明,这段代码就会向编译器请求为它也生成存取方法。

注意:编译器生成存取方法只会在已编译的代码中进行,而不会改动你的源代码文件。

 实现 changeGreeting: 方法

在上一个章节“对视图进行调整”里,你配置了 Hello 按钮的动作,在用户轻敲按钮时它便给视图控制器发送一个 changeGreeting: 消息。为了响应此消息,你会让视图控制器在标签上显示一段文字,包含用户刚刚输入的内容。具体而言,changeGreeting: 方法应该:

  1. 从文本框取回字符串,并将视图控制器的 userName 属性值设置为这个字符串。
  2. 根据 userName 属性创建一个新字符串,并将其显示在标签上。

如何实现 changeGreeting: 方法…

  1. 在工程导航栏中点选 HelloWorldViewController.m。你可能要移动到文件末尾才会看到 Xcode 为你添加的 changeGreeting: 存根实现。
  2. 将 changeGreeting: 方法的存根实现补全,请输入如下代码:

    - (IBAction)changeGreeting:(id)sender {

     

    self.userName = self.textField.text;

     

    NSString *nameString = self.userName;
    if ([nameString length] == 0) {
    nameString = @"World";
    }
    NSString *greeting = [[NSString alloc] initWithFormat:@"Hello, %@!", nameString];
    self.label.text = greeting;
    }

     

在 changeGreeting: 方法中有好几个有趣的地方:

  • self.userName = self.textField.text; 从文本框取回文字,并将视图控制器的 userName 属性值设置为该文字。
    在本篇教程中,你可能不会在其他地方用到存有用户姓名的这个字符串,但仍然需要明白它的作用:它是非常简单的一个模型对象,由视图控制器管理。通常情况下控制器会在自己的模型对象中保存关于应用数据的信息,该数据信息不应该被保存在用户界面元素中,例如 HelloWorld 的文本框。
  • NSString *nameString = self.userName; 会创建一个新的变量(类型为 NSString)并将它的值设为视图控制器 userName 属性的值。
  • @”World” 是一个字符串常量,由一个 NSString 类的实例来表示。如果用户运行应用时没有输入任何文字(即满足 [nameString length] == 0 这个条件),nameString 就会包含字符串“World”。
  • initWithFormat: 方法是由 Foundation 框架提供给你的。它根据你提供的格式化字符串的格式创建一个新的字符串(这一点和 C 语言中的 printf 函数很相近,你也许对它比较熟悉)。
    在格式化字符串中,%@ 代表字符串对象的占位符。双引号中的其他字符则会原封不动地显示在屏幕上。

将视图控制器配置为文本框的委托

如果你构建并运行应用,你应该会发现点按按钮时标签显示“Hello World!”字样。可是当你点选了文本框并输入一些文字时,则会发现仍然无法通过点按 Done 来收起键盘。

在一个 iOS 应用中,一旦能够接受文字输入的 UI 元素成为 first responder 就会自动调出键盘。反过来,该元素失去 first responder 状态时键盘就会自动收起。(请回忆一下 first responder 是什么:它是在若干事件中第一个接收通知的对象,例如轻敲文本框就会呼出键盘。)虽然不能直接从你的应用给键盘发送消息,但你可以通过改变文字输入 UI 元素的 first responder 状态来呼出和收起键盘。

而 UITextFieldDelegate 协议是由 UIKit 框架定义的,其中包含了一个 textFieldShouldReturn: 方法,它在用户轻敲回车键(无论回车键的标题被改成什么)是被文本框调用。因为我们已经将视图控制器设为了文本框的委托(在上一章节“对视图进行调整”),你可以通过实现这个方法来强制文本框失去 first responder 状态,给它发送一个 resignFirstResponder 消息即可,通过这个方式就能收起键盘。

注意:协议从根本上讲就是一系列方法的集合。如果某个类遵守(或采用了)某个协议,它也就承诺一定会实现协议中规定的所有方法。(协议也可以包含可选方法。)委托协议指定了对象可能发送给委托的所有消息。

如何配置文本框的委托 HelloWorldViewController …

  1. 在工程导航栏中点选 HelloWorldViewController.m
  2. 实现 textFieldShouldReturn: 方法。
    这个方法会让文本框失去 first responder 状态。实现的代码如下:

    - (BOOL)textFieldShouldReturn:(UITextField *)theTextField {
        if (theTextField == self.textField) {
            [theTextField resignFirstResponder];
        }
        return YES;
    }

    在本应用中,并非一定要包含 theTextField == self.textField 这个检查语句,因为只有一个文本框。不过这个模式非常值得反复使用,因为在某些情况下某个对象可能会成为类型相同的多个对象的委托,你就需要严格区分它们了。

  3. 在工程导航栏中点选 HelloWorldViewController.h
  4. 在 @interface 行的结尾添加 <UITextFieldDelegate>
    你的接口声明应该是这样的:

    @interface HelloWorldViewController : UIViewController <UITextFieldDelegate>

    这段声明指定了你的 HelloWorldViewController 类要采用 UITextFieldDelegate 协议。

最终测试应用

构建并运行应用吧。这一次,所有功能应该都已达到我们的预期效果。在 iOS 模拟器中,输入完你的姓名后点按 Done 按钮来收起键盘,然后点按 Hello 按钮在标签里显示“Hello, 你的姓名!”。

如果应用还是没能按照预期效果工作,你就需要排查一下问题了。下一章节“故障排除以及代码检查”里将介绍可能出错的几个地方。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值