iOS 8开发指南
上QQ阅读APP看书,第一时间看更新

第5章 Xcode InterfaceBuilder界面开发

Interface Builder(IB)是Mac OS X平台下用于设计和测试用户界面(GUI)的应用程序。为了生成GUI,IB并不是必需的,实际上Mac OS X下所有的用户界面元素都可以使用代码直接生成;但是IB能够使开发者简单快捷地开发出符合Mac OS X human-interface guidelines的GUI。通常你只需要通过简单的拖曳(drag-n-drop)操作来构建GUI就可以了。在本章将详细讲解Interface Builder的基本知识,为读者步入本书后面知识的学习打下基础。

5.1 Interface Builder基础

通过使用Interface Builder(IB),可以快速地创建一个应用程序界面。这不仅是一个GUI绘画工具,而且还可以在不编写任何代码的情况下添加应用程序。这样不但可以减少bug,而且缩短了开发周期,并且让整个项目更容易维护。本章的重点是介绍如何在Interface Builder中实现导航,这些内容是我们理解本章其余内容的关键。

5.1.1 Interface Builder的作用

IB向Objective-C开发者提供了包含一系列用户界面对象的工具箱,这些对象包括文本框、数据表格、滚动条和弹出式菜单等控件。IB的工具箱是可扩展的,也就是说,所有开发者都可以开发新的对象,并将其加入IB的工具箱中。

开发者只需要从工具箱中简单地向窗口或菜单中拖曳控件即可完成界面的设计。然后,用连线将控件可以提供的“动作”(Action)、控件对象分别和应用程序代码中对象“方法”(Method)、对象“接口”(Outlet)连接起来,就完成了整个创建工作。与其他图形用户界面设计器,如Microsoft Visual Studio相比,这样的过程减小了MVC模式中控制器和视图两层的耦合,提高了代码质量。

在代码中,使用IBAction标记可以接受动作的方法,使用IBOutlet标记可以接受对象接口。IB将应用程序界面保存为捆绑状态,其中包含了界面对象及其与应用程序的关系。这些对象被序列化为XML文件,扩展名为.nib。在运行应用程序时,对应的NIB对象调入内存,与其应用程序的二进制代码联系起来。与绝大多数其余GUI设计系统不同,IB不是生成代码以在运行时产生界面(如Glade,Codegear的C++ Builder所做的),而是采用与代码无关的机制,通常称为freeze dried。从IB 3.0开始,加入了一种新的文件格式,其扩展名为.xib。这种格式与原有的格式功能相同,但是为单独文件而非捆绑,以便于版本控制系统的运作,以及类似diff的工具的处理。

5.1.2 Interface Builder的新特色

当把Interface Builder集成到Xcode中后,和原来的版本相比主要如下4点不同。

(1)在导航区选择xib文件后,会在编辑区显示xib文件的详细信息。由此可见,Interface Builder和Xcode整合在一起了,如图5-1所示。

图5-1 显示xib文件

(2)在工具栏选择View控制按钮,单击图5-2中最右边的按钮可以调出工具区,如图5-3所示。

图5-2 View控制按钮

图5-3 工具区

在图5-3的工具区中,最上面的按钮分别是如下4个inspector:

Identity;

Attributes;

Size;

Connections。

工具区下面是可以往View中拖的控件。

(3)隐藏导航区。

为了专心设计我们的UI,可以在刚才提到的“View 控制按钮”中单击第一个,这样可以隐藏导航区,如图5-4所示。

图5-4 隐藏导航区

(4)关联方法和变量。

这是一个所见即所得功能,涉及了View:Assistant View,是编辑区的一部分,如图5-5所示。

图5-5 关联方法和变量

此时只需将按钮(或者其他控件)拖到代码指定地方即可。在“拖”时需要按住“Ctrl”键。怎么让Assistant View显示我要对应的.h文件?使用这个View上面的选择栏进行选择。

5.2 Interface Builder采用的方法

通过使用Xcode和Cocoa工具集,可手工编写生成iOS界面的代码,实现实例化界面对象、指定它们出现在屏幕的什么位置、设置对象的属性以及使其可见。例如通过下面的代码,可以在iOS设备屏幕设备的一角中显示文本“Hello Xcode”:

