博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UITableView介绍 之 复杂cell的高度计算
阅读量:6953 次
发布时间:2019-06-27

本文共 7257 字,大约阅读时间需要 24 分钟。

复杂cell的高度计算

  • 实现了多行文字的自适应
  • 实现了图文混排的自适应

20160312224113988

  在我的日常开发中经常会遇到cell内容比较复杂的情况,复杂的cell势必会有cell高度不相同的情况,这种需求往往是比较蛋疼的。但是没关系只要掌握了其中的原理剩下的就只是体力活了。本文采用传统方式纯代码布局来计算cell的高度值,如果精力允许下篇介绍AutoLayout自动布局下的cell高度的计算。

ViewController中的主要代码实现

为了方便起见本ViewController继承自UITableViewController具体实现代码如下:

////  MTableViewController.m//  cell计算////  Created by code_xq on 16/3/12.//  Copyright © 2016年 code_xq. All rights reserved.//#import "MTableViewController.h"#import "MTableViewCell.h"#import "DataModel.h"static NSString *ID = @"cell";@interface MTableViewController ()@property (nonatomic, strong) NSMutableArray *dataSource;@end@implementation MTableViewController- (void)viewDidLoad {    [super viewDidLoad];        self.title = @"cell的高度计算";    // 去除tableView的默认下划线    self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;    self.tableView.backgroundColor = [UIColor colorWithWhite:0.9 alpha:0.9];        // 注册cell    [self.tableView registerClass:[MTableViewCell class] forCellReuseIdentifier:ID];        // 异步获取数据    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{        NSString *path = [[NSBundle mainBundle] pathForResource:@"cellList.plist" ofType:nil];        NSArray *array = [NSArray arrayWithContentsOfFile:path];                for (NSDictionary *dict in array) {            DataModel *dm = [DataModel initWith:dict];            [self.dataSource addObject:dm];        }        // 造数据        [self.dataSource addObjectsFromArray:self.dataSource];        // 在主线程中刷新数据        dispatch_async(dispatch_get_main_queue(), ^{            [self.tableView reloadData];        });    });}#pragma mark - Table view data source- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {    return self.dataSource.count;}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {    MTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID forIndexPath:indexPath];    cell.selectionStyle = UITableViewCellSelectionStyleNone;    cell.dataModel = self.dataSource[indexPath.row];    return cell;}- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {    DataModel *dm = self.dataSource[indexPath.row];    return dm.cellHeight;}/** *  给出cell的估计高度,主要目的是优化cell高度的计算次数 */- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {    return 200;}/** * 初始化数据 */- (NSMutableArray *)dataSource {    if (_dataSource == nil) {        _dataSource = [NSMutableArray array];    }        return _dataSource;}@end

这段代码是初始化tableView的常规做法,值得注意的是UITableView的

estimatedHeightForRowAtIndexPath 这个方法给出cell的预估值,如果没有实现这个方法,tableView内部会一次性将所有的cell的高度全部计算出来,有了这个方法会对tableView的性能有所提高,这个方法的返回值理论上可以是任意值。

Model数据的代码实现

////  DataModel.h//  cell计算////  Created by code_xq on 16/3/12.//  Copyright © 2016年 code_xq. All rights reserved.//#import 
@interface DataModel : NSObject/** 文字内容 */@property (nonatomic, copy) NSString *text;/** 图标*/@property (nonatomic, copy) NSString *icon;/** 图片*/@property (nonatomic, copy) NSString *picture;/** 用户名*/@property (nonatomic, strong) NSString *name;/** cell的高度*/@property (nonatomic, assign) CGFloat cellHeight;+ (instancetype)initWith:(NSDictionary *)dict;@end/***********************类的实现*********************/#import "DataModel.h"@implementation DataModel+ (instancetype)initWith:(NSDictionary *)dict { DataModel *dm = [[self alloc] init]; [dm setValuesForKeysWithDictionary:dict]; return dm;}@end

数据是从plist中获取直接转换成DataModel对象的,这里多了一个cellHeight的属性用来存放cell的高度。

重头戏自定义cell的代码实现

