iOS UIKit:TableView之表格创建(1)

      Table View是UITableView类的实例对象,其是使用节(section)来描述信息的一种滚动列表。但与普通的表格不同,tableView只有一行,且只能在垂直方向进行滚动。tableView由多个section组成,而section又由行(row)组成,也可将行称为单元格(cell)。Cell是UITableViewCell类的实例对象。

1 样式

      UIKit框架提供了一些标准样式供设计UITableView和UITableViewCell的结构和显示外观,同时也提供一些单元格的附加显示方式。

1.1 Table View

UITableView类有两种主要的样式:plain 和grouped,两者的差别主要是在外观上。

1.1.1 Plain类型

      Plain样式是table view的一种常规样式,该类型的section间距非常细微。而且每个section对象都有自己的header和footer标题,当用户滚动表格时,section的header标题会跟着浮动到顶部,同时section的footer则会浮动到表格的底部。如图 11所示。

图 11 A table view in the plain style

      若使用了索引表(indexed list)则会在表格的右侧显示每个section的header标题,当用户触碰了某一项索引时,视图会滚动到相应的section中,从而索引表起到了导航的作用。如图 12所示。

图 12 A table view configured as an indexed list

 

1.1.2 Grouped类型

      Grouped样式的表格也可以展示数据,但每个section之间都有非常明确的间距,如图 13(左)所示。同时Grouped样式表格的每个section的位置和尺寸都是固定,如图 13(右)所示。

图 13 A table view in the grouped style

 

1.2 Cell View

      除了为UITableView定义了两种类型的样式外,UIKit框架还为 cell也定义了四种类型的样式。同时用户还可以自定类型的cell样式。

1.2.1 Basic类型

      这种类型的cell是由常量UITableViewCellStyleDefault来描述的,其使得table view的cell只拥有一个简单标题和可选的图像。如图 14所示。

图 14 Default table row style

1.2.2 Subtitle类型

      该类型的table view cell除拥有一个左对齐的标题,同时还有一个灰色的副标题,当然也可以设置图像。可以通过UITableViewCellStyleSubtitle常量进行描述,如图 15所示的效果图。

图 15 Table row style with a subtitle under the title

1.2.3 Right Detail类型

      该类型的table view cell也有一个左对齐的标题,但副标题是蓝色的右对齐,同时不允许设置图像。可以通过UITableViewCellStyleValue1常量进行描述,如图 16所示。

图 16 Table row style with a right-aligned subtitle

1.2.4 Left Detail类型

      该类型的table view cell比较特殊,其标题位于行的左侧,但是右对齐的且默认为蓝色;而副标题位于行的右侧,但是为左对齐。同时这种类型样式不允许设置图像。可以通过UITableViewCellStyleValue2常量进行描述,如图 17所示。

图 17 Table row style in Contacts format

1.3 Accessory Views

UIKit框架还Table view提供了三种附加视图,如表 11所示。

表 11 accessory views

accessory views

Name

Description

Disclosure indicator

使用UITableViewCellAccessoryDisclosureIndicator常量。若需在另一个层次的table view中显示更详细的信息,则可以使用这种类型。

Detail disclosure button

使用UITableViewCellAccessoryDetailDisclosureButton常量,可以在另一个view中显示更详细的信息(可以为 table view,也可以不是)。

Checkmark

使用UITableViewCellAccessoryCheckmark常量。可以使用这种样式来让用户进行选择,可以是多选,也可以是单选。

 

2 API概述

      UIKit为table view编程提供了两个protocols,及一个category。

2.1 View

      Table view本身是UITableView的实例对象,可以使用这个类的方法来配置table view的外观和行为,同时可以用于管理section、row和滚动视图。UITableView继承自UIScrollView类,该类定义了视图的滚动行为,但UITableView只允许在垂直方向上进行滚动操作。

2.2 Data Source与Delegate

      一个UITableView对象必须要有一个delegate和一个data source对象。遵守MVC设计模式,data source 用于协调数据模型和视图;而delegate管理视图的外观和行为。其实data source和delegate经常为同一个对象。

1) Data source

      Data source对象是继承自UITableViewDataSource协议,并且必须实现协议的其中两个方法:

  • tableView:numberOfRowsInSection该方法是告诉UIKit每一section有多少行,即有多少个cell。
  • tableView:cellForRowAtIndexPath该方法向UIKit返回每一行中的cell对象。

另外还有一些可选的方法用于配置section的数目、header和footer,及配置是否支持添加、移除和跟踪row。