- (BOOL)application:(UIApplication *)application

didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{

self.window=[[UIWindow alloc]

initWithFrame:[[UIScreen mainScreen] bounds]];

// Override point for customization after application launch.

UILabel *myMessage;

UILabel *myUnusedMessage;

myMessage=[[UILabel alloc]

initWithFrame:CGRectMake(30.0,50.0,300.0,50.0)];

myMessage.font=[UIFont systemFontOfSize:48];

myMessage.text=@"Hello Xcode";

myMessage.textColor = [UIColor colorWithPatternImage:

[UIImage imageNamed:@"Background.png"]];

[self.window addSubview:myMessage];

self.window.backgroundColor = [UIColor whiteColor];

[self.window makeKeyAndVisible];

return YES;

}

如果要创建一个包含文本、按钮、图像以及数十个其他控件的界面,会需要编写很多事件。而Interface Builder不是自动生成界面代码,也不是将源代码直接关联到界面元素,而是生成实时的对象,并通过称为连接(connection)的简单关联将其连接到应用程序代码。需要修改应用程序功能的触发方式时,只需修改连接即可。要改变应用程序使用我们创建的对象的方式,只需连接或重新连接即可。

5.3 Interface Builder的故事板

Storyboarding(故事板)是从iOS 5开始新加入的Interface Builder(IB)的功能。其主要功能是在一个窗口中显示整个app用到的所有或者部分的页面,并且可以定义各页面之间的跳转关系,大大增加了IB便利性。

5.3.1 推出的背景

Interface Builder是Xcode开发环境自带的用户图形界面设计工具,通过它可以随心所欲地将控件或对象(Object)拖曳到视图中。这些控件被存储在一个XIB(发音为zib)或NIB文件中。其实XIB文件是一个XML格式的文件,可以通过编辑工具打开并改写这个Xib文件。当编译程序时,这些视图控件被编译成一个NIB文件。

通常,NIB是与ViewController相关联的,很多ViewController都有对应的NIB文件。NIB文件的作用是描述用户界面、初始化界面元素对象。其实,开发者在NIB中所描述的界面和初始化的对象都能够在代码中实现。之所以用Interface Builder来绘制页面,是为了减少那些设置界面属性的重复而枯燥的代码,让开发者能够集中在功能的实现上。

在Xcode 4.2之前,每创建一个视图会生成一个相应的XIB文件。当一个应用有多个视图时,视图之间的跳转管理将变得十分复杂。为了解决这个问题,Storyboard便被推出。

NIB文件无法描述从一个ViewController到另一个ViewController的跳转,这种跳转功能只能靠手写代码的形式来实现。相信很多人都会经常用到如下两个方法。

-presentModalViewController:animated。

-pushViewController:animated。

随着Storyboarding 的出现,使得这种方式成为历史,取而代之的是 Segue [Segwei]。Segue 定义了从一个ViewController 到另一个ViewController的跳转。我们在IB中,已经熟悉如何连接界面元素对象和方法(Action Method)。在Stroyboard中,完全可以通过Segue将ViewController 连接起来,而不再需要手写代码。如果想自定义Segue,也只需写 Segue的实现即可,而无需编写调用的代码,Storyboard 会自动调用。在使用Storyboard机制时,必须严格遵守MVC原则。View与Controller需完全解耦,并且不同的Controller之间也要充分解耦。

在开发iOS 应用程序时,有如下两种创建一个视图(View)的方法。

在Interface Builder中拖曳一个UIView控件:这种方式看似简单,但是会在View之间跳转,所以不便操控。

通过原生代码方式:需要编写的代码工作量巨大,哪怕仅仅创建几个Label,就得手写上百行代码,每个Label 都得设置坐标。为解决以上问题,从iOS 5开始新增了Storyboard 功能。

Storyboard是Xcode 4.2 自带的工具,主要用于iOS 5 以上版本。早期的Interface Builder 所创建的View中,各个View之间是互相独立的,没有相互关联,当一个应用程序有多个View 时,View 之间的跳转很是复杂。为此Apple 为开发者带来了Storyboard,尤其是导航栏和标签栏的应用。Storyboard简化了各个视图之间的切换,并由此简化了管理视图控制器的开发过程,完全可以指定视图的切换顺序,而不用手工编写代码。

