UI基础 - UITableView 01:基本使用
■ 简言
1. 表视图是 iOS 中最重要的视图,没有之一。它通常用来管理一组具有相同数据结构的数据,并且常与 UINavigationController 结合使用;它可以分区(组)来显示内容:区称为 section;行称为 row
2. 表示图具有 4 种样式
3. UITableView 每行都会放置一个 cell,用来负责显示本行的内容;cell 包含三个部分,默认只显示中间的 ContentView
4. UITableView 靠 mutableSet 来实现重用功能:滚出屏幕的 cell 会被添加到 mutableSet 中;而进入屏幕的 cell,会先从 mutableSet 中获取,如果获取不到,才会创建一个 cell。注:在 cell 显示之前要给 cell 赋上相应的内容且 cell 的 reuseIdentifier 是重用的关键
5. datasource 提供要显⽰的数据;delegate 提供辅助设置
■ 使用方式
// - ViewController.m
1 #import "ViewController.h" 2 @interface ViewController ()<UITableViewDataSource,UITableViewDelegate>// 协议 3 4 @end 5 6 @implementation ViewController 7 8 - (void)viewDidLoad { 9 [super viewDidLoad]; 10 self.navigationItem.title = @"UITableView"; 11 self.view.backgroundColor = [UIColor cyanColor]; 12 13 // StylePlain: 有表格效果 14 // StyleGrouped:无表格效果 15 UITableView * tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height-64) style:UITableViewStylePlain]; 16 tableView.backgroundColor = [UIColor whiteColor]; 17 // 分隔线颜色 18 tableView.separatorColor = [UIColor redColor]; 19 //tableView.separatorStyle = UITableViewCellSeparatorStyleNone;// 分隔线样式 20 //tableView.rowHeight = 60;// 行高默认 40:建议使用代理控制行高 21 22 // 代理 23 tableView.dataSource = self; 24 tableView.delegate = self;// 25 [self.view addSubview:tableView]; 26 // 区头 27 UIScrollView *scrollView01 = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 64)]; 28 scrollView01.contentSize = CGSizeMake(self.view.frame.size.width*5, 100); 29 scrollView01.backgroundColor = [UIColor brownColor]; 30 scrollView01.indicatorStyle = UIScrollViewIndicatorStyleWhite; 31 tableView.tableHeaderView = scrollView01; 32 33 // 区尾 34 UIScrollView *scrollView02 = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 64)]; 35 scrollView02.contentSize = CGSizeMake(self.view.frame.size.width*4, 100); 36 scrollView02.backgroundColor = [UIColor brownColor]; 37 scrollView02.indicatorStyle = UIScrollViewIndicatorStyleWhite; 38 tableView.tableFooterView= scrollView02; 39 40 } 41 42 #pragma mark - <UITableViewDataSource> 43 // 每分区有几行 44 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ 45 switch (section) { 46 case 0: 47 return 3; 48 case 1: 49 return 5; 50 case 2: 51 return 8; 52 } 53 return 0; 54 } 55 56 // 有多少个分区 57 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ 58 return 3; 59 } 60 61 // 创建cell 62 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 63 64 // 重用标识符 65 static NSString *cellIndentifier = @"cellDemoID"; 66 67 // 根据重用标识符从重用的队列中获取是否有可重用的 cell 68 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIndentifier]; 69 if (!cell) { 70 cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIndentifier]; 71 // 选中单元格的样式 72 cell.selectionStyle = UITableViewCellSelectionStyleDefault; 73 // 自定制选中单元格 74 UIView *selectView = [[UIView alloc] initWithFrame:cell.bounds]; 75 selectView.backgroundColor = [UIColor redColor]; 76 cell.selectedBackgroundView = selectView; 77 } 78 79 // 左边图片:若不定制 imageView 的尺寸,则它尺寸随行高而定 80 UIImage *icon = nil; 81 if (indexPath.section == 0) { 82 icon = [UIImage imageNamed:@"001.jpeg"]; 83 }else if (indexPath.section == 1){ 84 icon = [UIImage imageNamed:@"002.jpg"]; 85 }else{ 86 icon = [UIImage imageNamed:@"003.jpg"]; 87 } 88 89 // 重新定制尺寸 90 CGSize itemSize = CGSizeMake(30, 43); 91 UIGraphicsBeginImageContextWithOptions(itemSize, NO ,0.0); 92 CGRect imageRect = CGRectMake(0.0, 0.0, itemSize.width, itemSize.height); 93 [icon drawInRect:imageRect]; 94 cell.imageView.image = UIGraphicsGetImageFromCurrentImageContext(); 95 UIGraphicsEndImageContext(); 96 97 // 辅助按钮 98 switch (indexPath.section) { 99 case 0:{ 100 cell.accessoryType = UITableViewCellAccessoryDetailButton; 101 }break; 102 case 1:{ 103 cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 104 }break; 105 case 2:{ 106 cell.accessoryType = UITableViewCellAccessoryCheckmark; 107 }break; 108 109 default: 110 break; 111 } 112 113 // 行标 114 cell.textLabel.text = [NSString stringWithFormat:@"%ld",indexPath.row]; 115 // cell 的类型会决定 detailTextLabel 显示的位置以及是否可以显示 116 // StyleSubtitle 可显示 StyleDefault 不可显示 117 cell.detailTextLabel.text = [NSString stringWithFormat:@"区:%ld",indexPath.section]; 118 119 return cell; 120 } 121 122 // 区头title 123 - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{ 124 125 return [[NSArray arrayWithObjects:@"-»A",@"-»B",@"-»C",nil] objectAtIndex:section]; 126 } 127 128 // 区尾title 129 - (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section{ 130 131 switch (section) { 132 case 0:return @"A«-"; 133 case 1:return @"B«-"; 134 case 2:return @"C«-"; 135 } 136 return nil; 137 } 138 139 // 分区索引标题 140 - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView{ 141 142 return @[@"A",@"B",@"C"]; 143 } 144 145 #pragma mark - <UITableViewDelegate> 146 -(void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(nonnull NSIndexPath *)indexPath{ 147 148 NSLog(@"选中:row = %ld,section = %ld",indexPath.row,indexPath.section); 149 } 150 151 // 选中某一区的某一行的单元格触发 152 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ 153 154 NSLog(@"选中:row = %ld,section = %ld",indexPath.row,indexPath.section); 155 [tableView deselectRowAtIndexPath:indexPath animated:YES]; 156 } 157 158 // 取消选中某一区的某一行的单元格触发 159 - (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath{ 160 161 NSLog(@"取消:row = %ld,section = %ld",indexPath.row,indexPath.section); 162 } 163 164 // 行高 165 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ 166 167 if (indexPath.row == 0 && indexPath.section == 1) { 168 return 100; 169 } 170 return 60; 171 } 172 173 // 分区高度:头 174 - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ 175 176 switch (section) { 177 case 0:return 20; 178 case 1:return 40; 179 case 2:return 60; 180 } 181 return 10; 182 } 183 184 // 分区高度:尾 185 - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{ 186 187 return 20; 188 } 189 190 191 // 自定义区头视图:自定义区头视图会遮挡 区头title 192 - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ 193 // 这里设置 frame 是无效的 194 // 高度取决于 heightForHeaderInSection方法 195 // UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(25, 25, 22, 22)];// 无效尺寸 196 197 UIScrollView *scrollView = [[UIScrollView alloc] init]; 198 scrollView.contentSize = CGSizeMake(320*5, 50); 199 scrollView.backgroundColor = [UIColor orangeColor]; 200 return scrollView ; 201 } 202 203 @end
运行效果
■ 结语1. 使用 UITableView 时容易遇到的问题
设置 cell 背景颜色有两种方式:通过 backgroundColor 和 backgroundView 都可以实现!但是 backgroundView 优先级要比 backgroundColor 高,所以如果同时设置了 backgroundColor 和 backgroundView,那么 backgroundView 会盖住 backgroundColor
// 方式一 UIView *view = [[UIView alloc] init]; view.backgroundColor = [UIColor blueColor]; cell.backgroundView = view; // 方式二:使用图片设置绚丽的效果 UIImageView *iv = [[UIImageView alloc] initWithImage:[UIImageimageNamed:@"xxx.jpg"]]; cell.backgroundView = iv;
在定义变量用来保存重用标记值时,不推荐使用宏!因为宏定义的定义、使用位置都太分散,不利于阅读程序。况且因为其值不变,我们没有必要每次都开辟一次,所以使用静态变量最为合适