第五章 :创建一个简单的基于Table View的应用程序

第五章 :创建一个简单的基于Table View的应用程序

译者注:由于本人英语水平有限,尽可能描述出作者的本意。如有错误,及时指出。文中会省略部分技术无关的赘述

Everything is easier said than done. Wanting something is easy. 
    Saying something is easy. The challenge and the reward are in the doing.                                                                                                    
                                                                                                    – Steve Maraboli

这里写图片描述


介绍UITableView

现在你对prototype和我们的demo app有个基础的了解 。在本章,我们将使用UItableView建立一个更有趣的app 。一旦你掌握了这个技术和table view的自定义(下章讨论),我们将会开始我们的Food Pin app开发。

首先,table view 究竟是什么? 他是IOS apps中最常见的UI元素 。大多数app(除过游戏),在某些方面 ,利用表视图来显示内容。最好的例子就是苹果的内建应用。你的联系人列表就是用tableview展示的 。 邮件也是,使用tableview展示你的邮箱和电子邮件 。 tableview不仅可以展示文本数据,还可以展示图像数据 。TED ,Google+ 和 Airbnb 也是很好的例子 。上图展示了一些简单的基于tableview的app ,尽管他们看起来不一样,但是他们都是利用tableview 开发的 。


创建一个简单的Table工程

我们开始创建一个简单的app ,这个app真的很简单 。 只是来展示一些餐馆名字的列表 。 这个tableview 看起来并不那么好看 。我们将在下一章改进它 ,打开Xcode ,创建一个”Single View application”

这里写图片描述

按照第一章讲得填好项目名Simple Table组织名随便填一个,不要勾选User Core Data , 选个好存放项目的目录 ,进入项目 。


storyboard 设计

这里写图片描述

首先我们会创建一个用户界面添加一个tableview 。 选择”Main.storyboard”切换到storyboard的编辑界面 。

我们不适用Size Classes ,按照第一章的方法把Size Classed的勾选去掉 。

下一步 ,从对象库拖一个table view 试图到当前试图 。如下图

这里写图片描述

然后,选择这个tableveiw 。 在属性编辑器中(如果没有在Xcode中显示 ,选择 View > Utilities > Show Attributes Inspector) , 把Prototype Cells 从 0 改成 1 。

这里写图片描述
(本图为译者添加)

tableView中就会出现一个prototype cell 。prototype cells 允许你很容易的去射你的table view cell 。它还配备了一些标准的单元格风格 包括basic (基础类型),right detail (右边明细),left detail (左边明细)和 subtitle (副标题) 。我们这个例子中会使用basic。

选择cell 打开属性编辑器 ,把cell的style 改成Basic ,这个类型足够显示文字和图片 。 此外,把Identifier 设置位 Cell ,这个是prototype cell的唯一标示符 。我们一会儿会在代码中使用到它 。

这里写图片描述


不写任何代码,Run你的app

在继续之前 , 在模拟器上Run你的app 。

模拟器上得界面显示如图

这里写图片描述

非常简单,对吗?你已经为你的app创建了一个table view 。然而它没有任何数据 ,下一步我们将会写一些代码给这个tableview 添加一些数据


UITableView 和协议

我前面提到我们会使用一些IOS SDK提供的类,这些类被组织成framework(框架)。UIKit框架是我们最经常使用的框架 。

它提供一些类去构建和管理你的app界面 。所有用户界面叛变对象库提供的对象都是这个框架提供的 。第一章用到的按钮控件和这章用的table veiw控件都是它提供的 。table view的类实际上是UITableView 。 你可以在对象库点击任何一个对象 ,它的类名都会弹出来 。

这里写图片描述

现在你已经知道Table View和UITableView之间的关系了 。我们将会写一些代码给table增加一些数据 。选择ViewController.Swift 。在代码编辑器中”UIViewController”后面添加”,UITableViewDataSource,UITableViewDelegate”来实现对应的协议 。

你把上面的协议添加上后,Xcode就会报错 ,当有错误的时候Xcode会显示一个红色的感叹号 。 点击左侧的小感叹号Xcode 将会把这行代码高亮 而且会显示出错误信息 。这个信息会提示你错误的信息但是不会提供解决方案 。

这里写图片描述

“ViewController does not conform to protocol
UITableViewDataSource” 是设么意思呢?

UITableViewDelegateUITableViewDataSource 是swift中的协议 。为了在table View中显示数据 ,我们必须符合协议中的规定并提供一个对象(这里就是ViewController)实现那些强制性的方法 。