////  MTableViewCell.h//  cell计算////  Created by code_xq on 16/3/12.//  Copyright © 2016年 code_xq. All rights reserved.//#import 
@class DataModel;@interface MTableViewCell : UITableViewCell/** 数据模型*/@property (nonatomic, strong) DataModel *dataModel;@end/***********************类的实现*********************/#import "MTableViewCell.h"#import "UIView+Expand.h"#import "DataModel.h"#define SCWIDTH [UIScreen mainScreen].bounds.size.width#define SCHEIGHT [UIScreen mainScreen].bounds.size.heightstatic CGFloat const margin = 10;@interface MTableViewCell()@property (nonatomic, weak) UIImageView *imageIcon;@property (nonatomic, weak) UILabel *labelName;@property (nonatomic, weak) UILabel *labelContent;@property (nonatomic, weak) UIImageView *picView;@end@implementation MTableViewCell- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { [self setUpView]; } return self;}- (void)setUpView { // 用户头像 UIImageView *imageIcon = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 50, 50)]; imageIcon.left = margin; imageIcon.top = margin; self.imageIcon = imageIcon; [self.contentView addSubview:imageIcon]; // 用户名 CGFloat nameW = SCWIDTH - imageIcon.width - 3 * margin; UILabel *labelName = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, nameW, 30)]; labelName.left = imageIcon.right + margin; labelName.top = margin; labelName.font = [UIFont systemFontOfSize:20]; self.labelName = labelName; [self.contentView addSubview:labelName]; // 文字内容 UILabel *labelContent = [[UILabel alloc] initWithFrame:CGRectMake(margin, 0, SCWIDTH - 20 , 30)]; labelContent.top = imageIcon.bottom + margin; // 设置显示多行文字 labelContent.lineBreakMode = NSLineBreakByCharWrapping; labelContent.numberOfLines = 0; labelContent.font = [UIFont systemFontOfSize:15]; self.labelContent = labelContent; [self.contentView addSubview:labelContent]; // 图片 UIImageView *picView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 120, 90)]; picView.left = margin; self.picView = picView; [self.contentView addSubview:picView];}- (void)setFrame:(CGRect)frame { frame = CGRectMake(frame.origin.x, frame.origin.y + 10, frame.size.width, frame.size.height - 10); [super setFrame:frame];}- (void)setDataModel:(DataModel *)dataModel { _dataModel = dataModel; // 设置用户头像 self.imageIcon.image = [UIImage imageNamed: dataModel.icon]; // 设置用户名 self.labelName.text = dataModel.name; // 计算文字内容的高度 CGFloat height = [dataModel.text boundingRectWithSize:CGSizeMake(SCWIDTH - 2 * margin, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : self.labelContent.font} context:nil].size.height; self.labelContent.height = height; self.labelContent.text = dataModel.text; // 设置图片内容 if (dataModel.picture) { self.picView.hidden = NO; self.picView.top = self.labelContent.bottom + margin; self.picView.image = [UIImage imageNamed:dataModel.picture]; dataModel.cellHeight = self.picView.bottom + 2 * margin; } else { self.picView.hidden = YES; dataModel.cellHeight = self.labelContent.bottom + 2 * margin; } }@end

为了布局方便自己给UIView写了个分类可以很容易获取view的left、top、right、bottom的值,好了到此复杂cell的高度计算就讲完了,如果有机会继续讲述AutoLayout自动布局下的cell高度的计算。

转载于:https://www.cnblogs.com/code-xq/p/5270932.html

你可能感兴趣的文章
JavaScript基本概念
查看>>
servlet和Struts2的线程安全性对比
查看>>
Android应用开发SharedPreferences存储数据的使用方法
查看>>
[2615]传纸条 sdutOJ
查看>>
ueditor 添加微软雅黑字体 异常“从客户端中检测到有潜在危险的 request.form值”,解决...
查看>>
Android 截取当前界面
查看>>
解决 Oracle10g安装过程中"无法确定主机的IP地址时产生该异常错误"
查看>>
测试安排
查看>>
数据库insert和update
查看>>
通过出生日期获取年龄的方法--Java
查看>>
零基础编程指南(By Turtle)
查看>>
Python学习笔记
查看>>
轻快PDF阅读器绿色版免费下载
查看>>
6.控制流语句_条件控制if
查看>>
java.net.SocketException四大异常解决方案
查看>>
Content作用
查看>>
安装courier-authlib找不到mysqlclient.so文件
查看>>
第3章 文件操作(2 标准I/O库)
查看>>
java输出九九乘法口诀表
查看>>
WebSocket数据帧和各种操作码
查看>>