复杂cell的高度计算

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

  在我的日常开发中经常会遇到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 <UIKit/UIKit.h>@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 <UIKit/UIKit.h>
@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:NSStringDrawingUsesLineFragmentOriginattributes:@{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

UITableView介绍 之 复杂cell的高度计算相关推荐

  1. 1014-34-首页15-计算原创微博的frame------计算cell的高度---计算 UILabel 的 CGSize 的方法...

    一.总体思路: 在控制器中,每次拿到数据模型(请求了数据.加载新微博)的时候,就调用 - (NSArray *)stausFramesWithStatuses:(NSArray *)statuses, ...

  2. ios15使用纯代码计算cell的高度

    ios15使用纯代码计算cell的高度 #import "MTableViewController.h" #import "MTableViewCell.h" ...

  3. UITableview高度计算

    2019独角兽企业重金招聘Python工程师标准>>> 方法1:iOS8的自动计算 此方法必须使用autolayout,这里我是用的xib设置的,也可以使用第三方框架masonry设 ...

  4. iOS开发总结-UITableView 自定义cell和动态计算cell的高度

    UITableView cell自定义头文件: shopCell.h #import <UIKit/UIKit.h> @interface shopCell : UITableViewCe ...

  5. [性能优化]UITableView性能优化的一点感悟及计算UILabel高度的新方法

    前言  在使用过程中发现,我们App的首页在快速滑动时会出现掉帧,以及在上拉加载更多时会抖动,因为首页模块是以前的同事写的,很多代码已不适应当前的需求,所以产生了优化的想法,优化主要分为以下几个方面: ...

  6. [性能优化]UITableView性能优化的一点感悟及计算UILabel高度的新方法 1

    前言 在使用过程中发现,我们App的首页在快速滑动时会出现掉帧,以及在上拉加载更多时会抖动,因为首页模块是以前的同事写的,很多代码已不适应当前的需求,所以产生了优化的想法,优化主要分为以下几个方面: ...

  7. ios开源框架——UITableView+FDTemplateLayoutCell优化UITableViewCell高度计算

    前言 这篇文章是我和我们团队最近对UITableViewCell利用AutoLayout自动高度计算和UITableView滑动优化的一个总结.从这篇文章里,你可以读到: UITableView高度计 ...

  8. iOS8新特性 计算 cell 的高度

    http://tutuge.me/2015/08/08/autolayout-example-with-masonry2/ 1.tableview: 自动计算 tableVIew 的 cell 的高度 ...

  9. (0072)iOS开发之UITableViewCell高度自适应探索--cell预估高度

    转载自:http://www.jianshu.com/p/f3609cd9392e 有了预估高度这个先决条件,一切都好说了.我们直接从代码入手. 接下来我们实现一个简单的信息展示功能,如: Demo最 ...

  10. iOS中的长文本高度计算

    很多的时候如果只是要显示一些简单的短文本,比如确定.取消什么的,一个UILabel就足够了. 但是某些情况下,文本较长.包含这些文本的View的高度取决于文本的高度.比如我们常见的 微博.虽然文本所占 ...

最新文章

  1. Android列表控件选项中添加进度框ProgressBar实现
  2. SQL 与oracle数据同步之 链接服务器
  3. 可持久化线段树——主席树
  4. [概统]本科二年级 概率论与数理统计 第五讲 二元随机变量
  5. 不要和Java“结婚”
  6. NPOI随笔——图片在单元格等比缩放且居中显示
  7. 鹤峰:美丽的茶乡——人物篇
  8. ELK之日志收集filebeat,并对nginx,tomcat access日志JSON格式化
  9. 永不改变的PCB设计黄金法则
  10. Uniswap V3的流通性突破5亿美元,24小时交易量仅次于V2和Sushiswap
  11. Spring源代码分析-Persist--JdbcTemplate
  12. 看〈走出软件作坊〉浅谈扁平化管理
  13. c语言getch函数_在C / C ++中使用getch()函数
  14. HALCON学习笔记 1
  15. c语言timer linux 回调函数_SetTimer 与 回调函数
  16. ipad服务器响应超时,iPad Air连接iTunes设备超时
  17. 如何将标准地图服务中的eps格式中国地图应用到论文中带审图号的地图制作?(二)
  18. 360主机卫士正式上线
  19. Flutter开发:使用SafeArea(安全区域)
  20. JavaScript/Js 大全

热门文章

  1. NSObject的hash方法
  2. 实验5 数独游戏界面设计
  3. JavaMail简单版实验测试
  4. eclipse远程发布代码的方法(SSH自动同步)
  5. struts2要点总结
  6. 手機短信阻擊中國化工項目
  7. 墨者学院——密码学加解密实训(Base64转义)
  8. ADF文件数据结构解析和ADF文件读写
  9. ComponentOne 2016 年产品规划
  10. DIY_DE2之DM9000A网卡调试系列例程(一)——准备工作