Storyboard 能够包含一个程序的所有的ViewController 以及它们之间的连接。在开发应用程序时,可以将UI Flow作为Storyboard 的输入,一个看似完整的UI在Storyboard中唾手可得。故事板可以根据需要包含任意数量的场景,并通过切换(segue)将场景关联起来。然而故事板不仅可以创建视觉效果,还让我们能够创建对象,而无需手工分配或初始化它们。当应用程序在加载故事板文件中的场景时,其描述的对象将被实例化,可以通过代码访问它们。

5.3.2 故事板的文档大纲

为了更加说明问题,我们打开一个演示工程来观察故事板文件的真实面目。双击光盘中本章工程中的文件Empty.storyboard,此时将打开Interface Builder,并在其中显示该故事板文件的骨架。该文件的内容将以可视化方式显示在IB编辑器区域,而在编辑器区域左边的文档大纲(Document Outline)区域,将以层次方式显示其中的场景,如图5-6所示。

图5-6 故事板场景对象

本章演示工程文件只包含了一个场景:View Controller Scene。本书中讲解的创建界面演示工程在大多数情况下都是从单场景故事板开始的,因为它们提供了丰富的空间,让您能够收集用户输入和显示输出。我们将探索多场景故事板。

在View Controller Scene中有如下3个图标:

First Responder(第一响应者);

View Controller(视图控制器);

View(视图)。

其中前两个特殊图标用于表示应用程序中的非界面对象,在我们使用的所有故事板场景中都包含它们。

First Responder:该图标表示用户当前正在与之交互的对象。当用户使用iOS应用程序时,可能有多个对象响应用户的手势或键击。第一响应者是当前与用户交互的对象。例如,当用户在文本框中输入时,该文本框将是第一响应者,直到用户移到其他文本框或控件。

View Controller:该图标表示加载应用程序中的故事板场景并与之交互的对象。场景描述的其他所有对象几乎都是由它实例化的。第6章将更详细地介绍界面和视图控制器之间的关系。

View:该图标是一个UIView实例,表示将被视图控制器加载并显示在iOS设备屏幕中的布局。从本质上说,视图是一种层次结构,这意味着当您在界面中添加控件时,它们将包含在视图中。您甚至可在视图中添加其他视图,以便将控件编组或创建可作为一个整体进行显示或隐藏的界面元素。

通过使用独特的视图控制器名称/标签,还有利于场景命名。Interface Builder自动将场景名设置为视图控制器的名称或标签(如果设置了标签),并加上后缀。例如给视图控制器设置了标签Recipe Listing,场景名将变成Recipe Listing Scene。在本项目中包含一个名为View Controller的通用类,此类负责与场景交互。

在最简单的情况下,视图(UIView)是一个矩形区域,可以包含内容以及响应用户事件(触摸等)。事实上,我们将加入到视图中的所有控件(按钮、文本框等)都是UIView的子类。对于这一点您不用担心,只是您在文档中可能遇到这样的情况,即将按钮和其他界面元素称为子视图,而将包含它们的视图称为父视图。

需要牢记的是,在屏幕上看到的任何东西几乎都可视为“视图”。当创建用户界面时,场景包含的对象将增加。有些用户界面由数十个不同的对象组成,这会导致场景拥挤而变得复杂 。如果项目程序非常复杂,为了方便管理这些复杂的信息,可以采用折叠或展开文档大纲区域的视图层次结构的方式来解决。

5.3.3 文档大纲的区域对象

在故事板中,文档大纲区域显示了表示应用程序中对象的图标,这样可以展现给用户一个漂亮的列表,并且通过这些图标能够以可视化方式引用它们代表的对象。开发人员可以从这些图标拖曳到其他位置或从其他地方拖曳到这些图标,从而创建让应用程序能够工作的连接。假如我们希望一个屏幕控件(如按钮)能够触发代码中的操作。通过从该按钮拖曳到View Controller图标,可将该GUI元素连接到希望它激活的方法,甚至可以将有些对象直接拖放到代码中,这样可以快速地创建一个与该对象交互的变量或方法。