你也许会疑惑 ?这些协议是什么? 为什么要使用这些协议 ?

我们来打个比方 , 你雇佣了一个平面设计师 帮你设计公司的logo 。他是一个数量的设计师可以设计各种logo 。但是它不能立即开始设计 。 在让它设计之前你至少要给他提一些需求比如公司的名字 、颜色偏好、商业背景。然而,你非常忙。你委托你的个人助理去提供这些需求 。

在IOS编程中 ,UITableView就像那个图像设计师 。他足够灵活在table中显示各种数据 。 你也许想显示一些国家或者联系人名称 或者一些其他的东西 。我们将展示一个餐馆列表附带缩略图 。

但是它需要一个 代理去提供协议基础信息 如:

  • 你想在这个table中展示多少行数据 ?

  • table中的数据是什么 ?例如你想给第二行显示什么?你想给第五行显示什么?

上面的东西像一个个人助理,ViewController充当一个代理去提供必要的信息 。

然而你怎样告诉UITableView展示什么数据 ? UITableViewDataSource是关键 。他是你的数据和tableview的桥梁 。这个协议定义了一写方法让你去实现 。下面是两个UITableViewDataSource必须实现的方法:

  • tableView(_:numberOfRowsInSection:)

  • tableView(_:cellForRowAtIndexPath:)

你需要的是有一个对象去实现上面的方法 ,以便让UITableView知道显示多少行和每行显示什么数据 。 这个协议还定义了一些可选方法 ,但我们这里并不准备讨论他们 。

UITableViewDelegate处理table view的外观 ,协议中所有方法都是可选的 。 它帮你管理你行高 配置section 的header 和 footer ,重新给tableview cells排序 等等 。我们例子中不会用到这些方法 。我们后面章节会使用他们 。

带着这几基础知识,我们继续编写代码 。 选择ViewController.swift 声明一个变量存储数据 。

var restaurantNames = ["Cafe Deadend", "Homei", "Teakha", "Cafe Loisl", "Petite Oyster", "For Kee Restaurant", "Po's Atelier","Bourke Street Bakery", "Haigh’s Chocolate", "Palomino Espresso","Upstate", "Traif", "Graham Avenue Meats And Deli", "Waffle &Wolf", "Five Leaves", "Cafe Lore", "Confessional", "Barrafina","Donostia", "Royal Oak", "CASK Pub and Kitchen"]

在这里例子中,我们使用一个数组去存储数据 。 swift中数组使用不再赘述 。

下一步 ,我们来实现UITableViewDataSource协议的两个必要的方法

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // Return the number of rows in the section.
    return restaurantNames.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) ->
UITableViewCell {
    let cellIdentifier = "Cell"
    let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath:
    indexPath) as UITableViewCell
    // Configure the cell...
    cell.textLabel.text = restaurantNames[indexPath.row]
    return cell
}

第一个方法告诉table View某个section中共有多少行(一个tableview可以有多个section 默认是一个) 。 这个简单取数组的长度。

第二个方法展示每行数据的时候都会调用 。使用indexPath对象 ,我们可以得到当前行(indexPath.row) 。以便我们从restaurantNames数组中取出索引元素赋值给cell的text Label 去显示 。

那么dequeueReusableCellWithIdentifier这个方法是什么意思呢 ?

那个方法是通过唯一标示符(在storyboard中页面的identifier属性定义的”Cell”)从table cell队列中取出可重复利用的tableview cell 。

你希望你这个tableview app能够快速响应,即使是处理上千条数据 。如果你每次都分配一个新的cell而不是重用它。你的app会使用更多的内存 ,当用户滚动tableview的时候还会反应呆滞 。分配每一行都会有性能开销,特别是在很多一段时间内分配。

屏幕可以显示大小是固定的 ,即使你需要显示1000条记录 ,屏幕最多显示10条 。为什么要创建并分配1000个tableview cell而不是创建10个tableview cell并且重用他们呢 。这将节省大量的内存也会使你的app效率更高 。因此处于性能考虑,你应该重用cell

这里写图片描述

现在点击Run按钮去测试你的app , 哎呀!app还是显示空的。

为什么tableview没有像我们预期那样显示内容呢?我们已经写了显示他们的方法呀?

还有一件事情没做。


连接DataSource 和 Delegate

尽管我们的ViewController 已经实现了协议的方法 , 但是UITableView并不晓得 。我们需要告诉UITableView ViewController就是他data source的代理 。

回到storyboard 。按住control建不放 ,点击table view拖到左边的饿View Controller 。如图

这里写图片描述

