UI基础 - UITableView 02:单元格定制 | 自适应高度

■ 单元格定制

1. 系统的 UITableViewCell 通常不能满足自身的 UI 设计效果,那么一般有两条路可走

要么是修改系统自身的 cell

要么是使用 UITableViewCell 的子类

2. 代码示例:实现单元格定制

方式一:在控制器中当 cell 创建时直接修改

// - ViewController

 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.view.backgroundColor = [UIColor cyanColor];
11 
12     self.navigationItem.title = @"cell定制";
13     
14     UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0,self.view.frame.size.width, self.view.frame.size.height) style:UITableViewStylePlain];
15     tableView.separatorColor = [UIColor blueColor];
16     tableView.dataSource = self;
17     tableView.delegate = self;
18     [self.view addSubview:tableView];
19 }
20 
21 #pragma mark - <UITableViewDataSource>
22 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
23     switch (section) {
24         case 0:return 3;
25         case 1:return 5;
26         case 2:return 8;
27     }
28     return 0;
29 }
30 
31 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
32     return 3;
33 }
34 
35 // cell
36 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
37 
38     static NSString * cellIndentifier = @"cell";
39     UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:cellIndentifier];
40 
41     // cell 定制:cell 初始化一定要在创建时进行
42     if (!cell) {
43 
44         cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIndentifier];
45 
46         // 右按钮
47         UIButton *rightBT = [UIButton buttonWithType:UIButtonTypeRoundedRect];
48         rightBT.frame = CGRectMake(220, 10, 100, 30);
49         [rightBT setTitle:@"right" forState:UIControlStateNormal];
50         [cell.contentView addSubview:rightBT];
51 
52         // 左标提
53         UILabel *leftLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 100, 30)];
54         leftLabel.tag = 103;// 赋值使用
55         leftLabel.backgroundColor = [UIColor redColor];
56         [cell.contentView addSubview:leftLabel];
57     }
58     
59     // 左标题赋值
60     UILabel *leftLab = (UILabel*)[cell.contentView viewWithTag:103];// 获取到 Label
61     leftLab.text = [NSString stringWithFormat:@"%ld",indexPath.row];// 赋值
62 
63     return cell;
64 }
65 
66 - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
67 
68     return [[NSArray arrayWithObjects:@"-A-",@"-B-",@"-C-",nil] objectAtIndex:section];
69 }
70 
71 
72 - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView{
73 
74     return @[@"A",@"B",@"C"];
75 }
76 
77 #pragma mark - <UITableViewDelegate>
78 - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
79 
80     return 10;
81 }
82 
83 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
84 
85     return 50;
86 }
87 
88 @end

运行效果

方式二:在控制器中直接修改单元格会使代码冗余且分散!接下来我们使用 UITableViewCell 的子类实现单元格定制,降低代码耦合度,并对其做自适应高度处理

// - MakeCell.h

1 #import <UIKit/UIKit.h>
2 #define W_Text  [UIScreen mainScreen].bounds.size.width - 20
3 @interface MakeCell : UITableViewCell
4 @property(nonatomic,strong)UILabel *contenLabel;// 文本内容
5 
6 @end

// - MakeCell.m

 1 #import "MakeCell.h"
 2 @implementation MakeCell
 3 
 4 - (void)awakeFromNib {
 5     [super awakeFromNib];
 6 }
 7 
 8 - (void)setSelected:(BOOL)selected animated:(BOOL)animated {
 9     [super setSelected:selected animated:animated];
10 }
11 
12 // 重写方法:在里面初始化控件
13 -(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
14 
15     self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
16     if (self) {
17 
18         self.contenLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, W_Text, 60)];
19         self.contenLabel.backgroundColor = [UIColor orangeColor];
20         self.contenLabel.font = [UIFont systemFontOfSize:15.0];
21         self.contenLabel.numberOfLines = 0;// 不限行
22         self.contenLabel.lineBreakMode = NSLineBreakByWordWrapping;
23         [self.contentView addSubview:self.contenLabel];
24         
25         self.contentView.backgroundColor = [UIColor cyanColor];
26         
27     }
28     return self;
29 }
30 
31 // 高度自适应:步骤一
32 // 在 layoutSubviews 处理自适应,减少 VC 中的代码量
33 -(void)layoutSubviews{
34     [super layoutSubviews];
35 
36     /* 自适应高度步骤
37      *   1、字号和换行模式,要保持一致
38      *   2、高度自适应实际上是指定宽度且高度足够大
39     */
40     NSString *text = self.contenLabel.text;
41     // 宽度 300,高度管够
42     CGSize textSize = [text sizeWithFont:[UIFont systemFontOfSize:15.0] constrainedToSize:CGSizeMake(W_Text, 10000) lineBreakMode:NSLineBreakByWordWrapping];
43     CGRect rect = self.contenLabel.frame;
44     rect.size.height = textSize.height;
45     self.contenLabel.frame = rect;
46 }
47 @end