当在Interface Builder中使用对象时,Xcode为我们开发人员提供了很大的灵活性。例如可以在IB编辑器中直接与UI元素交互,也可以与文档大纲区域中表示这些UI元素的图标交互。另外,在编辑器中的视图下方有一个图标栏,所有在用户界面中不可见的对象(如第一响应者和视图控制器)都可在这里找到,如图5-7所示。

图5-7 在编辑器和文档大纲中和对象交互

5.4 创建一个界面

在本节的内容中,将详细讲解如何使用Interface Builder创建界面的方法。在开始之前,需要先创建一个Empty.storyboard文件。

5.4.1 对象库

添加到视图中的任何控件都来自对象库(Object Library),从按钮到图像再到Web内容。可以依次选择Xcode菜单View>Utilities>Show Object Library(Control+Option+Command+3)来打开对象库。如果对象库以前不可见,此时将打开Xcode的Utility区域,并在右下角显示对象库。确保从对象库顶部的下拉列表中选择了Objects,这样将列出所有的选项。

其实在Xcode中有多个库,对象库包含将添加到用户界面中的UI元素,但还有文件模板( File Template)、代码片段(Code Snippet)和多媒体(Media)库。通过单击Library区域上方的图标的操作来显示这些库。如果发现在当前的库中没有显示期望的内容,可单击库上方的立方体图标或再次选择菜单View>Utilities>Show Object Library,如图5-8所示,这样可以确保处于对象库中。

图5-8 打开对象库命令

在单击对象库中的元素并将鼠标指向它时会出现一个弹出框,在其中包含了如何在界面中使用该对象的描述,如图5-9所示。这样我们无需打开Xcode文档,就可以得知UI元素的真实功能。

图5-9 对象库包含大量可添加到视图中的对象

另外,通过使用对象库顶部的视图按钮,可以在列表视图和图标视图之间进行切换。如果只想显示特定的UI元素,可以使用对象列表上方的下拉列表。如果知道对象的名称,但是在列表中找不到它,可以使用对象库底部的过滤文本框快速找到。

5.4.2 将对象加入到视图中

在添加对象时,只需在对象库中单击某一个对象,并将其拖放到视图中就可以将这个对象加入到视图中。例如在对象库中找到标签对象(Label),并将其拖放到编辑器中的视图中央。此时标签将出现在视图中,并显示Label信息。假如双击Label并输入文本“how are you”,这样显示的文本将更新,如图5-10所示。

图5-10 插入了一个Label对象

其实我们可以继续尝试将其他对象(按钮、文本框等)从对象库中拖放到视图,原理和实现方法都是一样。在大多数情况下,对象的外观和行为都符合您的预期。要将对象从视图中删除,可以单击选择它,再按Delete键。另外还可以使用Edit菜单中的选项,在视图间复制并粘贴对象以及在视图内复制对象多次。

5.4.3 使用IB布局工具

通过使用Apple为我们提供的调整布局的工具,我们无需依赖于敏锐的视觉来指定对象在视图中的位置。其中常用的工具如下所示。

1.参考线

当我们在视图中拖曳对象时,将会自动出现蓝色的帮助我们布局的参考线。通过这些蓝色的虚线能够将对象与视图边缘、视图中其他对象的中心,以及标签和对象名中使用的字体的基线对齐。并且当间距接近Apple界面指南要求的值时,参考线将自动出现以指出这一点。也可以手工添加参考线,方法是依次选择菜单Editor>Add Horizontal Guide或Editor> Add Vertical Guide实现。

2.选取手柄

除了可以使用布局参考线外,大多数对象都有选取手柄,可以使用它们沿水平、垂直或这两个方向缩放对象。当对象被选定后在其周围会出现小框,单击并拖曳它们可调整对象的大小,例如图5-11通过一个按钮演示了这一点。

图5-11 大小调整手柄

读者需要注意,在iOS中有一些对象会限制我们如何调整其大小,因为这样可以确保iOS应用程序界面的一致性。

