UITableView
上节讲了一下UIView,这节接着讲它的重要子类,UITableView和UITableViewCell
UITableView是UIScrollView的子类,因此用户可以滚动UITableViewCell(UIView的子 类)组成的列表。
UITableView 与 UIScrollView 有很多共同点。对于非数据列表的深度自定义的视图,你可以 使用 UIScrollView 并在里面布置 UIView 或 UIControl 的子类,不过这种情况下使用 UITableView 更有优势。首先,如果可能的话,推荐使用更高级的抽象。其次,UITableView 会自 动实现一些微妙的功能。其中一个是能轻松出列并重用 UITableViewCell单元,这样可以改善性能 并减少内存占用。另一个是通过数据源和接收到的委托方法反馈来填充内容UITableViewController
UITableViewController 是 UIViewController 的子类,它能实现一些与表视图加载有关的额外功能。如果你正在通过一个 nib 文件初始化 UITableViewController,nib 加载机制会从 nib 文 件载入归档的表视图。如果不是的话,则它会创建一个未配置的表视图。这两种情况下你都可以使用 UITableViewController 类的 tableView 属性来访问表视图。
@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里,关系如下图所示:
UITableViewCell是UIView的子类,它给UIView添加了一些能在UITableView中提供帮助的属性与功能。你并不需要手动添加自定义元素,因为 UITableViewCell已经提供了一些常用的元素,比如标题,子标题以及用来显示 textLabel、detailedTextLabel 和 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渲染方法中要避免的东西
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述