1、自定义非等高 Cell介绍

  • 1.1 代码自定义(frame)

    • 新建一个继承自 UITableViewCell 的类。
    • 重写 initWithStyle:reuseIdentifier: 方法。
      • 添加所有需要显示的子控件(不需要设置子控件的数据和 frame, 子控件要添加到 contentView 中)。
      • 进行子控件一次性的属性设置(有些属性只需要设置一次, 比如字体\固定的图片)。
    • 提供 2 个模型。
      • 数据模型: 存放文字数据\图片数据。
      • frame 模型: 存放数据模型\所有子控件的 frame\cell 的高度。
    • cell 拥有一个 frame 模型(不要直接拥有数据模型)。
    • 重写 cell frame 模型属性的 setter 方法: 在这个方法中设置子控件的显示数据和 frame。
    • frame 模型数据的初始化已经采取懒加载的方式(每一个 cell 对应的 frame 模型数据只加载一次)。
  • 1.2 代码自定义(Autolayout)

    • 新建一个继承自 UITableViewCell 的类。
    • 重写 initWithStyle:reuseIdentifier: 方法。
      • 添加所有需要显示的子控件(不需要设置子控件的数据和 frame, 子控件要添加到 contentView 中)。
      • 进行子控件一次性的属性设置(有些属性只需要设置一次, 比如字体\固定的图片)。
    • 设置 cell 上子控件的约束。
    • 在模型中增加一个 cellHeight 属性,用来存放对应 cell 的高度。
    • 在 cell 的模型属性 set 方法中调用 [self layoutIfNeed] 方法强制布局,然后计算出模型的 cellheight 属性值。
    • 在控制器中实现 tableView:estimatedHeightForRowAtIndexPath: 方法,返回一个估计高度,比如 200。
    • 在控制器中实现 tableView:heightForRowAtIndexPath: 方法,返回 cell 的真实高度(模型中的 cellHeight 属性)。

2、代码

  • 2.1 XMGStatus.h

@interface XMGStatus : NSObject@property (strong, nonatomic) NSString *name;
@property (strong, nonatomic) NSString *text;
@property (strong, nonatomic) NSString *icon;
@property (strong, nonatomic) NSString *picture;
@property (assign, nonatomic, getter=isVip) BOOL vip;/** cell 的高度 */
@property (assign, nonatomic) CGFloat cellHeight;+ (instancetype)statusWithDict:(NSDictionary *)dict;@end
  • 2.2 XMGStatus.m

@implementation XMGStatus+ (instancetype)statusWithDict:(NSDictionary *)dict {XMGStatus *status = [[self alloc] init];[status setValuesForKeysWithDictionary:dict];return status;
}@end
  • 2.3 XMGStatusCell.h

@class XMGStatus;@interface XMGStatusCell : UITableViewCell+ (instancetype)cellWithTableView:(UITableView *)tableView;/** 模型数据 */
@property (nonatomic, strong) XMGStatus *status;@end
  • 2.4 XMGStatusCell.m