放开,在弹出菜单中选择 dataSource ,重复上面的操作 ,再选择delegate 。
这里写图片描述

为了确保连接正确 , 在左边的窗体选择tableview右击显示那些连接 。

这里写图片描述


测试你的app

最后我们点击Run按钮让我们的app在模拟器上跑起来 。你的app现在战士了餐馆名字的列表 。

这里写图片描述


给tableview添加缩略图

这个tableview看起来太单调了 ,我们需要给每行添加图片 。UITableView使他变得很简单 ,我们只需要添加一行代码就能搞定 。

首先需要从这里下载示例中的图片https://www.dropbox.com/s/d1rwisj6pt89db3/restaurantimages.zip. (国外地址需要翻墙)这里包含三个图像文件。所有的文件都是一样的,只是不同的分辨率 。当你开发一个IOS应用的时候 。推荐你准备三套图片 。@3x后缀名的是给iPhone plus用的,@2x给iPhone 4/4s/5/5s/6 , 没有 @ 后缀名的是给一些没有retain的老设备使用的 。

Xcode项目包含一个 image asset 目录(images.xcassets) 供你去管理大多数类型的图像文件 。你把那些图片解压,选择images.xcassets ,把那几个文件从Finder中拖进来就可以了。

这里写图片描述

系统自动事变retain 和 非 retain图像 。一旦图像在图像组中可用 ,你就可以在代码中是用不带后缀名的文件名称来访问他们。

这里写图片描述

现在打开ViewController.swift在tableView(_:cellForRowAtIndexPath:)方法的return cell前添加

cell.imageView.image = UIImage(named: "restaurant")

UIImage是由UIKit框架提供的 。它支持各种图像格式比如png ,gif ,jpeg .简单的传递图像的名称它将帮你家在这个图像 。

我们使用单元格的基础样式 ,它有一块默认的区域用来显示图像 。这行代码就是让UITableView在默认图像显示区域显示制定的图像 。现在点击Run按钮 SimpleTable app会在每行显示图像 。

这里写图片描述


隐藏状态栏

从IOS 7开始ViewController会在整个屏幕显示 。tableview的内容和状态栏重叠了 ,看起来并不美观 。

一个简单的措施就是隐藏状态栏 。你可以在任意一个Viewcontroller中控制它的状态栏的外貌。 如果你再一个特定的页面不想显示状态栏 。仅仅需要添加下面的代码 。

override func prefersStatusBarHidden() -> Bool {
    return true
}

把上面的代码添加到ViewController.swift中 ,重新运行app ,现在状态栏被隐藏了。


给UITableView添加Auto Layout 约束

你已经做了很多了 。你第二个app在iPhone 5/5s上看起来不错 ,你有没有试过在iPhone 4s上运行 或者横屏显示 ?你可以试试这么做。

下图横屏的情况

这里写图片描述

table View并没有完全显示 。你也许清楚你需要使用Auto Layout 使它充满屏幕 。

打开storyboard选择tableview 。在Auto Layout菜单点击 Pin 按钮打开Pin 工具菜单 。选择每个红色虚线,一旦选中这些虚线就变成了实线 。点击”Add 4 Constraints” 按钮添加这些约束 。这里我们对UITableview的4个边定义了四个约束 。另外, 我们想要保证UITableView的底部不要超过Bottom Layout Guide。 如果在左边窗体中展开约束项目 你会看到两个横向的空间约束和两个竖向的束。两个水平空间约束可以确保左侧和右侧表视图将延伸到视图的边缘。垂直约束用于解决了3.5英寸的屏幕问题 。UITableView的底部和Bottom Layout Guide对齐 。换句话说,你的app将自动调整大小适配小屏幕 。

非常好 ,现在测试你的app 。你的app不管任何屏幕下都可以完美显示包括横屏 。

这里写图片描述


你的练习作业

到目前为止你的demo app在每个cell中展示了固定的图像 。尝试调整你的app代码 ,让他在每个cell中显示不同的图像 。


总结

表视图是在IOS编程最常用的要素之一。如果你完全理解上面讲得 ,你应该对构建自己的table view app有个很好的想法 。我尝试去把demo中的每个点都讲得非常简单 。在真实的项目中table数据不会是简单的”hard-code”。

通常他们从文件、数据库后者其他地方中加载。我们后面会讨论这些。然而你首先要确认你了解tableview怎么工作 ,否则把这章再读一遍 。

你可以下载示例工程供你参考:https://www.dropbox.com/s/kufb6373g1rrsn8/SimpleTable.zip.

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值