// - ViewController.h

 1 #import "ViewController.h"
 2 #import "MakeCell.h"
 3 @interface ViewController ()<UITableViewDataSource,UITableViewDelegate>
 4 @property(nonatomic,strong)NSArray *dataArray;// 数据源
 5 
 6 @end
 7 
 8 @implementation ViewController
 9 
10 - (void)viewDidLoad {
11     [super viewDidLoad];
12     self.navigationItem.title = @"高度自适应";
13     
14     // 数据源
15     self.dataArray = [NSArray arrayWithObjects:@"姆大陆土地辽阔,东起现今夏威夷群岛,西至马里亚纳群岛,南边是斐济、大溪地群岛和复活节岛,全大陆东西长8000公里,南北宽5000公里,相当于南北美洲面积的总和,总面积约为3500万平方公里,是一块美丽富饶的地方。今天的人类文明中不可解释的一些现象可能来自于姆大陆人的文明。",
16                       @"雷姆利亚大陆的传说地理位置在今天的印度洋。根据地质学家的推测,雷姆利亚大陆应该是在距今约3400万年前(即第三纪初期)开始沉没的,在约2500万年前完全沉没。",
17                       @"在柏拉图的提示中,有这样的话:“在梭伦九千年前左右,海格力斯之柱(直布罗陀海峡)对面,有一个很大的岛,从那里你们可以去其它的岛屿,那些岛屿的对面,就是海洋包围着的一整块陆地,这就是‘亚特兰蒂斯’王国”。当时亚特兰蒂斯正要与雅典展开一场大战,没想到亚特兰蒂斯却突然遭遇到地震和水灾,不到一天一夜就完全没入海底,成为希腊人海路远行的阻碍。",
18                       @"黄金国(西班牙文:El Dorado,意思为“The Golden One”)别称黄金城、黄金乡,为一个古老传说,最早是始于一个南美仪式,部落族长会在自己的全身涂满金粉,并到山中的圣湖中洗净,而祭司和贵族会将珍贵的黄金和绿宝石投入湖中献给神。",
19                       @"阿瓦隆(Avalon)是亚瑟王传说中的重要岛屿,凯尔特神话的圣地,古老德鲁伊宗教的中心信仰",
20                       @"Bermeja岛:古老的地图上常常出现无法找到的岛屿和大陆板块。其中一些所谓“幽灵岛屿”是由于早期的地理变化而消失,其它的岛屿就像Bermeja一样被认为事实上曾经存在并且由于自然灾难而消失了。古老地图上将Bermeja标记在墨西哥湾,在墨西哥尤卡坦半岛西北100英里的位置。",nil];
21 
22     self.view.backgroundColor = [UIColor whiteColor];
23     UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 64, self.view.frame.size.width, self.view.frame.size.height-64) style:UITableViewStylePlain];
24     tableView.separatorColor = [UIColor blueColor];
25     tableView.dataSource = self;
26     tableView.delegate = self;
27     [self.view addSubview:tableView];
28 }
29 
30 #pragma mark - <UITableViewDataSource>
31 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
32 
33     return self.dataArray.count;
34 }
35 
36 // cell
37 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
38 
39     static NSString *cellIndentifier = @"cell";
40     MakeCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIndentifier];
41     if (!cell) {
42         // 初始化
43         cell = [[MakeCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIndentifier];
44     }
45 
46     NSString *text = [self.dataArray objectAtIndex:indexPath.row];
47     cell.contenLabel.text = text;
48 
49 //    // 高度自适应:步骤一
50 //    // 可优化:把此处代码搬进 layoutSubviews 中处理
51 //    CGSize textSize = [text sizeWithFont:[UIFont systemFontOfSize:15.0] constrainedToSize:CGSizeMake(W_Text, MAXFLOAT) lineBreakMode:NSLineBreakByWordWrapping];
52 //    CGRect rect = cell.contenLabel.frame;
53 //    rect.size.height = textSize.height;
54 //    cell.contenLabel.frame = rect;
55 
56     return cell;
57 }
58 
59 #pragma mark - <UITableViewDelegate>
60 // 高度自适应:步骤二
61 // cell 自适应高度完成后,在代理方法中同样要返回相对应的高度
62 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
63 
64     NSString *text = [self.dataArray objectAtIndex:indexPath.row];
65     CGSize textSize = [text sizeWithFont:[UIFont systemFontOfSize:15.0] constrainedToSize:CGSizeMake(W_Text, MAXFLOAT) lineBreakMode:NSLineBreakByWordWrapping];
66     return textSize.height + 20;
67 }
68 
69 @end

运行效果

 

posted on 2018-04-09 20:29  低头捡石頭  阅读(18)  评论(0编辑  收藏  举报

导航