3.对齐

要快速对齐视图中的多个对象,可单击并拖曳出一个覆盖它们的选框,或按住Shift键并单击以选择它们,然后从菜单Editor→Align中选择合适的对齐方式。例如我们将多个按钮拖放到视图中,并将它们放在不同的位置,我们的目标是让它们垂直居中,此时我们可以选择这些按钮,再依次选择菜单Editor>Align>Align Horizontal Centers,如图5-12所示。

图5-12 垂直居中

图5-13显示了对齐后的效果。

图5-13 垂直居中后的效果

另外,我们也可以微调对象在视图中的位置,方法是先选择一个对象,然后再使用箭头键以每次一个像素的方式向上、下、左或右调整其位置。

4.大小检查器

为了控制界面布局,有时需要使用Size Inspector(大小检查器)工具。Size Inspector为我们提供了和大小有关的信息,以及有关位置和对齐方式的信息。要想打开Size Inspector,需要先选择要调整的一个或多个对象,再单击Utility区域顶部的标尺图标,也可以依次选择菜单View>Utilities> Show Size Inspector或按“Option+ Command+5”快捷键组合,打开后的界面效果如图5-14所示。

图5-14 打开Size Inspector后的界面效果

另外,使用该检查器顶部的文本框可以查看对象的大小和位置,还可以通过修改文本框Height/Width和X/Y中的坐标了调整大小和位置。另外,通过单击网格中的黑点(它们用于指定读数对应的部分)可以查看对象特定部分的坐标,如图5-15所示。

图5-15 单击黑点查看特定部分的坐标

注意:在Size&Position部分,有一个下拉列表,可通过它选择Frame Rectangle或Layout Rectangle。这两个设置的方法通常十分相似,但也有细微的差别。具体说明如下所示:

当选择Frame Rectangle时,将准确指出对象在屏幕上占据的区域;

当选择Layout Rectangle时,将考虑对象周围的间距。

使用Size Inspector中的Autosizing可以设置当设备朝向发生变化时,控件如何调整其大小和位置。并且该检查器底部有一个下拉列表,此列表包含了与菜单Editor>Align中的菜单项对应的选项。当选择多个对象后,可以使用该下拉列表指定对齐方式,如图5-16所示。

图5-16 另外一种对齐方式

当在Interface Builder中选择一个对象后,如果按住Option键并移动鼠标,会显示选定对象与当前鼠标指向的对象之间的距离。

5.5 定制界面外观

在iOS应用中,其实最终用户看到的界面不仅仅取决于控件的大小和位置。对于很多对象来说,有数十个不同的属性可供我们进行调整,在调整时可以使用Interface Builder中的工具来达到事半功倍的效果。

5.5.1 使用属性检查器

为了调整界面对象的外观,最常用的方式是通过Attributes Inspector(属性检查器)。要想打开该检查器,可以通过单击Utility区域顶部的滑块图标的方式实现。如果当前Utility区域不可见,可以依次选择菜单View>Utility>Show Attributes Inspector(或“Option+ Command+4”快捷键实现)。

接下来我们通过一个简单演示来说明如何使用它,假设存在一个空工程文件Empty.storyboard,并在该视图中添加了一个文本标签。选择该标签,再打开Attributes Inspector,如图5-17所示。

图5-17 打开AttributesInspector后的界面效果

在“Attributes Inspector”面板的顶部包含了当前选定对象的属性。例如,标签对象Label包括的属性有字体、字号、颜色和对齐方式等。在“Attributes Inspector”面板的底部是继承而来的其他属性,在很多情况下,我们不会修改这些属性,但背景和透明度属性很有用。

5.5.2 设置辅助功能属性

在iOS应用中可以使用专业屏幕阅读器技术Voiceover,此技术它集成了语音合成功能,可以帮助开发人员实现导航应用程序。在使用Voiceover后,当触摸界面元素时会听到有关其用途和用法的简短描述。虽然我们可以免费获得这种功能,但是通过在Interface Builder中配置辅助功能(accessibility)属性,可以提供其他协助。要想访问辅助功能设置,需要打开Identity Inspector(身份检查器),为此可单击Utility区域顶部的窗口图标,也可以依次选择菜单View>Utility>Show Identity Inspector或按下“Option+Command+3”快捷键,如图5-18所示。

图5-18 打开Identity Inspector

在Identity Inspector中,辅助功能选项位于一个独立的部分。在该区域,可以配置如下所示的4组属性。

Accessibility(辅助功能):如果选中它,对象将具有辅助功能。如果创建了只有看到才能使用的自定义控件,则应该禁用这个设置。

Label(标签):一两个简单的单词,用作对象的标签。例如,对于收集用户姓名的文本框,可使用your name。

Hint(提示):有关控件用法的简短描述。仅当标签本身没有提供足够的信息时才需要设置该属性。

Traits(特征):这组复选框用于描述对象的特征——其用途以及当前的状态。

具体界面如图5-19所示。

图5-19 4组属性

注意:为了让应用程序能够供最大的用户群使用,应该尽可能利用辅助功能工具来开发项目。即使像在本章前面使用的文本标签这样的对象,也应配置其特征(traits)属性,以指出它们是静态文本,这可以让用户知道不能与之交互。

5.5.3 测试界面

通过使用Xcode,能够帮助开发人员编写绝大部分的界面代码。这意味着即使该应用程序还未编写好,在创建界面并将其关联到应用程序类后,依然可以在iOS模拟器中运行该应用程序。接下来开始介绍启用辅助功能检查器(Accessibility Inspector)的过程。

如果我们创建了一个支持辅助功能的界面,可能想在iOS模拟器中启用Accessibility Inspector(辅助功能检查器)。此时可启动模拟器,再单击主屏幕(Home)按钮返回主屏幕。单击Setting(设置),并选择General>Accessibility(“通用”>“辅助功能”),然后使用开关启用Accessibility Inspector,如图5-20所示。

图5-20 启用Accessibility Inspector功能

通过使用Accessibility Inspector,能够在模拟器工作空间中添加一个覆盖层,功能是显示我们为界面元素配置的标签、提示和特征。使用该检查器左上角的“×”按钮,可以在关闭和开启模式之间切换。当处于关闭状态时,该检查器折叠成一个小条,而iOS模拟器的行为将恢复正常。在此单击×按钮可重新开启。要禁用Accessibility Inspector,只需再次单击Setting并选择General> Accessibility即可。

5.6 实战演练——将界面连接到代码

经过本章前面内容的学习,已经掌握了创建界面的基本知识。但是如何才能使设计的界面起作用呢?在本节的内容中,将详细讲解将界面连接到代码并让应用程序运行的方法。

5.6.1 打开项目

首先,我们将使用本章Projects文件夹中的项目“lianjie”。打开该文件夹,并双击文件“lianjie.xcworkspace”,这将在Xcode中打开该项目,如图5-21所示。

图5-21 在Xcode中打开项目

加载该项目后,展开项目代码编组(Disconnected),并单击文件MainStoryboard.storyboard,此故事板文件包含该应用程序将把它显示为界面的场景和视图,并且会在Interface Builder编辑器中显示场景,如图5-22所示。

图5-22 显示应用程序的场景和相应的视图

由图5-22所示的效果可知,该界面包含了如下4个交互式元素:

一个按钮栏(分段控件);

一个按钮;

一个输出标签;

一个Web视图(一个集成的Web浏览器组件)。

这些控件将与应用程序代码交互,让用户选择花朵颜色并单击“获取花朵”按钮时,文本标签将显示选择的颜色,并从网站http://www.floraphotographs.com随机取回一朵这种颜色的花朵。假设我们期望的执行结果如图5-23所示。

图5-23 执行效果

但是到目前为止,还没有将界面连接到应用程序代码,因此执行后只是显示一张漂亮的图片。为了让应用程序能够正常运行,需要将创建到应用程序代码中定义的输出口和操作的连接。

5.6.2 输出口和操作

输出口(outlet)是一个通过它可引用对象的变量,假如Interface Builder中创建了一个用于收集用户姓名的文本框,可能想在代码中为它创建一个名为userName的输出口。这样便可以使用该输出口和相应的属性获取或修改该文本框的内容。

