前两天做了一个项目,中间有遇到一个问题,就是聊天的时候cell高度的问题。这是一个很多前辈都遇到过,并且很完美的解决过的问题。这里主要是记录自己的学习心得。项目中首先想到的是用三方库,可是有问题,遂放弃,自己写一个,但是没有封装。项目地址

  UITableView 的属性特征什么的,这里就暂时不做介绍了。

  由于聊天内容比较简单,不需要对聊天做出很多操作,只是简单的使用 UILable 进行展示即可。首先我们定义一个模型 JXChatModel

//
// JXChatModel.h
// JXAutoCell
//
// Created by 王加祥 on 16/9/28.
// Copyright © 2016年 王加祥. All rights reserved.
// #import <UIKit/UIKit.h> @interface JXChatModel : NSObject
// 字典模型转换
+ (instancetype)modelWithDict:(NSDictionary *)dict;
/** 昵称 */
@property (nonatomic,copy) NSString * nickName;
/** 等级 */
@property (nonatomic,copy) NSString * graide;
/** 内容 */
@property (nonatomic,copy) NSString * content;
/** 高度,用来存放计算后的cell高度 */
@property (nonatomic,assign) CGFloat cellHeight;
@end
//
// JXChatModel.m
// JXAutoCell
//
// Created by 王加祥 on 16/9/28.
// Copyright © 2016年 王加祥. All rights reserved.
// #import "JXChatModel.h" @implementation JXChatModel
+ (instancetype)modelWithDict:(NSDictionary *)dict {
JXChatModel * model = [[self alloc] init];
[model setValuesForKeysWithDictionary:dict];
return model;
} - (void)setValue:(id)value forUndefinedKey:(NSString *)key {
// 这里对没有定义的键值对不进行任何操作
}
@end
  • 自定义 UITableViewCell

  前面我们定义了一个数据模型,当我们请求过来的数据之后,我们首先将数据转换成模型,之后直接将模型赋值给我们自定义的表格,这样做有极大的好处

//
// JXChatCell.h
// JXAutoCell
//
// Created by 王加祥 on 16/9/28.
// Copyright © 2016年 王加祥. All rights reserved.
// #import <UIKit/UIKit.h> @class JXChatModel; @interface JXChatCell : UITableViewCell
/** 模型 */
@property (nonatomic,strong) JXChatModel * model;
@end
//
// JXChatCell.m
// JXAutoCell
//
// Created by 王加祥 on 16/9/28.
// Copyright © 2016年 王加祥. All rights reserved.
// #import "JXChatCell.h"
#import "JXChatModel.h"
#import "Masonry.h" /** 等级图片宽度 */
#define kIconWidth 25
/** 等级图片高度 */
#define kIconHeight 25 #define kWidth [UIScreen mainScreen].bounds.size.width
@interface JXChatCell ()
/** 头像 */
@property (nonatomic,weak) UIImageView * iconImageView;
/** 昵称 */
@property (nonatomic,weak) UILabel * nickNameLabel;
/** 内容 */
@property (nonatomic,weak) UILabel * contentLabel; @end @implementation JXChatCell - (void)setModel:(JXChatModel *)model { NSString * name = [NSString stringWithFormat:@"rank_%@",model.graide];
self.iconImageView.image = [UIImage imageNamed:name]; self.nickNameLabel.text = model.nickName;
[self.nickNameLabel sizeToFit];
CGRect frame = self.nickNameLabel.frame;
frame.size.height = kIconHeight;
self.nickNameLabel.frame = frame; // 设置内容宽度,这里首先在自适应之前需要将内容的宽度固定
self.contentLabel.text = model.content;
CGRect contentFrame = self.nickNameLabel.frame;
contentFrame.size.width = kWidth - kIconWidth - self.nickNameLabel.frame.size.width - ;
self.contentLabel.frame = contentFrame;
[self.contentLabel sizeToFit]; model.cellHeight = CGRectGetMaxY(self.contentLabel.frame) + ; } #pragma mark - 布局
- (void)layoutSubviews {
[super layoutSubviews]; // 等级图片
self.iconImageView.frame = CGRectMake(, , kIconWidth, kIconHeight); // 昵称
self.nickNameLabel.frame = CGRectMake(kIconWidth + , , self.nickNameLabel.frame.size.width, kIconHeight); // 内容大小
self.contentLabel.frame = CGRectMake(CGRectGetMaxX(self.nickNameLabel.frame) + , , self.contentLabel.frame.size.width, self.contentLabel.frame.size.height); }
#pragma mark - 懒加载
- (UIImageView *)iconImageView{
if (_iconImageView == nil) {
UIImageView * iconImageView = [[UIImageView alloc] init];
[self.contentView addSubview:iconImageView];
_iconImageView = iconImageView;
}
return _iconImageView;
} - (UILabel *)nickNameLabel{
if (_nickNameLabel == nil) {
UILabel * nickNameLabel = [[UILabel alloc] init];
nickNameLabel.textColor = [UIColor orangeColor];
nickNameLabel.font = [UIFont systemFontOfSize:13.0];
[self.contentView addSubview:nickNameLabel];
_nickNameLabel = nickNameLabel;
}
return _nickNameLabel;
} - (UILabel *)contentLabel{
if (_contentLabel == nil) {
UILabel * contentLabel = [[UILabel alloc] init];
contentLabel.textColor = [UIColor blackColor];
contentLabel.numberOfLines = ;
contentLabel.font = [UIFont systemFontOfSize:13.0];
[self.contentView addSubview:contentLabel];
_contentLabel = contentLabel;
}
return _contentLabel;
}
@end
  • 控制器部分代码

  在控制器中我们需要操作的就稍微少了点了,这里我们只需要将数据请求下来,然后将数据转换成模型,存到数组中。之后的 UITableView 数据源就根据这个数组来操作