#define MAS_SHORTHAND
#define MAS_SHORTHAND_GLOBALS#import "Masonry.h"@interface XMGStatusCell()@property (weak, nonatomic) UIImageView *iconView;
@property (weak, nonatomic) UILabel *nameLabel;
@property (weak, nonatomic) UIImageView *vipView;
@property (weak, nonatomic) UILabel *contentLabel;
@property (weak, nonatomic) UIImageView *pictureView;@end@implementation XMGStatusCell+ (instancetype)cellWithTableView:(UITableView *)tableView {static NSString *ID = @"status";XMGStatusCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];if (cell == nil) {cell = [[XMGStatusCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];}return cell;
}- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {UIImageView *iconView = [[UIImageView alloc] init];[self.contentView addSubview:iconView];self.iconView = iconView;UILabel *nameLabel = [[UILabel alloc] init];[self.contentView addSubview:nameLabel];self.nameLabel = nameLabel;UIImageView *vipView = [[UIImageView alloc] init];[self.contentView addSubview:vipView];self.vipView = vipView;UILabel *contentLabel = [[UILabel alloc] init];contentLabel.numberOfLines = 0;// 设置 label 每一行文字的最大宽度contentLabel.preferredMaxLayoutWidth = [UIScreen mainScreen].bounds.size.width - 20;[self.contentView addSubview:contentLabel];self.contentLabel = contentLabel;UIImageView *pictureView = [[UIImageView alloc] init];[self.contentView addSubview:pictureView];self.pictureView = pictureView;}return self;
}- (void)layoutSubviews {[super layoutSubviews];CGFloat margin = 10;[self.iconView makeConstraints:^(MASConstraintMaker *make) {make.size.equalTo(30);make.left.top.offset(margin);}];[self.nameLabel makeConstraints:^(MASConstraintMaker *make) {make.top.equalTo(self.iconView);make.left.equalTo(self.iconView.right).offset(margin);}];[self.vipView makeConstraints:^(MASConstraintMaker *make) {make.size.equalTo(14);make.left.equalTo(self.nameLabel.right).offset(margin);make.centerY.equalTo(self.nameLabel.centerY);}];[self.contentLabel makeConstraints:^(MASConstraintMaker *make) {make.top.equalTo(self.iconView.bottom).offset(margin);make.left.offset(margin);//        make.right.offset(-margin);       // 可加可不加}];[self.pictureView makeConstraints:^(MASConstraintMaker *make) {make.size.equalTo(100);make.top.equalTo(self.contentLabel.bottom).offset(margin);make.left.offset(margin);}];
}- (void)setStatus:(XMGStatus *)status {_status = status;// 设置显示的数据self.iconView.image = [UIImage imageNamed:status.icon];self.nameLabel.text = status.name;if (status.isVip) {self.nameLabel.textColor = [UIColor orangeColor];self.vipView.hidden = NO;} else {self.nameLabel.textColor = [UIColor blackColor];self.vipView.hidden = YES;}self.contentLabel.text = status.text;if (status.picture) {self.pictureView.hidden = NO;self.pictureView.image = [UIImage imageNamed:status.picture];} else {self.pictureView.hidden = YES;}// 计算 cell 高度// 强制布局[self layoutIfNeeded];// 计算 cell 的高度if (self.pictureView.hidden) {  // 没有配图_status.cellHeight = CGRectGetMaxY(self.contentLabel.frame) + 10;} else {                        // 有配图_status.cellHeight = CGRectGetMaxY(self.pictureView.frame) + 10;}
}@end
  • 2.5 XMGStatusesViewController.m

@interface XMGStatusesViewController ()@property (strong, nonatomic) NSArray *statuses;@end@implementation XMGStatusesViewController- (NSArray *)statuses {if (_statuses == nil) {// 加载plist中的字典数组NSString *path = [[NSBundle mainBundle] pathForResource:@"statuses.plist" ofType:nil];NSArray *dictArray = [NSArray arrayWithContentsOfFile:path];// 字典数组 -> 模型数组NSMutableArray *statusArray = [NSMutableArray array];for (NSDictionary *dict in dictArray) {XMGStatus *status = [XMGStatus statusWithDict:dict];[statusArray addObject:status];}_statuses = statusArray;}return _statuses;
}#pragma mark - Table view data source- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {return self.statuses.count;
}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {XMGStatusCell *cell = [XMGStatusCell cellWithTableView:tableView];cell.status = self.statuses[indexPath.row];return cell;
}#pragma mark - 代理方法
// 返回每一行的高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {XMGStatus *staus = self.statuses[indexPath.row];return staus.cellHeight;
}/**
* 返回每一行的估计高度
* 只要返回了估计高度,那么就会先调用 tableView:cellForRowAtIndexPath: 方法创建 cell,
* 再调用 tableView:heightForRowAtIndexPath: 方法获取 cell 的真实高度
*/
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {return 200;
}@end
  • 2.6 运行效果图

  • ---

3、其它设置方式

  • 3.1 计算方式

    • BookModel.h
    @property(nonatomic, copy)NSString *title;
    @property(nonatomic, copy)NSString *detail;
    @property(nonatomic, copy)NSString *icon;
    @property(nonatomic, copy)NSString *price;
    • BookCell.h
    @property(nonatomic, retain)UILabel *titleLabel;
    @property(nonatomic, retain)UILabel *detailLabel;
    @property(nonatomic, retain)UIImageView *iconView;
    @property(nonatomic, retain)UILabel *priceLabel;
    • 设置行高
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {// 从数据源数组中取出数据BookModel *bookModel = [myDataArray objectAtIndex:indexPath.row];// 计算 detailLabel 占用的高度CGFloat detialHeight = [bookModel.detail boundingRectWithSize:CGSizeMake(self.view.bounds.size.width - 40, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: [UIFont systemFontOfSize:14]} context:nil].size.height;// 判断是否有图片if (bookModel.icon.length) {// 60 为图片的高度return 30 + detialHeight + 60 + 30;}else {return 30 + detialHeight + 30;}
    }
    • 设置每一行显示的内容
    // 设置每一行显示的内容
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {BookCell3 *cell = [tableView dequeueReusableCellWithIdentifier:@"test" forIndexPath:indexPath];BookModel *bookModel = [myDataArray objectAtIndex:indexPath.row];// 设置 titleLabelcell.titleLabel.text = bookModel.title;// 设置 detailLabel// 计算 detailLabel 的高度CGSize detialSize = [bookModel.detail boundingRectWithSize:CGSizeMake(self.view.bounds.size.width - 40, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: [UIFont systemFontOfSize:14]} context:nil].size;CGRect detialFrame = cell.detailLabel.frame;detialFrame.size.height = detialSize.height + 5;    // 加偏移量 5,适应标点无法换行detialFrame.size.width = detialSize.width + 5;cell.detailLabel.frame = detialFrame;               // 设置 detailLabel 的 framecell.detailLabel.text = bookModel.detail;// 判断是否有图片if (bookModel.icon.length) {// 设置 iconViewCGRect iconFrame = cell.iconView.frame;iconFrame.origin.y = detialFrame.origin.y + detialFrame.size.height;cell.iconView.frame = iconFrame;cell.iconView.image = [UIImage imageNamed: bookModel.icon];// 设置 priceLabelCGRect priceFrame = cell.priceLabel.frame;priceFrame.origin.y = iconFrame.origin.y + iconFrame.size.height;cell.priceLabel.frame = priceFrame;cell.priceLabel.text = bookModel.price;}else {// 设置 priceLabelCGRect priceFrame = cell.priceLabel.frame;priceFrame.origin.y = detialFrame.origin.y + detialFrame.size.height;cell.priceLabel.frame = priceFrame;cell.priceLabel.text = bookModel.price;}return cell;
    }
  • 3.2 系统自动布局方式

    • 自适应 cell 中较高的一个视图的高度。
    • ImageView 与 Label 同行显示,且都设置了上下边缘约束,ImageView 的图片填充模式为 Aspect Fit,否则图片将会被拉长。
    • 协议方法 方式设置
      ``` Objective-C
      // 动态设置行高
    • (CGFloat)tableView:(UITableView )tableView estimatedHeightForRowAtIndexPath:(NSIndexPath )indexPath {

      /
      行高自适应 Label 高度
      /

      secondTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"secondTableViewCell" forIndexPath:indexPath];

      cell.secondLabel.text = [_labelArray objectAtIndex:indexPath.row];

      return [cell.contentView systemLayoutSizeFittingSize:(UILayoutFittingCompressedSize)].height + 1;
      }

    // 属性变量 方式设置
    self.tableView.estimatedRowHeight = 80;
    self.tableView.rowHeight = UITableViewAutomaticDimension;
    ```

转载于:https://www.cnblogs.com/CH520/p/9420417.html

自定义非等高 Cell相关推荐

  1. 非等高cell实战(01)-- 实现微博页面

    非等高cell实战(01)-- 实现微博页面 学习过UITableView.AutoLayout以及MVC的相关知识,接下来通过一个微博页面实战来整合一下. 首先看一下效果图: 需求分析 此页面为非等 ...

  2. 非等高cell实战--实现微博页面

    代码地址如下: http://www.demodashi.com/demo/11639.html 前言 学习过UITableView.AutoLayout以及MVC的相关知识,接下来通过一个微博页面实 ...

  3. 【Android 应用开发】 自定义组件 宽高适配方法, 手势监听器操作组件, 回调接口维护策略, 绘制方法分析 -- 基于 WheelView 组件分析自定义组件

    博客地址 : http://blog.csdn.net/shulianghan/article/details/41520569 代码下载 : -- GitHub : https://github.c ...

  4. R语言ggplot2可视化绘制线图(line plot)、使用gghighlight包突出高亮满足条件的线图、并保留其它线图的色彩(而不是灰色)自定义非高亮线图的透明度

    R语言ggplot2可视化绘制线图(line plot).使用gghighlight包突出高亮满足条件的线图.并保留其它线图的色彩(而不是灰色)自定义非高亮线图的透明度 目录

  5. 纯代码计算不等高cell

    不等高cell纯代码: 对应的GitHub 项目链接:https://github.com/liminting/CalculateCellDemo 不等高cell - 先设置高度rowH = 250 ...

  6. akka框架——异步非阻塞高并发处理框架

    akka actor, akka cluster akka是一系列框架,包括akka-actor, akka-remote, akka-cluster, akka-stream等,分别具有高并发处理模 ...

  7. SpringBoot基于AOP实现自定义非空验证的注解

    为了避免对大量参数进行过多的非空校验,我们可以自定义一个非空验证的注解,因为spring自带的@RequestParam并不能对参数进行非空 准备工作 首先需要创建一个spring boot项目,并引 ...

  8. android view设置按钮颜色_Android 酷炫自定义 View:高仿 QQ 窗帘菜单

    作者:大公爵 链接:https://www.jianshu.com/p/cdb3d373fe37 介绍 不知道大家是否有印象,QQ 曾经有个版本用到了一种双向侧拉菜单,就像窗帘一样可以两边开合,并且伴 ...

  9. 让自定义view宽高成比例显示

    有时候我们自定义一个View,比如ImageView,我们需要让它宽高按照一定的比例显示,例如在ImageView在GridView中显示,GridView设置了3列,由于ImageVIew的宽度会根 ...

最新文章

  1. (原创)按照一定的格式生成一定数量的随机数的例子
  2. No overload for 'OnStartup' matches delegate 'System.Windows.StartupEventHandler'
  3. Not so Mobile(二叉树递归输入同时建树){天平}
  4. NSIS脚本语言安装与编译
  5. FastCGI - Writing Hello World in FCGI with C++
  6. 有多个正整数存放在数组中,编写一个函数要求偶数在左边由小到大顺序放置,奇数在右边,也是由小到大顺序放置,Java实现...
  7. Dns信息收集工具集合
  8. VS2008引用webservice的奇怪BUG解决方案
  9. 发那科机器人注油_安川机器人加油保养流程
  10. 什么是QCIF? CIF?2CIF?4CIF?DCIF?
  11. ARM学习(8) axf 工具解析
  12. 配置多用户连接k8s
  13. 滴滴打车CTO张博:生死战役,技术和时间赛跑
  14. 定理在数学中的简写形式_数学公式定理中的特殊符号含义及读法
  15. 视觉伺服入门第二步:带你从经典论文阅读Visual Servo Control Part II: Advanced Approaches进阶版
  16. 快速寻找研究方向+发文章的方法!!按头安利!
  17. unity中3D数学相关类、属性、方法、用途总结+超级综合的案例
  18. 税务会计实务【13】
  19. Win10右键文件无响应崩溃
  20. POI导出Excel设置单元格背景色

热门文章

  1. 4 通讯_鼎信通讯:2019年净利润同比下降20.58% 拟10转4派1.04元
  2. 【文本分类】基于改进CHI和PCA的文本特征选择
  3. Navicat 2003-can't connect to MYSQL server on 'localhost'(10061)
  4. 大数据学习笔记二:Ubuntu/Debian 下安装大数据框架Hadoop
  5. php多个域名301重定向到主域名代码,Nginx 301和apache重定向域名规则方法(多个域名,单个域名)...
  6. php mysql sample,GitHub - BensonWuu/php-apache-mysql-sample
  7. java 简单 语言_将简单的表达式语言放入java中
  8. php程序耗时是负数,php 代码测试,代码越在前面越耗时
  9. canal下载 linux_canal实时同步mysql数据到redis或ElasticSearch
  10. 未找到要求的 from 关键字_莫纳什大学要求