iOS分享【OC】—— UITableView 的 cell 自适应

这次跟大家分享的 UITableVIew 的 cell 的自适应,这个 cell 可以是系统自带的,也可以是自定义的 cell。既然如此,那就先定义一个系统cell 的 tableview 页面吧。这次的例子是纯代码操作,Storyboard 和 XIB 的原理也是一样的。

1.系统的 UITableViewCell

#import "ViewController.h"

@interface ViewController () <UITableViewDataSource, UITableViewDelegate>

@property (nonatomic, strong) NSArray *array;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    _array = @[@"日落时分,沏上一杯山茶,听一曲意境空远的《禅》,心神随此天籁,沉溺于玄妙的幻境里。仿佛我就是那穿梭于葳蕤山林中的一只飞鸟,时而盘旋穿梭,时而引吭高歌;仿佛我就是那潺潺流泻于山涧的一汪清泉,涟漪轻盈,浩淼长流;仿佛我就是那竦峙在天地间的一座山峦,伟岸高耸,从容绵延。我不相信佛,只是喜欢玄冥空灵的梵音经贝,与慈悲淡然的佛境禅心,在清欢中,从容幽静,自在安然。一直向往走进青的山,碧的水,体悟山水的绚丽多姿,领略草木的兴衰荣枯,倾听黄天厚土之声,探寻宇宙自然的妙趣。走进了山水,也就走出了喧嚣,给身心以清凉,给精神以沉淀,给灵魂以升华。",
               @"… 公司说实习交税特别高 我就查了一下 总工资减掉百分之二十之后再乘百分之二十就是要交的税 这样一算 正好百分之十六的税",
               @"Uibezierpath是对coregraphic那个画线方法的一个封装 贝塞尔曲线可以画多种图像 线条 配合动画效果可以实现好多酷炫的效果 不过不知道怎么的 有的时候感觉还是graficcontext好使~",
               @"zxczxczxc",
               @"西方人发展科技,给今天的人类造成了五大危机,这五大危机是人类在最近的三十年之内都会面临到的。第一个,缺水。第二个,缺土。第三个,就是缺粮,因为水土不够,粮食一定短缺。第四个,就是缺人。而造成这四大危机的原因只有一个,就是第五个,也是最要紧的,就是缺德。",
               @"是啊,还不如返璞归真呢。那时的天是蓝的,夜晚的星星距离我们“很近”。。道可道,名可名。。不亦乐乎是真情。。。"];
    
    UITableView *myTableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
    myTableView.dataSource = self;
    myTableView.delegate = self;

    // 先估算 cell 的高度,实现自适应高度
    myTableView.rowHeight = UITableViewAutomaticDimension;
    myTableView.estimatedRowHeight = 44.0;

    [self.view addSubview:myTableView];
    [myTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"test"];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.array.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *myCell = [tableView dequeueReusableCellWithIdentifier:@"test" forIndexPath:indexPath];
    myCell.textLabel.text = self.array[indexPath.row];
    myCell.textLabel.numberOfLines = 0;
    return myCell;
}

是的,你没看错,这个 tableview 多定义了两个属性,这两属性:rowHeight 和 estimatedRowHeight,这两个属性是 iOS8以后苹果新增加的,就是为了方便大家定义 cell 高度自适应。estimatedRowHeight 的值就是一个估算的平均值,这个需要我们自己先预估一下,但是不要随意写,个别值会使项目crash,建议最好估算一下。最后就是要设置 textLabel.numberOfLines = 0,把tabel 的多行模式开启。这样就可以使 cell 自适应高度了。

2. 自定义的 TableViewCell

对于自定义的 cell 自适应,需要与约束布局结合使用,Autolayout、Masonry 都可以,这里我用的 Masonry 布局。下面是代码:

MyTableViewCell.m

#import "MyTableViewCell.h"
#import <Masonry.h>

#define WEAKSELF(weakSelf)  __weak __typeof(&*self)weakSelf = self;

@implementation MyTableViewCell

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        self.myLabel = [[UILabel alloc] init];
        self.myLabel.backgroundColor = [UIColor orangeColor];
        self.myLabel.font = [UIFont systemFontOfSize:10];
        self.myLabel.numberOfLines = 0;
        [self.contentView addSubview:_myLabel];
        
        self.otherLabel = [[UILabel alloc] init];
        self.otherLabel.backgroundColor = [UIColor cyanColor];
        self.otherLabel.font = [UIFont systemFontOfSize:16];
        self.otherLabel.numberOfLines = 0;
        [self.contentView addSubview:_otherLabel];
        
        WEAKSELF(weakSelf);
        
        [_myLabel mas_makeConstraints:^(MASConstraintMaker *make) {
            make.width.mas_equalTo(@150);
            make.top.mas_equalTo(weakSelf.contentView.mas_top).offset(5);
            make.left.mas_equalTo(weakSelf.contentView.mas_left).offset(5);
            make.bottom.equalTo(weakSelf.contentView).offset(-5);
            make.right.mas_equalTo(_otherLabel.mas_left).offset(-5);
        }];
        [_otherLabel mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.mas_equalTo(_myLabel.mas_top).offset(0);
            make.left.mas_equalTo(_myLabel.mas_right).offset(5);
            make.bottom.mas_equalTo(weakSelf.contentView.mas_bottom).offset(-5);
            make.right.mas_equalTo(weakSelf.contentView.mas_right).offset(-5);
        }];
    }
    return self;
}
ViewController.m
#import "MyTableViewCell.h"
#import "ViewController.h"