2) Delegate

      Delegate对象是继承自UITableViewDelegate协议,这个协议没有必须要实现的方法。其提供了很多配置table view可视化外观的方法,及一些section管理方法。 同时app还可以使用一个便利的类:UILocalizedIndexedCollation。该类帮助data source来组织索引列表的数据;同时当用户点击row时,该类能以非常合适的方式来显示section对象。

2.3 Controller

      根据UIKit提出的MVC设计模型,UITableView属于V部分元素,其需要指定C部分元素进行管理。对于control对象,有两种实现方式:

1)继承UIViewController类

     若用户直接继承UIViewController类来管理UITableView,那么用户需实现UIViewController类的两个方法,其实现的具体任务为:

  • viewWillAppear:方法

    即在table view展示之前,通过调用UITableView对象的deselectRowAtIndexPath:animated:方法来清理选中的row。

  • viewDidAppear:方法

    即在table view展示了之后,应向UITableView对象发送flashScrollIndicators消息,从而刷新视图。

2) 继承UITableViewController类

      UITableViewController类已经实现了Delegate和Data Source协议,同时实现了一些细节工作。如当table view将要显示视图时,或是table view完成了显示内容时,UITableViewController类能帮忙清理section对象。另外还能以合适的方式响应用户交互事件;最重要的是UITableViewController类有一个tableView属性,其指向UITableView对象。

注意:

      Apple虽然推荐采用继承UITableViewController类来管理tableView,但若一个视图中还拥有其它的子view对象,那么应该采用继承UIViewController类的方式,而不是继承UITableViewController类,因为UITableViewController类会将UITableView对象填充整个屏幕。

    当然若在interface builder的库中直接拖动一个 table view controller对象到设计界面中,那么则需要继承UITableViewController类。

2.4 Paths

      很多table view方法都使用NSIndexPath对象作为参数。该对象声明了在table view中单元格(cell)的路径,其有两个属性:sectionrow。通过这个对象能标识二维空间table view中cell的位置。

2.5 Cells

      在table view中的其实是一个单元格,即是UITableViewCell对象。该类提供了很多方法用于管理和配置单元格。用户可以直接继承该类,从而自定义cell的外观和样式。

3 创建与配置

3.1 基本过程

      在创建table view过程中,有几个实体对象之间会发生交互:viewController、tableView、data source和delegate。其中viewController、data source和delegate一般是同一个对象,如下是创建基本tableView的过程,如图 31所示。

      a) viewController指定frame和style值来创建UITableView实例对象,其中可以使用programmatically或storyboard方式。

      b) 用户(ViewController)为UITableView对象设置data source和delegate对象,然后向其发送reloadData消息。

      c) UITableView对象调用data source对象的numberOfSectionsInTableView:方法,从而获得tableView中section的数量。该方法为可选方法,默认返回1。

      d) UITableView对象调用data source对象的tableView:numberOfRowsInSection:方法,从而获得每个section中row的数量,该方法为必须实现的方法。

      e) UITableView对象调用data source对象的tableView:cellForRowAtIndexPath:方法,从而获得每个row中的UITableViewCell对象,该方法为必须实现的方法。

图 31 Calling sequence for creating and configuring a table view

 

3.2 Storyboard方式

3.2.1 创建tableView

      在interface builder的库中有两种控件:table view和table view controller,从而可以采用两种方式来创建表格。

 1) table view控件

      若使用table view控件,则可自由配置content view中的内容,如可以添加更多的控件,而不是仅仅只有一个table view控件。当然这种方式需要用户进行更多配置,如界面的布局等。如下是创建和配置的步骤:

  • 直接从库中拖动一个table view控件到某个UIViewController的rootView内。
  • 创建一个继承UIViewController子类,同时创建遵守UITableViewDataSourceUITableViewDelegate协议的类,在该类中实现data source两个必选方法。
  • 在UIViewController子类中设置tableView对象的data source和delegate对象。
  • 在indentity inspector中指定相应的class,并指定tableView的样式类型。

 2) table view controller控件

       也可以直接使用table view controller控件,但由于table view controller控件把整个屏幕除了导航栏和状态栏都被table view所填满,所以无法再添加其它的视图,其自定义方式比较受限,但若只是使用table view则比较简单。如下是创建和配置的步骤:

  • 直接从库中拖动一个table view controller控件到中央的编辑器内。
  • 创建一个UITableViewController子类,并实现UITableViewDataSource协议的两个必选方法(其它方法也可实现)。
  • 在indentity inspector标签中指定相应的class,并指定tableView的样式类型。

3.2.2 设置tableview内容

        tableView的内容就是cell,其中有两种方式来创建cell:DynamicStatic

1) Dynamic prototypes

         这种方式是指在interface builder中创建一个cell原型(模板),然后在data source的相应方法中通过标识符获取原型cell类,接着实例化模板对象并返回。如图 32所示的cell原型(左),及设置Identifier的内容(右)。

图 32 A dynamic table view

2) Static cells

        这种方式为tableView指定静态的布局内容和cell的数量。

图 33 A static table view

        注意:通过interface builder创建tableView默认是动态原型模型,若希望使用static cell方式,需要对其进行某些设置,如图 34所示:

  • 选中table view;
  • 显示Attributes inspector;
  • 在其content菜单中选择Static Cells选项

图 34 static cell配置

3.3 Program方式

3.3.1 实现协议

      通过程序的方式创建table view,一样需要实现协议的相应方法;若是继承UIViewController类,则同时还需实现UITableViewDelegate和UITableViewDataSource协议,并实现相应的方法。如下所示。

1 @interface RootViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
2 @property (nonatomic, strong) NSArray *timeZoneNames;
3 @end

 

3.3.2 创建和配置

在实现相应协议后,即可创建table view对象,并进行相应配置,可按如下方法进行:

      a) 创建并初始化UITableView对象;

      b) 设置data source和delegate对象;

      c) 调用UITableView对象的reloadData方法

如下是创建一个tableView对象,并设置到controller的view的属性:

 1 - (void)loadView
 2 {
 3     UITableView *tableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] style:UITableViewStylePlain];
 4     tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
 5     tableView.delegate = self;
 6     tableView.dataSource = self;
 7     [tableView reloadData];
 8 
 9     self.view = tableView;
10 }

 

3.4 查询数据

      在创建一个UITableView对象后,controller对象将向UITableView对象发送reloadData消息,从而UITableView对象通过查询data source和delegate对象的消息来显示相应section和row对象。

如下所示是实现一个data source和delegate协议方法的简单示例:

 1 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { //可选:返回表格section的数量,默认为1.
 2     return [regions count];
 3 }
 4 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {//必选:返回每个section中row的数量
 5     Region *region = [regions objectAtIndex:section];
 6     return [region.timeZoneWrappers count];
 7 }
 8 - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {//可选:返回每个section中的header标题
 9     Region *region = [regions objectAtIndex:section];
10     return [region name];
11 }
12 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {//必选:返回每个row中的cell对象
13     static NSString *MyIdentifier = @"MyReuseIdentifier";
14     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
15     if (cell == nil) {
16         cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault  reuseIdentifier:MyIdentifier];
17     }
18     Region *region = [regions objectAtIndex:indexPath.section];
19     TimeZoneWrapper *timeZoneWrapper = [region.timeZoneWrappers objectAtIndex:indexPath.row];
20     cell.textLabel.text = timeZoneWrapper.localeName;
21     return cell;
22 }

 

3.5 索引列表

      Table view通过索引列表能够快速进行导航,其中UITableView的plain和grouped样式都可配置索引列表。而配置索引列表只需实现UITableViewDataSource协议的三个方法:

       1) sectionIndexTitlesForTableView:其返回表格右边的索引标题,是一个NSString类型的数组。

       2) tableView:titleForHeaderInSection:其返回每个section的header标题,是一个NSString对象。

       3) tableView:sectionForSectionIndexTitle:atIndex:其返回section的索引,即当点击表格右边的索引时,将滚动到section的位置,是一个整型值。

 

如在一个tableView中有8个section,则与索引列表的三个方法所实现如下:

 1 - (NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView
 2 {
 3     NSArray<NSString*>* array = @[@"I0",@"I1",@"I2",@"I3",@"I4",@"I5",@"I6",@"I7"];
 4     return array;
 5 }
 6 - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
 7 {
 8     NSString* title = [[NSString alloc] initWithFormat:@"T%ld",section];
 9     return title;
10 }
11 
12 - (NSInteger)tableView:(UITableView *)tableView
13 sectionForSectionIndexTitle:(NSString *)title
14                atIndex:(NSInteger)index
15 {
16     return index;
17 }

 

图 35 索引列表效果图

posted @ 2016-05-10 19:05  xiuneng  阅读(1101)  评论(0编辑  收藏  举报