在本课中,你创建第二个场景,它基于表视图,用来罗列用户的菜品。这个菜品列表会成为应用的首场景。你也要设计自定义的表单元来显示每个菜品,大概是这样的:
学习目标
在结束本课的时候,你将能够:
- 创建第二个storyboard场景
- 理解table view (表视图)的关键组件
- 创建和设计自定义table view cell(表视图单元)。
- 理解table view 委托方法(delegate)和数据源(data source)方法的规则
- 用数组存储和使用数据
- 在table view中动态显示数据
创建菜品列表
到现在为止,FoodTracker应用只有一个单一场景,也就是说,只有一个屏幕的内容。在storyboard中,每个场景包含由一个视图控制器管理的视图以及添加在控制器或者其视图上的任何元素(例如,自动布局的约束)。一个视图是一个能够绘制它们自己的内容并对用户事件作出响应的矩形区域。视图是UIView或者其子类的实例。在本例中,场景包含了视图控制器的视图,以及所有你添加在Interface Builder上的子视图(stack view,label,text field, imge view,以及rating控件)。
现在是时候创建另一个场景,它显示整个菜品列表。幸运的是,iOS自带一个内建的项目,UITableView,专门设计用来显示项目的滚动列表。表视图由表视图控制器(UITableViewController)管理。UITableViewController是UIViewController的子类,它被设计用来处理表视图相关的逻辑。你将使用表视图控制器来创建一个新场景。这个视图控制器显示并管理表视图。事实上,表视图是这个视图控制器的内容视图,充满整个场景的可用控件。
使用table view添加一个场景到storyboard
- 打开Main.storyboard.
- 在utility area中打开Object library。(或者选择View > Utilities > Show Object Library。)
- 在Object library,找到Table View Controller 对象。
- 从这个列表中拖拽Table View Controller对象到场景中现有的场景的右边。
如果你拖拽了但是没有什么改变,有可能你拖拽的是table view对象而不是table view controller对象。table view 对象是一个表示表格自身的一个视图。和其他的视图对象一样,它必须作为子视图添加到一个已有的场景中。另一方面,table view controller是整个场景。它包含了table view以及管理这个table view 的控制器。
现在你有了两个场景,一个显示菜品的列表,另一个显示某一菜品的详细内容。
为了使菜品列表成为用户启动应用时第一眼看到的场景,需要通过设置table view controller为第一场景来告诉Xcode你的打算。
设置菜品列表作为初始化场景
-
如果你想要跟多的空间,那么把那些边边角角都收起来吧。
-
把storyboard entry point(故事板入口点)从菜品详情场景移动到菜品列表场景。
这个table view controller被设置为了storyboard的初始化视图控制器,这样在应用启动的时候菜品列表作为第一场景被加载。
检查点:运行应用。取代带有text field、image view、以及rating空间的菜品详情场景,你将会考到一个空的table view——一个由很多水平分割线把屏幕分成行的屏幕,但是这些行里还没有内容。
你需要在这个table view上改变一些设置,以便在应用中使用它。
配置table view
- 在storyboard中,打开大纲视图并展开utility area。
-
在大纲视图,选择Table View。
table view被嵌套在Table View Controller Scene > Table View Controller里面。你需要点击这些对象旁边的展开三角才能看到被嵌套的table view。
- 选中table view,在utility area中打开Size inspector。
- 在Size inspector,找到Row Height(行高)字段,输入90,按下回车键。
过会儿我们再回来操作table view自身,我们先来设计显示table view显示内容的界面:table view cells(表视图单元)。
设计自定义表单元
在table view中的单独一行,是被table view cell(UITableViewCell)管理的,它负责绘制它们自己。Table view cell拥有各种预定义的行为和默认的单元样式;但是,因为你要显示在cell中的内容超过了默认样式的范围,所以你需要自定义cell样式。
创建一个UITableViewCell的子类
- 打开Project navigator。
- 选择File > New > File (或按下 Command-N)
- 在出现的对话框的顶部,选择iOS。
- 选择Cocoa Touch Class,然后点击Next。
- 在Class字段,键入Meal。
- 在Subclass of字段,选择UITableViewCell。
类标题更改为MealTableViewCell。Xcode从命名中清楚的表明你创建了一个自定义的table view cell,就用这个新名字。 - 语言还是用Swift。
- 点击Next。
保存到项目目录。Group选项保持默认,FoodTracker。 - 在Targets部分,确保你的应用被选中,而应用的测试没有选中。
- 点击Create。
Xcode创建了定义MealTableViewCell类的文件:MealTableViewCell.swift。 - 在Project navigator中,把MealTableViewCell文件放在其他Swift文件的下面。
现在再次打开storyboard。
如果你查看storyboard中的菜品列表场景,你会注意到它只显示了一个单一的的table view cell。
这个cell是table的属性cell。你能定义它的设计和行为。Table可以在需要的时候创建这个cell的实例。但首先,你需要连接场景中的table view cell到你创建的自定义cell子类。
为你的table view 配置自定义cell
-
在大纲视图,选择Table View Cell。
找到嵌套的table view cell。
- 选中table view cell,打开Attributes inspector。
- 在Attributes inspector中,找到Identifier标签字段并键入MealTableViewCell。按下回车键。
你将使用这个识别符来创建属性cell的实例。 - 打开Size inspector。
-
在Size inspector中,找到Row Height标签字段并键入90。确保这个字段旁边的Custom复选框被选中。
按下回车键,storyboard中显示了新cell高度。
- 打开Identity inspector。
回想一下,Identity inspector让我们编辑storyboard中的对象的与身份相关的属性,例如对象所属什么类。 -
在Identity inspector中,找到Class 字段并选择MealTableViewCell。
使用cell设置,你能在storyboard中直接设计自定义用户界面。你需要一个label、一个image view、以及一个rating 控件。你能复用在之前的课程里创建的rating控件类。你的自定义界面将包含菜品名、照片、评分,它看起来是这样的。
设计自定义表单元界面
- 使用对象库找到Image View对象并拖拽到table cell。
-
拖拽image view,让它呈现下图的样子和位置:
- 选中image view,打开Attributes inspector。
-
在Attributes inspector中找到Image 字段,选择defaultPhoto。
你可以添加上一课默认的图片到项目。
- 使用对象库找到Label 对象并拖拽它到table cell。你将使用这个label来显示菜品的名称。
-
拖拽label,让它到达下图显示的位置。
-
拖拽label的右边缘和table cell的右边缘对其。如下图所示。
- 使用对象库找到Horizontal Stack View 对象并拖拽到table cell。
- 选中stack view,打开Size inspector。
- 在Size inspector中,在Height字段键入44,在Width字段键入252。按下回车键。
-
拖拽stack view到下图所示的位置。
- 选中这个视图,打开Identity inspector。
-
在Identity inspector中,找到Class 字段,并选择RatingControl。
如果你在弹出菜单中没有看到RatingControl选项,确保你已经在画布中选择了stack view。
- 选中这个视图,打开Attributes inspector。
- 在Attributes inspector中,设置Spacing为8。接下来,找到Interactoio字段并取消User Interaction Enabled复选框。
你设计的自定义rating 控件类是可以交互的,但是你在这个cell 视图中不想用户能够改变评分。取而代之的是,用户点击在cell的任何地方选中的都是这个cell本身。所以取消这个控件的交互性很重要。
你的用户界面看上去应该是这样的:
检查点:运行应用。表视图单元的高度是变高了。但是你没有看到任何你添加在表视图单元上的用户界面元素,它们显示的是空白,就像之前一样,为什么会这样?
在storyboard中,你能够设置table view显示静态数据(在storyboard中提供)或者动态数据(通过table view controller的编程提供)。默认情况下,table view controller使用动态数据。这意味着你在storyboard中创建的界面只是table cell的属性而已。你仍然需要在代码中创建cell的实例并使用应用的数据来填充它。
现在,你可以使用助理编辑器来预览你的cell。
预览你的界面
-
打开助理编辑器。
-
折叠一些区域增加操作空间。
-
在编辑器选择器栏中,在助理编辑器顶部出现,选择Automatic to Preview > Main.storyboard(Preview)。
你的Xcode窗口看上去是这样的:
这个预览显示image view 和label。rating空间没有显示在预览中,但是table view cell看上去和预期的一样。
注意
如果在预览中看到错误的场景,确保是容果点击table view的场景dock来选择它的。
添加图片到项目
接下来,你需要添加几张简单的图片到项目。当你加载初始化菜品数据到应用中的时候,你将使用这些图片。
你能在本课最后的下载文件的Images文件夹中找到这些图片,或者你使用自己的图片。(确保图片的名字和你稍后在代码中使用的图片名字相匹配)。
添加图片到项目
-
如果助理编辑器开着,返回到标准编辑器。
- 在project navigator,选择 Assets.xcassets来访问资源目录视图。
- 在左下角,点击加号按钮并在弹出菜单中选择New Folder。
- 双击文件名并重命名为Sample Images。
- 选中文件,在左下角点击加号按钮,在弹出菜单中选择New Image Set。
- 双击image set名字并重命名它,这个名在你编写代码的时候也要一致。
- 在你的电脑中,选择你想添加的图片。
- 拖拽图片到image set中的2x的插槽。
重复上面5-8步骤添加更多你喜欢的图片。在本课中将定你有三个不同的图片,meal1, meal2, 和 meal3。