操作(action)是代码中的一个方法,在相应的事件发生时调用它。有些对象(如按钮和开关)可在用户与之交互(如触摸屏幕)时通过事件触发操作。通过在代码中定义操作,Interface Builder可使其能够被屏幕对象触发。

我们可以将Interface Builder中的界面元素与输出口或操作相连,这样就可以创建一个连接。为了让应用程序Disconnected能够成功运行,需要创建到如下所示的输出口和操作的连接。

ColorChoice:一个对应于按钮栏的输出口,用于访问用户选择的颜色。

GetFlower:这是一个操作,它从网上获取一幅花朵图像并显示它,然后将标签更新为选择的颜色。

ChoosedColor:对应于标签的输出口,将被getFlower更新以显示选定颜色的名称。

FlowerView:对应于Web视图的输出口,将被getFlower更新以显示获取的花朵图像。

5.6.3 创建到输出口的连接

要想建立从界面元素到输出口的连接,可以先按住Control键,并同时从场景的View Controller图标(它出现在文档大纲区域和视图下方的图标栏中)拖曳到视图中对象的可视化表示或文档大纲区域中的相应图标。读者可以尝试对按钮栏(分段控件)进行这样的操作。在按住Control键的同时,再单击文档大纲区域中的View Controller图标,并将其拖曳到屏幕上的按钮栏。拖曳时将出现一条线,这样让我们能够轻松地指向要连接的对象。

当松开鼠标时会出现一个下拉列表,在其中列出了可供选择的输出口,如图5-24所示。再次选择“选择颜色”。

图5-24 出现一个下拉列表

因为Interface Builder知道什么类型的对象可以连接到给定的输出口,所以只显示适合当前要创建的连接的输出口。对文本“你的颜色”的标签和Web视图重复上述过程,将它们分别连接到输出口chosenColor和flowerView。

在我们这个演示工程中,其核心功能是通过文件 ViewController.m实现的,其主要代码如下所示:

#import "ViewController.h"

@implementation ViewController

@synthesize colorChoice;

@synthesize chosenColor;

@synthesize flowerView;