@interface ViewController () <UITableViewDataSource, UITableViewDelegate>

@property (nonatomic, strong) NSArray *array;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    _array = @[@"日落时分,沏上一杯山茶,听一曲意境空远的《禅》,心神随此天籁,沉溺于玄妙的幻境里。仿佛我就是那穿梭于葳蕤山林中的一只飞鸟,时而盘旋穿梭,时而引吭高歌;仿佛我就是那潺潺流泻于山涧的一汪清泉,涟漪轻盈,浩淼长流;仿佛我就是那竦峙在天地间的一座山峦,伟岸高耸,从容绵延。我不相信佛,只是喜欢玄冥空灵的梵音经贝,与慈悲淡然的佛境禅心,在清欢中,从容幽静,自在安然。一直向往走进青的山,碧的水,体悟山水的绚丽多姿,领略草木的兴衰荣枯,倾听黄天厚土之声,探寻宇宙自然的妙趣。走进了山水,也就走出了喧嚣,给身心以清凉,给精神以沉淀,给灵魂以升华。",
               @"… 公司说实习交税特别高 我就查了一下 总工资减掉百分之二十之后再乘百分之二十就是要交的税 这样一算 正好百分之十六的税",
               @"Uibezierpath是对coregraphic那个画线方法的一个封装 贝塞尔曲线可以画多种图像 线条 配合动画效果可以实现好多酷炫的效果 不过不知道怎么的 有的时候感觉还是graficcontext好使~",
               @"zxczxczxc",
               @"西方人发展科技,给今天的人类造成了五大危机,这五大危机是人类在最近的三十年之内都会面临到的。第一个,缺水。第二个,缺土。第三个,就是缺粮,因为水土不够,粮食一定短缺。第四个,就是缺人。而造成这四大危机的原因只有一个,就是第五个,也是最要紧的,就是缺德。",
               @"是啊,还不如返璞归真呢。那时的天是蓝的,夜晚的星星距离我们“很近”。。道可道,名可名。。不亦乐乎是真情。。。"];
    
    UITableView *myTableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
    myTableView.dataSource = self;
    myTableView.delegate = self;

    // 先估算 cell 的高度,实现自适应高度
    myTableView.rowHeight = UITableViewAutomaticDimension;
    myTableView.estimatedRowHeight = 44.0;

    [self.view addSubview:myTableView];
    [myTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"test"];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.array.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    MyTableViewCell *myCell = [tableView dequeueReusableCellWithIdentifier:@"test" forIndexPath:indexPath];
    myCell.myLabel.text = self.array[indexPath.row];
    myCell.otherLabel.text = self.array[indexPath.row];
    return myCell;
}
这里需要注意的是自定义 cell 的定义方式,普通的定义方式,还需要重写父类的 layoutSubviews 方法,并且把布局方式写在 layoutSubviews 这个方法中。但是如果在这种情况下还这么写,就会出现一个问题:启动的时候效果不是自适应的,只有当 cell 进入重用池以后才会自适应高度。原因就是在视图初始化的时候,没有给视图任何约束,一切都是默认的。当视图准备铺出来时,才调用 layoutSubviews 方法,可以一切都晚了,所有的视图都已经是默认大小了,所以刚启动时,cell 并不是自适应的,只有进入重用池再出来,才会自适应。

所以,一定不能按照原来自定义 cell 的方法敲代码,一定要把布局的代码写在初始化中,而且不用重写 layoutSubviews 方法。而且,一定要用约束布局。

最后分享一个自己加工过的计算文本 size 的方法,有时候不是很好用,正在努力修改中,还是先记录下来吧!

- (CGSize)sizeWithString:(NSString *)str font:(UIFont *)font maxSize:(CGSize)maxSize
{
    NSDictionary *attributes = @{NSFontAttributeName : font};
    // 如果将来计算的文字的范围超出了指定的范围,返回的就是指定的范围
    // 如果将来计算的文字的范围小于指定的范围, 返回的就是真实的范围
    CGSize size =  [str boundingRectWithSize:maxSize options:NSStringDrawingUsesFontLeading | NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil].size;
    return size;
}

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值