//
// ViewController.m
// JXAutoCell
//
// Created by 王加祥 on 16/9/28.
// Copyright © 2016年 王加祥. All rights reserved.
// 自动计算行高 #import "ViewController.h"
#import "JXChatCell.h"
#import "JXChatModel.h"
@interface ViewController ()<UITableViewDelegate,UITableViewDataSource>
/** 数据源数组 */
@property (nonatomic,strong) NSMutableArray * chatArray;
/** UITableView */
@property (nonatomic,weak) UITableView * tableView;
@end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad]; // 数据
NSArray * array = @[
@{
@"nickName":@"你成佛了",
@"graide":@"",
@"content":@"连接方式李金发欧式24234242342冯绍峰烦死拉伸的减肥了敬爱是骄傲是激发按时发放费;啊; 拉伸放假接方式李反对党的圾费垃圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法lkjslajflsajflasjlasjflajflj零距离圣诞节佛按实际大量积分垃圾地方啦垃圾了房间爱令肌肤拉伸件地方垃圾垃圾了极大浪费就暗恋的激发了设计费垃圾费拉激发偶尔加乱收费来释放接方式李反对党的圾费垃圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法lkjslajflsajflasjlasjflajflj零距离圣诞节佛按实际大量积分垃圾地方啦垃圾了房间爱令肌肤拉伸件地方垃圾垃圾了极大浪费就暗恋的激发了设计费垃圾费拉激发偶尔加乱收费来释放接方式李反对党的圾费垃圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法lkjslajflsajflasjlasjflajflj零距离圣诞节佛按实际大量积分垃圾地方啦垃圾了房间爱令肌肤拉伸件地方垃圾垃圾了极大浪费就暗恋的激发了设计费垃圾费拉激发偶尔加乱收费来释放接方式李反对党的圾费垃圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法lkjslajflsajflasjlasjflajflj零距离圣诞节佛按实际大量积分垃圾地方啦垃圾了房间爱令肌肤拉伸件地方垃圾垃圾了极大浪费就暗恋的激发了设计费垃圾费拉激发偶尔加乱收费来释放啊;发;是放假啊;了解算法来释放"
},
@{
@"nickName":@"式李金发",
@"graide":@"",
@"content":@"连接方式323242342432圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法来释放"
},
@{
@"nickName":@"垃圾费垃圾房间",
@"graide":@"",
@"content":@"连接方式李反对党的圾费垃圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法来释放"
},
@{
@"nickName":@"了仨解放啦",
@"graide":@"",
@"content":@"连接方式沙发沙发"
},
@{
@"nickName":@"式李金发",
@"graide":@"",
@"content":@"连接方式323242342432圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法来释放"
},
@{
@"nickName":@"垃圾费垃圾房间",
@"graide":@"",
@"content":@"连接方式李反对党的圾费垃圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法来释放"
},
@{
@"nickName":@"式李金发",
@"graide":@"",
@"content":@"连接方式323242342432圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法来释放"
},
@{
@"nickName":@"垃圾费垃圾房间",
@"graide":@"",
@"content":@"连接方式李反对党的圾费垃圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法来释放"
},
@{
@"nickName":@"式李金发",
@"graide":@"",
@"content":@"连接方式323242342432圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法来释放"
},
@{
@"nickName":@"垃圾费垃圾房间",
@"graide":@"",
@"content":@"连接方式李反对党的圾费垃圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法来释放"
},
@{
@"nickName":@"式李金发",
@"graide":@"",
@"content":@"连接方式323242342432圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法来释放"
},
@{
@"nickName":@"垃圾费垃圾房间",
@"graide":@"",
@"content":@"连接方式李反对党的圾费垃圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法来释放"
},
@{
@"nickName":@"式李金发",
@"graide":@"",
@"content":@"连接方式323242342432圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法来释放"
},
@{
@"nickName":@"垃圾费垃圾房间",
@"graide":@"",
@"content":@"连接方式李反对党的圾费垃圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法来释放"
},
@{
@"nickName":@"式李金发",
@"graide":@"",
@"content":@"连接方式323242342432圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法来释放"
},
@{
@"nickName":@"垃圾费垃圾房间",
@"graide":@"",
@"content":@"连接方式李反对党的圾费垃圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法来释放"
},
@{
@"nickName":@"式李金发",
@"graide":@"",
@"content":@"连接方式323242342432圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法来释放"
},
@{
@"nickName":@"垃圾费垃圾房间",
@"graide":@"",
@"content":@"连接方式李反对党的圾费垃圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法来释放"
},
@{
@"nickName":@"式李金发",
@"graide":@"",
@"content":@"连接方式323242342432圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法来释放"
},
@{
@"nickName":@"垃圾费垃圾房间",
@"graide":@"",
@"content":@"连接方式李反对党的圾费垃圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法来释放"
},
@{
@"nickName":@"式李金发",
@"graide":@"",
@"content":@"连接方式323242342432圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法来释放"
},
@{
@"nickName":@"垃圾费垃圾房间",
@"graide":@"",
@"content":@"连接方式李反对党的圾费垃圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法来释放"
},
@{
@"nickName":@"式李金发",
@"graide":@"",
@"content":@"连接方式323242342432圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法来释放"
},
@{
@"nickName":@"垃圾费垃圾房间",
@"graide":@"",
@"content":@"连接方式接方式李反对党的圾费垃圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法lkjslajflsajflasjlasjflajflj零距离圣诞节佛按实际大量积分垃圾地方啦垃圾了房间爱令肌肤拉伸件地方垃圾垃圾了极大浪费就暗恋的激发了设计费垃圾费拉激发偶尔加乱收费来释放接方式李反对党的圾费垃圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法lkjslajflsajflasjlasjflajflj零距离圣诞节佛按实际大量积分垃圾地方啦垃圾了房间爱令肌肤拉伸件地方垃圾垃圾了极大浪费就暗恋的激发了设计费垃圾费拉激发偶尔加乱收费来释放接方式李反对党的圾费垃圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法lkjslajflsajflasjlasjflajflj零距离圣诞节佛按实际大量积分垃圾地方啦垃圾了房间爱令肌肤拉伸件地方垃圾垃圾了极大浪费就暗恋的激发了设计费垃圾费拉激发偶尔加乱收费来释放李反对党的圾费垃圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法来释放"
},
@{
@"nickName":@"式李金发",
@"graide":@"",
@"content":@"连接方式接方式李反对党的圾费垃圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法lkjslajflsajflasjlasjflajflj零距离圣诞节佛按实际大量积分垃圾地方啦垃圾了房间爱令肌肤拉伸件地方垃圾垃圾了极大浪费就暗恋的激发了设计费垃圾费拉激发偶尔加乱收费来释放323242342432圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法来释放"
},
@{
@"nickName":@"垃圾费垃圾房间",
@"graide":@"",
@"content":@"连接方式接方式李反对党的圾费垃圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法lkjslajflsajflasjlasjflajflj零距离圣诞节佛按实际大量积分垃圾地方啦垃圾了房间爱令肌肤拉伸件地方垃圾垃圾了极大浪费就暗恋的激发了设计费垃圾费拉激发偶尔加乱收费来释放李反对党的圾费垃圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法来释放"
},
@{
@"nickName":@"式李金发",
@"graide":@"",
@"content":@"连接方式接方式李反对党的圾费垃圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法lkjslajflsajflasjlasjflajflj零距离圣诞节佛按实际大量积分垃圾地方啦垃圾了房间爱令肌肤拉伸件地方垃圾垃圾了极大浪费就暗恋的激发了设计费垃圾费拉激发偶尔加乱收费来释放323242342432圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法来释放"
},
@{
@"nickName":@"垃圾费垃圾房间",
@"graide":@"",
@"content":@"连接方式接方式李反对党的圾费垃圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法lkjslajflsajflasjlasjflajflj零距离圣诞节佛按实际大量积分垃圾地方啦垃圾了房间爱令肌肤拉伸件地方垃圾垃圾了极大浪费就暗恋的激发了设计费垃圾费拉激发偶尔加乱收费来释放李反对党的圾费垃圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法来释放"
},
@{
@"nickName":@"式李金发",
@"graide":@"",
@"content":@"连接方式接方式李反对党的圾费垃圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法lkjslajflsajflasjlasjflajflj零距离圣诞节佛按实际大量积分垃圾地方啦垃圾了房间爱令肌肤拉伸件地方垃圾垃圾了极大浪费就暗恋的激发了设计费垃圾费拉激发偶尔加乱收费来释放323242342432圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法来释放"
},
@{
@"nickName":@"垃圾费垃圾房间",
@"graide":@"",
@"content":@"连接方式李反对党的圾费垃圾房间爱乱收费;啊; 拉伸放假啊;发;是放假啊;了解算法lkjslajflsajflasjlasjflajflj零距离圣诞节佛按实际大量积分垃圾地方啦垃圾了房间爱令肌肤拉伸件地方垃圾垃圾了极大浪费就暗恋的激发了设计费垃圾费拉激发偶尔加乱收费来释放"
}
]; // 将数据转换成模型
for (NSDictionary * dict in array) {
JXChatModel * model = [JXChatModel modelWithDict:dict];
[self.chatArray addObject:model];
}
[self.tableView reloadData];
} - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.chatArray.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString * identifier = @"cell"; JXChatCell * cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[JXChatCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
}
cell.model = self.chatArray[indexPath.row];
return cell;
} - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
JXChatModel * model = self.chatArray[indexPath.row];
return model.cellHeight;
} // 先给cell表格一个预估计高度
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
return ;
}
- (NSMutableArray *)chatArray{
if (_chatArray == nil) {
_chatArray = [NSMutableArray array];
}
return _chatArray;
} - (UITableView *)tableView{
if (_tableView == nil) {
UITableView * tableView = [[UITableView alloc] init];
tableView.frame = self.view.bounds;
tableView.delegate = self;
tableView.dataSource = self;
[self.view addSubview:tableView];
_tableView = tableView;
}
return _tableView;
}
@end

  构建运行,展示效果

