Xcode 提供了对象库,您可以将库中的对象添加到串联图文件。其中的一些对象属于视图中的用户界面元素,例如按钮和文本栏。其他对象为高级对象,例如视图控制器和手势识别器。
“Hello World View Controller”场景已经包含了一个视图。现在需要添加一个按钮、一个标签和一个文本栏。然后,在这些元素和视图控制器类之间建立连接,以便元素提供您想要的行为。
将对象库中的用户界面 (UI) 元素拖移到画布上的视图中,来添加用户界面元素。UI 元素添加到视图后,可以适度移动它们的位置和调整大小。
在添加文本栏、标签和按钮 UI 元素,并对布局做出建议的修改后,您的项目看起来应该是这样的:
您可能注意到,当您将文本栏、标签和按钮添加到背景视图时,Xcode 在名为 Constraints 的大纲视图中插入了项目。Cocoa Touch 具有一个自动布局系统,让您定义用户界面元素的布局约束。这些约束定义用户界面元素之间的关系,当其他视图的大小改变或设备摆放方向改变时,该关系影响各界面元素如何改变其位置和几何形状。现在不要改变您添加到用户界面的视图的默认约束。
您还可以对文本栏进行一些修改,使文本栏的行为符合用户的期望。首先,因为用户要输入自己的姓名,您可以确保 iOS 对用户键入的每个英文单词的首字母实施大写。其次,还可以确保与文本栏相关联的键盘配置为输入姓名(而不是数字),并且键盘显示“Done”按钮。
这些更改所遵循的原则是:因为在设计时,您已知道文本栏将包含何种类型的信息,您可以配置文本栏使它运行时的外观和行为符合用户的任务。这些配置都可以在“Attributes”检查器中修改。
在 Simulator 中运行应用程序,以确定所添加的 UI 元素外观正如所期望的样子。如果点按“Hello”按钮,该按钮应该高亮显示;如果在文本栏内点按,键盘应该出现。不过,这时按钮没有任何功能,标签还是空的,而且键盘出现后无法使它消失。要添加此功能,需要在 UI 元素和视图控制器之间进行适当的连接。下面将说明如何建立连接。
注:因为只是在 Simulator 中(而不是在设备上)运行应用程序,所以是通过点按来激活控制,而不是用手轻按的方式。
当用户激活一个 UI 元素时,该元素可以向知道如何执行相应操作方法的对象发送一则操作消息,例如“将此联系人添加到用户的联系人列表”。这种互动是目标-操作机制的一部分,该机制是另一种 Cocoa Touch 设计模式。
在本教程中,当用户轻按“Hello”按钮时,您想要按钮发送一则“更改问候语”的消息(操作)给视图控制器(目标)。视图控制器通过更改其管理的字符串(即模型对象)来响应此消息。然后,视图控制器更新在标签中显示的文本,以反映模型对象值的变动。
使用 Xcode,您可以将操作添加到 UI 元素,并设置其相应的操作方法。方法是按住 Control 键并将画布上的元素拖移到源文件中的合适位置(通常是类扩展在视图控制器的实现文件中)。串联图将您通过这种方式创建的连接归档存储下来。稍后,应用程序载入串联图时,会恢复这些连接。
按住 Control 键将“Hello”按钮拖移到 HelloWorldViewController.m
文件中的类扩展,并配置生成的操作后,您完成了两件事情:通过 Xcode 将合适的代码添加到了视图控制器类中(在 HelloWorldViewController.m
中),并在按钮和视图控制器之间创建了连接。具体来说,Xcode 做了以下事情:
在 HelloWorldViewController.m
中,将以下操作方法声明添加到了类扩展:
- (IBAction)changeGreeting:(id)sender; |
并将以下的存根方法添加到了实现区域:
- (IBAction)changeGreeting:(id)sender { |
} |
注:IBAction
是一个特殊关键词,用于告诉 Xcode 将一个方法作为目标-操作连接的操作部分来处理。IBAction
被定义为 void
。
操作方法中的 sender
参数指向发送操作消息的对象(在本教程中,发送对象为按钮)。
它在按钮和视图控制器之间创建了连接。
接下来,您要在视图控制器和剩余的两个 UI 元素(即标签和文本栏)之间创建连接。
Outlet 描述了两个对象之间的连接。当您想要一个对象(例如视图控制器)和它包含的对象(例如文本栏)进行通讯时,须将被包含的对象指定为 outlet。应用程序运行时,会恢复在 Xcode 中创建的 outlet,从而使对象在运行时可以互相通讯。
在本教程中,您想要视图控制器从文本栏获取用户的文本,然后将文本显示在标签上。为确保视图控制器可以和这些对象通讯,您在它们之间创建 outlet 连接。
为文本栏和标签添加 outlet 的步骤与添加按钮操作的步骤非常相似。开始之前,请确定主串联图文件仍然显示在画布上,而 HelloWorldViewController.m
在辅助编辑器中保持打开。
通过为文本栏添加 outlet,您完成了两件事情:在这个过程中:
Xcode 将合适的代码添加到了视图控制器类的实现文件 (HelloWorldViewController.m
)。
具体来说,Xcode 将以下声明添加到了类扩展:
@property (weak, nonatomic) IBOutlet UITextField *textField; |
注:IBOutlet
是一个特殊关键词,仅用于告诉 Xcode 将对象作为 outlet 处理。它实际上的定义为什么都不是,因此在编译时不起作用。
Xcode 在视图控制器和文本栏之间建立了连接。
通过在视图控制器和文本栏之间建立连接,用户输入的文本可以传递给视图控制器。和处理 changeGreeting:
方法声明一样,Xcode 在文本栏声明的左边显示带有填充的圆圈,以表示已经建立连接。
注:较早版本的 Xcode 使用按住 Control 键拖移的方式将 @synthesize
指令添加到您所声明的每个属性的实现块。因为编译器自动合成存取方法,所以这些指令是不必要的。您可以放心地将它们全部删除。
现在为标签添加 outlet 并配置连接。在视图控制器和标签之间建立连接,会让视图控制器以字符串(该字符串包含用户输入的文本)来更新标签。完成此任务的步骤与为文本栏添加 outlet 的步骤相同,只不过在配置时要做适当修改。(确定 HelloWorldViewController.m
仍然显示在辅助编辑器中。)
到此为止,您一共创建了三种到视图控制器的连接:
按钮的操作连接
文本栏的 Outlet 连接
标签的 Outlet 连接
您可以在“Connections”检查器中验证这些连接。
在“Connections”检查器中,Xcode 显示了所选对象(在本例中为视图控制器)的连接。在工作区窗口中,您看到的应该是这样的:
您会发现,在视图控制器和其视图之间,除了您创建的三个连接之外,还有一个连接。Xcode 提供了视图控制器和其视图之间的默认连接;您不必用任何方式访问它。
您还需要在应用程序中建立另一个连接:您需要将文本栏连接到您指定的委托对象上。在本教程中,您将视图控制器用作文本栏的委托。
您需要为文本栏指定一个委托对象。这是因为当用户轻按键盘中的“Done”按钮时,文本栏发送消息给它的委托(前面提到过委托是代表另一个对象的对象)。在后面的步骤中,您将使用与此消息相关联的方法让键盘消失。
确定串联图文件已在画布上打开。如果未打开,则在项目导航器中选择 MainStoryboard.storyboard
。
iOS 操作系统提供了许多功能,让应用程序可供所有用户使用,包括有视觉障碍、听觉障碍和身体残疾的用户。让应用程序具有辅助功能,也就让应用程序接触到了数以百万计原本不能够使用它的用户。
Apple 的创新性读屏技术 VoiceOver 是一个重要的辅助功能。使用 VoiceOver,用户可以在不看屏幕的情况下导航和控制应用程序的各部分。通过触摸用户界面中的控制或其他对象,用户可以知道他们的位置、可以执行的操作以及执行某些操作后将发生什么。
您可以将一些辅助功能属性添加到用户界面中的任何视图。这些属性包括视图的当前值(例如文本栏中的文本)、其标签、提示以及很多特征。就 HelloWorld 应用程序而言,您将要给文本栏添加一则提示。
注:您所添加的任何辅助功能文本都应该本地化。要了解如何将辅助功能文本本地化,请参阅“应用程序设计”中的“将您的应用程序国际化”。
点按“Run”以测试您的应用程序。
在您点按“Hello”按钮时,应该看到它高亮显示。您还应该发现,如果在文本栏中点按,键盘会出现,您可以输入文本。然而还没有办法让键盘消失。要让键盘消失,您必须实施相关的委托方法。下一章会教您如何做。现在请退出 Simulator。
当您在画布上的视图控制器与辅助编辑器中实现文件(即 HelloWorldViewController.m
)里的类扩展之间建立适当的连接时,也就更新了实现文件以支持 Outlet 和操作。
您不必使用 Xcode 自动添加代码(即通过按住 Control 键从画布拖移到源文件来建立连接时)的功能。而是可以自行编写类扩展的属性和方法声明,或公共属性和方法声明的头文件,然后就像建立文本栏的委托那样进行连接。然而通常情况下,Xcode 做得越多,您犯错的机会就越少,需要键入的内容也会越少。