-(IBAction)getFlower:(id)sender {

NSString *outputHTML;

NSString *color;

NSString *colorVal;

int colorNum;

colorNum=colorChoice.selectedSegmentIndex;

switch (colorNum) {

case 0:

color=@"Red";

colorVal=@"red";

break;

case 1:

color=@"Blue";

colorVal=@"blue";

break;

case 2:

color=@"Yellow";

colorVal=@"yellow";

break;

case 3:

color=@"Green";

colorVal=@"green";

break;

}

chosenColor.text=[[NSString alloc] initWithFormat:@"%@",color];

outputHTML=[[NSString alloc] initWithFormat:@"<body style='margin: 0px; padding:

0px'><img height='1200'

src='http://www.floraphotographs.com/showrandom.php?color= %@'></body>",colorVal];

[flowerView loadHTMLString:outputHTML baseURL:nil];

}

- (void)didReceiveMemoryWarning

{

[super didReceiveMemoryWarning];

}

#pragma mark - View lifecycle

- (void)viewDidLoad

{

[super viewDidLoad];

}

- (void)viewDidUnload

{

[self setFlowerView:nil];

[self setChosenColor:nil];

[self setColorChoice:nil];

[super viewDidUnload];

}

- (void)viewWillAppear:(BOOL)animated

{

[super viewWillAppear:animated];

}

- (void)viewDidAppear:(BOOL)animated

{

[super viewDidAppear:animated];

}

- (void)viewWillDisappear:(BOOL)animated

{

[super viewWillDisappear:animated];

}

- (void)viewDidDisappear:(BOOL)animated

{

[super viewDidDisappear:animated];

}

-

(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrien-t

ation

{

return (interfaceOrientation !=UIInterfaceOrientationPortraitUpsideDown);

}

@end

5.6.4 创建到操作的连接

选择将调用操作的对象,并单击Utility区域顶部的箭头图标以打开Connections Inspector(连接检查器)。另外,也可以选择菜单View>Utilities>Show Connections Inspector(Option+ Command+6)。

Connections Inspector显示了当前对象(这里是按钮)支持的事件列表,如图5-25所示。每个事件旁边都有一个空心圆圈,要将事件连接到代码中的操作,可单击相应的圆圈并将其拖曳到文档大纲区域中的View Controller图标。

图5-25 使用Connections Inspector操作连接

假如要将按钮“送给我花”连接到方法getFlower,可选择该按钮并打开Connections Inspector (Option+Command+6)。然后将Touch Up Inside事件旁边的圆圈拖曳到场景的View Controller图标,再松开鼠标。当系统询问时选择操作getFlower,如图5-26所示。

图5-26 选择希望界面元素触发的操作

在建立连接后检查器会自动更新,以显示事件及其调用的操作。如果单击了其他对象,ConnectionsInspector将显示该对象到输出口和操作的连接。到此为止,已经将界面连接到了支持它的代码。单击Xcode工具栏中的Run按钮,在iOS模拟器或iOS设备中便可以生成并运行该应用程序,执行效果如图5-27所示。

图5-27 执行效果

5.7 实战演练——在界面中实现按钮的交互(基于Swift实现)

在本节的内容中,将通过一个具体实例的实现过程,详细讲解使用Xcode 6创建UI界面的过程。在本实例的界面中插入了一个按钮,并且通过Swift编程实现了和这个按钮的交互操作。

(1)打开Xcode 6,单击“Create a new…”选项,如图5-28所示。

图5-28 单击“Create a new…”选项

(2)在弹出的界面中选择“Cocoa Application”,如图5-29所示。

图5-29 选择“Cocoa Application”

(3)在新界面中输入工程信息,设置工程名为“buttonuse”,设置Language选项为“Swift”,如图5-30所示。

图5-30 设置工程名和语言类型

(4)在新界面中选择保存工程的位置,如图5-31所示。

图5-31 选择保存工程的位置

最终在Xcode 6中会生成一个自动创建的工程文件,如图5-32所示。

图5-32 Xcode 6生成的工程文件

(5)开始添加控件,打开MainMenu.xib并拖放一个Push Button,如图5-33所示。

图5-33 拖放一个Push Button

(6)开始添加响应代码,打开文件AppDelegate.swift,添加Push Button对应的变量:

@IBOutlet var pushButton: NSButton

然后给pushButton添加一个响应事件,也就是一个Action ,这一功能在函数application Did Finish Launching中编写实现:

func applicationDidFinishLaunching(aNotification: NSNotification?) {

// Insert code here to initialize your application

pushButton.action = Selector("pushButtonClick")

}

将下面的代码添加为pushButtonClick的内容:

func pushButtonClick(){

print("Hello , welcome to http://www.sollyu.com")

}

(7)开始绑定Push Button,将pushButton绑定到界面上去。首先打开MainMenu.xib,并选择AppDelegete,如图5-34所示。

图5-34 选择App Delegete

(8)然后在右边的实用工具选择这个右箭头的面板,可以看到里面有一个pushButton,如图5-35所示。

图5-35 拖曳pushButton后面的“+”

(9)拖曳pushButton后面的“+”到界面的按钮上,如图5-36所示。

图5-36 拖曳pushButton后面的“+”

拖曳完成后的效果如图5-37所示。

图5-37 拖曳完成后的效果

最终整理后的代码如下所示:

import Cocoa

class AppDelegate: NSObject, NSApplicationDelegate {

@IBOutlet var window: NSWindow

@IBOutlet var pushButton: NSButton

func applicationDidFinishLaunching(aNotification: NSNotification?) {

// Insert code here to initialize your application

pushButton.action = Selector("pushButtonClick")

}

func pushButtonClick(){

print("Hello , welcome to http://www.sohu.com")

}

func applicationWillTerminate(aNotification: NSNotification?) {

// Insert code here to tear down your application

}

}

由此可见,通过Xcode 6的界面设计器,不但可以方便地设计UI界面,而且可以方便地和界面中的控件实现交互处理。本实例的最终执行效果如图5-38所示,单击按钮后会实现简单的交互功能。

图5-38 执行效果