iOS UITableViewableViewCell自适应高度的更多相关文章

  1. IOS UITextView自适应高度

    LOFTER app需要实现了一个类似iPhone短信输入框的功能,它的功能其实蛮简单,就是:[UITextView的高度随着内容高度的变化而变化].实现思路应该是: 在UITextView的text ...

  2. iOS Label 自适应高度

    推荐第二个 测试一,只改变numberOfLines属性,label的高度不会自适应(会有text中的一部分内容称为......) NSString *str = @"jgreijgirje ...

  3. iOS tableViewCell自适应高度 第三发类库

    在github中有许多大牛封装好的第三发类库,其中有个自适应cell高度的类库 下载地址:https://github.com/gsdios/SDAutoLayout model类 commentsM ...

  4. 【原】ios tableViewCell 自适应高度

    原文:http://www.cnblogs.com/A--G/p/4819051.html 前言:之前在做一个类似微博的小需求时候,用table view实现了微博文字和图片等等的基本展示,由于文字和 ...

  5. iOS UITextView自适应高度UITextContainerView抖动问题

    在打造一个类似于微信朋友圈评论输入框的时候,需要动态调整输入框的高度, 但是,在调整了UITextView的高度之后,继续输入会导致内容(UITextContainerView里的文字)抖动. scr ...

  6. IOS UILabel 根据内容自适应高度

    iOS Label 自适应高度  适配iOS7以后的版本 更多 self.contentLabelView = [[UILabel alloc] init]; self.contentLabelVie ...

  7. iOS Dev (59) 高度自适应的UITextView

    iOS Dev (59) 高度自适应的UITextView 作者:阿锐 地址:http://blog.csdn.net/prevention - 例如以下 _inputTextView 为一个 UIT ...

  8. IOS Swift语言开发 tableView的重用以及自cell的自适应高度

    http://www.aichengxu.com/iOS/11143168.htm 一.准备数据 (这是一个元组,第一个元素为英雄的名字;第二个元素为英雄头像图片的名字,格式为.PNG,如果为其他的格 ...

  9. iOS 【终极方案】精准获取webView内容高度,自适应高度

    前言:是这样的,刚写完上一篇文章还没缓过神来,上一篇文章我还提到了,想和大家聊聊原生+H5如何无缝连接的故事.结果我朋友就给我发了两篇他的作品.他的做法也都有独到之处.好的文章都是这样,让你每次看都能 ...

