CS193P第八堂课摘要及心得笔记

121℃ 791评论

在上次探讨了 Navigation Controller 等内建的类别之后,在这一次的课程内容中,我们将看看要如何在 iPhone 开发平台上使用资料表格以及可以捲动的 View,还请各位多多指教!

Scroll Views

在 iPhone 应用程式中,像是内建的地图程式,我们可以自由的用手指在画面上移动,而画面也会随之而捲动。而这样的功能可以透过 UIScrollView 这个 UIKit 内建的 View 来完成。除了地图之外,像是记事软体中的文字显示或是相簿的显示也都是透过 UIScrollView 或其子类别完成的。此外,除了捲动之外,UIScrollView 也支援了放大缩小的功能,这将会在等会的内容中提到。

而建立一个 UIScrollView 的方法就如同其他 UIView 一般,我们可以透过 Interface Builder 或是在程式中完成:

   CGRect frame = CGRectMake;   scrollView = [[UIScrollView alloc] initWithFrame:frame];

当然,我们也需要加入需要显示的图片作为 subView:

   frame = CGRectMake;   myImageView = [[UIImageView alloc] initWithFrame:frame];   [scrollView addSubview:myImageView];

最关键的步骤是,我们需要替 UIScrollView 设定两个属性,分别是 contentSize 和 contentInsect,前者是将要显示的 view 尺寸,后者则是显示的 view 四周的留白,关于这两者的差异,可以参考以下的示意图:

CS193P第八堂课摘要及心得笔记

那我们要如何得知使用者开始捲动画面或是进行其他动作呢?我们可以使用 delegate,也就是让某一个物件来负责接收这些讯息,并且做出对应的处理。在实做上,我们需要让这个物件类别去实做 这个 Protocol 中所需的方法以及一些选择性的方法,像是下面这个:

- scrollViewDidScroll:scrollView {   // 对捲动的动作进行回应   if{   } }

至于放大缩小,我们则需要先设定:

scrollView.maximumZoomScale = 2.0; // 最大放大倍率 scrollView.minimumZoomScale = scrollView.size.width /myImage.size.width; // 最小缩小倍率

然后还要实做这个 delegate 方法:

- viewForZoomingInScrollView:view {   return someViewThatWillBeScaled; // 回传某些可以被放大缩小的 View }

另外,我们也可以直接呼叫函式 - setZoomScale:scale animated:; 来直接放大缩小到某个特定的倍率,也可以用 - zoomToRect:rect animated:; 来放大缩小到某个特定的位置,UIKit 会自动帮我们找到最适合的缩放倍率以做显示。

Table View

在 iPhone 中的大大小小程式都会看到 Table View 的出现,除了一般的表格资料呈现之外,设定的呈现也往往用 Table View,主要分成以下两种:

CS193P第八堂课摘要及心得笔记

而针对 UITableView,我们有一些特别的惯用术语,我们称作每一行为 Cell,而许多 Cell 可以组成 Section,每个 Section 上下又分别有 Header 和 Footer,而许多个 Section 则组成了整个 Table,当然 Table 也有 Header 和 Footer,整体来说,如以下两张图所示:

CS193P第八堂课摘要及心得笔记
CS193P第八堂课摘要及心得笔记
在 Table View 中显示资料

重点来了,我们要如何在 Table View 中显示资料呢?一开始我们可能会猜测是否是直接设定一个阵列给 Table View,然而这样做会造成所有的资料都必须一口气读入记忆体,对于效能将是很大的危害。所以在 Cocoa 中,我们使用的是一种有弹性的方法,藉由指定资料来源 ,并且实做以下的方法:

// 回传 TableView 中的 section 数量,若不需要使用 section,则预设为 1 - numberOfSectionsInTableView:table; // 回传某个 section 中所包含的 rows 数量 - tableView:tableView numberOfRowsInSection:section; // 回传某 section 某 row 的 cell,也就是资料栏位 - tableView:tableView cellForRowAtIndexPath:indexPath;

至于这个 NSIndexPath 到底是什幺?其实他是一个特别用来在巢状的资料结构中定位的类别,包含了 row 和 section 两个 property 可以设定、使用。在投影片 69 页中有个简易的 Data Source 实做,大家可以参考。

然而,虽然动态产生 cell 回传比起直接建立所有 cell 来说在效能上有所增进,但仍然会遇到一些瓶颈。事实上,这些 cell 在同一张 table 中往往可以重新利用,只需要修改内容就可以了,因此 UIKIt 提供了这样的方法:- dequeueReusableCellWithIdentifier: identifier;,在应用上,当我们 init 一个 UITableViewCell 的同时需要设定 reuseIdentifier,这个参数将会替 cell 做标籤,未来我们就可以用这个 reuseIdentifier 去取得同样的 cell 并重複使用。

在投影片的 72 页到 79 页之间也介绍了一些重新读取资料的方法可以呼叫,有兴趣的读者还请自行参考。

Table View 的动作行为

就如同一般的 UIView 一般,当 cell 被使用者点选时,我们需要做出相对的动作,像是 push 一个新的 View 到 NavigationController 上等。要完成这样的功能,我们可以实做 - tableView:tableView didSelectRowAtIndexPath:indexPath 这个方法。

而我们也可以禁止使用者点选某些特定的 Row,只要实做 - tableView:tableView willSelectRowAtIndexPath:indexPath,回传 NSIndexPath 代表允许使用者点选,而回传 nil 则代表不能点选。

UITableViewController

诚如我们上面所见,要建立一个 UITableView 除了要设定 Data Source 之外,还有许多方法需要实做。为了方便我们能够快速开发,Cocoa 提供了一个 UITableViewController,这个特别的 ViewController 包含了一个 TableView,并且定义了以上大多的方法还有少数的实做,此外,这个 Controller 也会处理一些预设的行为,像是在 TableView 出现之前,会帮我们呼叫 -reloadData 这个方法等等。

Table View Cells

在 Data Source 那边我们曾经透过 initWithStyle:style reuseIdentifier:reuseIdentifier; 这个方法来建立 Cell,想必大家有注意这里有一个 UITableViewCellStyle 参数,下图就是几种常用的:

CS193P第八堂课摘要及心得笔记

而对于每个 UITableViewCell,我们可以设定 :

除此之外,也可以藉由 - tableView:table accessoryTypeForRowWithIndexPath:indexPath; 设定 Accessory Type,也就是每个 Cell 的小按钮,如下图所示:

CS193P第八堂课摘要及心得笔记

除了使用这些现成的的 UITableViewCell 方法之外,我们也可以直接修改 cell.contentView,自行加入想要的 UIView 作为 subView。

结论

在这一次的心得笔记中,我们涵盖了 iPhone 中最常见到的 Table View 显示,相信大家应该很有收穫。在下一次的笔记中,我们将会进入资料的储存以及读取,还请读者敬请期待!

参考资源
上一篇:           下一篇: