UITableView

 上节讲了一下UIView,这节接着讲它的重要子类,UITableView和UITableViewCell

UITableViewUIScrollView的子类,因此用户可以滚动UITableViewCell(UIView的子 类)组成的列表。

UITableView UIScrollView 有很多共同点。对于非数据列表的深度自定义的视图,你可以 使用 UIScrollView 并在里面布置 UIView UIControl 的子类,不过这种情况下使用 UITableView 更有优势。首先,如果可能的话,推荐使用更高级的抽象。其次,UITableView 会自 动实现一些微妙的功能。其中一个是能轻松出列并重用 UITableViewCell单元,这样可以改善性能 并减少内存占用。另一个是通过数据源和接收到的委托方法反馈来填充内容
 


UITableViewController

UITableViewController UIViewController 的子类,它能实现一些与表视图加载有关的额外功能。如果你正在通过一个 nib 文件初始化 UITableViewController,nib 加载机制会从 nib 文 件载入归档的表视图。如果不是的话,则它会创建一个未配置的表视图这两种情况下你都可以使用 UITableViewController 类的 tableView 属性来访问表视图。

通常来说,一个UITableView需要通过UITableViewController来指定它的样式。 当一个UITableViewController初始化的时候会创建UITableView的实例然后赋给自身的View属性,同时这个UITableView的两个属性dataSource和delegate都会指向UITableViewController。
@interface ItemsViewController : UITableViewController

 

#import "ItemsViewController.h"

@implementation ItemsViewController

- (id)init
{
    self = [super initWithStyle:UITableViewStyleGrouped];
    if (self) {

    }
    return self;
}


调用就如同上节所说的把它设为window的rootViewControlle

#import "ItemsViewController.h"

@implementation HomepwnerAppDelegate

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

    ItemsViewController *itemsViewController = [[ItemsViewController alloc] init];

    [[self window] setRootViewController:itemsViewController];

    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    return YES;
}

 

 

下图就是一个空的UITableView,由UITableViewController创建

接下来我们就要给它填充内容,看起来就像这样:

 


UITableViewCell

为了给UITableView填充内容,我们需要遵守UITableViewDataSource Protocol,其中有两个必须的方法,我们接来下会实现他们

– tableView:cellForRowAtIndexPath:  required method
– numberOfSectionsInTableView:
– tableView:numberOfRowsInSection:  required method
– sectionIndexTitlesForTableView:
– tableView:sectionForSectionIndexTitle:atIndex:
– tableView:titleForHeaderInSection:
– tableView:titleForFooterInSection:


UITableView包含了一个ContentView,而我们的具体内容都是包含在这个ContentView里,关系如下图所示:



UITableViewCellUIView的子类,它给UIView添加了一些能在UITableView中提供帮助的属性与功能。你并不需要手动添加自定义元素,因为 UITableViewCell已经提供了一些常用的元素,比如标题,子标题以及用来显示 textLabeldetailedTextLabel imageView 的缩略图。

当创建了一个 UITableViewCell,你便需要通过指定一个 UITableViewCellStyle来设置表单元的类型。样式决定了新创建的表单元支持哪些自定义元素。举个例子,通过 UITableViewCellStyleDefault样式创建的表单元不会支持 detailedTextLabel属性。

UITableViewCell第二个重要的功能是可以维护 selected highlighted 状态并在状态发生变化时实现动画效果。




我们用一个Item类封装了ContentView所需的内容,然后用一个Store类来管理。具体代码就不写了,很简单,有经验的人一看头文件就懂。

@class BNRItem;

@interface BNRItemStore : NSObject
{
    NSMutableArray *allItems;
}

+ (BNRItemStore *)defaultStore;
- (NSArray *)allItems;
- (BNRItem *)createItem;

@end

 

 

接着在UITableViewCell,我们通过tableView:cellForRowAtIndexPath: 方法来创建一个Cell并显示

- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                reuseIdentifier:@"UITableViewCell"];

    BNRItem *p = [[[BNRItemStore sharedStore] allItems]
                                    objectAtIndex:[indexPath row]];

    [[cell textLabel] setText:[p description]];

    return cell;
}

具体要创建多少个cell是由方法- (NSInteger)tableView:numberOfRowsInSection:决定的,我们可以写死一个数字尝试下效果

- (NSInteger)tableView:(UITableView *)tableView
 numberOfRowsInSection:(NSInteger)section
{
    return 1;
}

这时效果如图



我们可以根据自己的需要调节。


 

 完整的代码如下

#import "ItemsViewController.h"
#import "BNRItemStore.h"
#import "BNRItem.h"

@implementation ItemsViewController
- (id)init 
{
    self = [super initWithStyle:UITableViewStyleGrouped];
    if (self) {
        for (int i = 0; i < 10; i++) {
            [[BNRItemStore defaultStore] createItem];
        }
    }
    return self;
}

- (id)initWithStyle:(UITableViewStyle)style
{
    return [self init];
}

- (NSInteger)tableView:(UITableView *)tableView
 numberOfRowsInSection:(NSInteger)section
{
    return [[[BNRItemStore defaultStore] allItems] count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

    UITableViewCell *cell =
        [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"];

    if (!cell) {
        cell = [[UITableViewCell alloc]
                    initWithStyle:UITableViewCellStyleDefault
                  reuseIdentifier:@"UITableViewCell"];
    }
 
    BNRItem *p = [[[BNRItemStore defaultStore] allItems]
                                    objectAtIndex:[indexPath row]];
    [[cell textLabel] setText:[p description]];
    return cell;
}
@end

 


提高性能的一些做法(以后再详细说明):

滚动表视图时引发性能问题的不是解析nib文件,而 是要渲染多个子视图。当 UITableViewCell 拥有多个子视图时,iOS 的渲染机制会拖慢速度。 因此,代码生成的 UI 并不是要将 addSubView:方法放到 initWithStyle:reuseIdentifier 方法那里,而是要重写 drawRect 方法并以直接绘制内容的方式代替使用子视图。减少子视图(尤其是半透明的或下方还混有其他视图的)可以提高性能。


UITableViewCell
渲染方法中要避免的东西

绘制时要避免分配资源,包括 NSDateFormatterUIFont或任何在绘制时需要的对象。可以在类层级的初始化方法中执行分配工作,并将其存储为静态变量,并对每个表单元实例使用这个 静态变量。



到目前为止这些都是挺简单的东西,下节我们要介绍好玩的东西,CALayer

posted on 2013-05-07 20:57  一路转圈的雪人  阅读(2286)  评论(1编辑  收藏  举报