随机推荐

  1. Vue.js 2.0 和 React、Augular等其他框架的全方位对比

    引言 这个页面无疑是最难编写的,但也是非常重要的.或许你遇到了一些问题并且先前用其他的框架解决了.来这里的目的是看看Vue是否有更好的解决方案.那么你就来对了. 客观来说,作为核心团队成员,显然我们会 ...

  2. 谈谈一些有趣的CSS题目(十)-- 结构性伪类选择器

    开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...

  3. 在jekyll模板博客中添加网易云模块

    最近使用GitHub Pages + Jekyll 搭建了个人博客,作为一名重度音乐患者,博客里面可以不配图,但是不能不配音乐啊. 遂在博客里面引入了网易云模块,这里要感谢网易云的分享机制,对开发者非 ...

  4. ES6的一些常用特性

    由于公司的前端业务全部基于ES6开发,于是给自己开个小灶补补ES6的一些常用特性.原来打算花两天学习ES6的,结果花了3天才勉强过了一遍阮老师的ES6标准入门(水好深,ES6没学好ES7又来了...) ...

  5. [原]Cachedb 网络模块文档

    Cachedb 网络模块文档 整体结构 多路复用 (epoll 模块) 事件驱动 (事件封装) 缓冲管理 (上层buffer管理) 设计思想 层次化的设计,每一个模块只调用上一个模块的接口,并将耦合聚 ...

  6. 解决使用IE8打开ADFS 3.0登录页面

    系统上线前一天,发现客户竟然有XP系统和2003系统,这些系统都不能访问外网.测试时,客户端是IE8,打开我们系统ADFS的登录页面,一直在Loading,无法打开,也不报错.后来通过fiddler跟 ...

  7. TFS2013 设置签出独占锁

    转载自: http://www.cnblogs.com/zhang888/p/4280251.html

  8. 【初码干货】【Azure系列】1、再次感受Azure,体验Windows Server 2016并部署BlogEngine.NET

    上个月末,在某人的建议下,重新注册了一个1元试用账户(包含1个月期限的1500元订阅),并充值了1000元转为了正式账户,相当于1000元得到了2500的订阅,于是又一次开启了Azure之旅. 在这不 ...

  9. CSharpGL(38)带初始数据创建Vertex Buffer Object的情形汇总

    CSharpGL(38)带初始数据创建Vertex Buffer Object的情形汇总 开始 总的来说,OpenGL应用开发者会遇到为如下三种数据创建Vertex Buffer Object的情形: ...

  10. 二、Redis基本操作——String(实战篇)

    小喵万万没想到,上一篇博客,居然已经被阅读600次了!!!让小喵感觉压力颇大.万一有写错的地方,岂不是会误导很多筒子们.所以,恳请大家,如果看到小喵的博客有什么不对的地方,请尽快指正!谢谢! 小喵的唠 ...