通过代码自定义cell(cell的高度不一致)
2016-03-13 15:52
357 查看
cell的高度不一致情况的实现步骤
1.新建一个继承自UITableViewCell的类2.重写initWithStyle:reuseIdentifier:方法
1)添加所有需要显示的子控件(不需要设置子控件的数据和frame, 子控件要添加到contentView中)
2)进行子控件一次性的属性设置(有些属性只需要设置一次, 比如字体\固定的图片)
3.提供2个模型数据模型:
1)存放文字数据\图片数据模型
2)存放数据模型\所有子控件的frame\cell的高度
存放文字数据\图片数据模型
存放数据模型\所有子控件的frame\cell的高度
4.cell拥有一个frame模型(不要直接拥有数据模型)
5.重写frame模型属性的setter方法: 在这个方法中设置子控件的显示数据和frame
6.frame模型数据的初始化已经采取懒加载的方式(每一个cell对应的frame模型数据只加载一次)
全部代码:
1)2个模型数据模型存放文字数据\图片数据模型:MJStatus.h和MJStatus.m
存放数据模型\所有子控件的frame\cell的高度:MJStatusFrame.h和MJStatusFrame.m
MJStatus.h
#import <Foundation/Foundation.h> @interface MJStatus : NSObject @property (nonatomic,copy) NSString *text; // 内容 @property (nonatomic,copy) NSString *icon; // 头像 @property (nonatomic,copy) NSString *picture; // 昵称 @property (nonatomic,copy) NSString *name; // 配图 @property (nonatomic,assign) BOOL vip; -(instancetype)initWithDict:(NSDictionary *)dict; +(instancetype)statusWithDict:(NSDictionary *)dict; @end
MJStatus.m
#import "MJStatus.h" @implementation MJStatus -(instancetype)initWithDict:(NSDictionary *)dict{ if(self = [super init]){ [self setValuesForKeysWithDictionary:dict]; } return self; } +(instancetype)statusWithDict:(NSDictionary *)dict{ return [[self alloc] initWithDict:dict]; } @end
MJStatusFrame.h
#import <Foundation/Foundation.h> #import <UIKit/UIKit.h> @class MJStatus; @interface MJStatusFrame : NSObject /** * 头像的frame */ @property (nonatomic, assign, readonly) CGRect iconF; /** * 昵称的frame */ @property (nonatomic, assign, readonly) CGRect nameF; /** * 会员图标的frame */ @property (nonatomic, assign, readonly) CGRect vipF; /** * 正文的frame */ @property (nonatomic, assign, readonly) CGRect textF; /** * 配图的frame */ @property (nonatomic, assign, readonly) CGRect pictureF; /** * cell的高度 */ @property (nonatomic, assign, readonly) CGFloat cellHeight; @property (nonatomic, strong) MJStatus *status; @end
MJStatusFrame.m
// 昵称的字体 #define MJNameFont [UIFont systemFontOfSize:14] // 正文的字体 #define MJTextFont [UIFont systemFontOfSize:15] #import "MJStatusFrame.h" #import "MJStatus.h" @implementation MJStatusFrame /** * 计算文字尺寸 * * @param text 需要计算尺寸的文字 * @param font 文字的字体 * @param maxSize 文字的最大尺寸 */ -(CGSize)sizeWithText:(NSString *)text font:(UIFont *)font maxSize:(CGSize)maxSize { NSDictionary *attrs = @{NSFontAttributeName : font}; return [text boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attrs context:nil].size; } /** * 为status赋值时设置控件的frame(懒加载的方法) */ -(void)setStatus:(MJStatus *)status{ _status = status; // 子控件之间的间距 CGFloat padding = 10; // 1.头像 CGFloat iconX = padding; CGFloat iconY = padding; CGFloat iconW = 30; CGFloat iconH = 30; _iconF = CGRectMake(iconX, iconY, iconW, iconH); // 2.昵称 //文本字体 CGSize nameSize = [self sizeWithText:self.status.name font:MJNameFont maxSize:CGSizeMake(MAXFLOAT, MAXFLOAT)]; CGFloat nameX = CGRectGetMaxX(_iconF) + padding; CGFloat nameY = iconY + (iconH - nameSize.height) * 0.5; _nameF = CGRectMake(nameX, nameY, nameSize.width, nameSize.height); // 3.会员图标 CGFloat vipX = CGRectGetMaxX(_nameF) + padding; CGFloat vipY = nameY; CGFloat vipW = 14; CGFloat vipH = 14; _vipF = CGRectMake(vipX, vipY, vipW, vipH); // 4.正文 CGSize textSize = [self sizeWithText:self.status.text font:MJTextFont maxSize:CGSizeMake(300, MAXFLOAT)]; CGFloat textX = iconX; CGFloat textY = CGRectGetMaxY(_iconF) + padding; _textF = CGRectMake(textX, textY, textSize.width, textSize.height); // 5.配图 if(self.status.picture){ CGFloat pictureX = textX; CGFloat pictureY = CGRectGetMaxY(_textF) + padding; CGFloat pictureW = 100; CGFloat pictureH = 100; _pictureF = CGRectMake(pictureX, pictureY, pictureW, pictureH); _cellHeight = CGRectGetMaxY(_pictureF) + padding; } else{ _cellHeight = CGRectGetMaxY(_textF) + padding; } } @end
2)继承自UITableViewCell的类:MJStatusCell.h和MJStatusCell.m
MJStatusCell.h
#import <UIKit/UIKit.h> @class MJStatusFrame; @interface MJStatusCell : UITableViewCell @property (nonatomic,strong) MJStatusFrame *statusFrame; +(instancetype)cellWithTableView:(UITableView *)tableView; @end
MJStatusCell.m
// 昵称的字体 #define MJNameFont [UIFont systemFontOfSize:14] // 正文的字体 #define MJTextFont [UIFont systemFontOfSize:15] #import "MJStatusCell.h" #import "MJStatus.h" #import "MJStatusFrame.h" @interface MJStatusCell() /** * 头像 */ @property (nonatomic, weak) UIImageView *iconView; /** * 昵称 */ @property (nonatomic, weak) UILabel *nameView; /** * 会员图标 */ @property (nonatomic, weak) UIImageView *vipView; /** * 正文 */ @property (nonatomic, weak) UILabel *textView; /** * 配图 */ @property (nonatomic, weak) UIImageView *pictureView; @end @implementation MJStatusCell /** * 构造方法(在初始化对象的时候会调用) * 一般在这个方法中添加需要显示的子控件 */ -(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{ self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if(self){ // 1.头像 UIImageView *iconView = [[UIImageView alloc] init]; [self.contentView addSubview:iconView]; self.iconView = iconView; // 2.昵称 UILabel *nameView = [[UILabel alloc] init]; nameView.font = MJNameFont; [self.contentView addSubview:nameView]; self.nameView = nameView; // 3.会员图标 UIImageView *vipView = [[UIImageView alloc] init]; vipView.image = [UIImage imageNamed:@"vip"]; [self.contentView addSubview:vipView]; self.vipView = vipView; // 4.正文 UILabel *textView = [[UILabel alloc] init]; textView.numberOfLines = 0; textView.font = MJTextFont; [self.contentView addSubview:textView]; self.textView = textView; // 5.配图 UIImageView *pictureView = [[UIImageView alloc] init]; [self.contentView addSubview:pictureView]; self.pictureView = pictureView; } return self; } /** * 在这个方法中设置子控件的frame和显示数据 */ -(void)setStatusFrame:(MJStatusFrame *)statusFrame{ _statusFrame = statusFrame; // 1.设置数据 [self settingData]; // 2.设置frame [self settingFrame]; } /** * 设置数据 */ -(void)settingData{ // 微博数据 MJStatus *status = self.statusFrame.status; // 1.头像 self.iconView.image = [UIImage imageNamed:status.icon]; // 2.昵称 self.nameView.text = status.name; // 3.会员图标 if(status.vip){ self.vipView.hidden = NO; self.nameView.textColor = [UIColor redColor]; } else{ self.vipView.hidden = YES; self.nameView.textColor = [UIColor blackColor]; } // 4.正文 self.textView.text = status.text; // 5.配图 if (status.picture) { self.pictureView.hidden = NO; self.pictureView.image = [UIImage imageNamed:status.picture]; } else{ self.pictureView.hidden = YES; } } /** * 设置frame */ -(void)settingFrame{ // 1.头像 self.iconView.frame = self.statusFrame.iconF; // 2.昵称 self.nameView.frame = self.statusFrame.nameF; // 3.会员图标 self.vipView.frame = self.statusFrame.vipF; // 4.正文 self.textView.frame = self.statusFrame.textF; // 5.配图 if (self.statusFrame.status.picture) { self.pictureView.frame = self.statusFrame.pictureF; } } +(instancetype)cellWithTableView:(UITableView *)tableView{ static NSString *ID = @"status"; MJStatusCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; if(cell == nil){ cell = [[MJStatusCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID]; } return cell; }
3)控制器中的使用
ViewController.m
#import "ViewController.h" #import "MJStatus.h" #import "MJStatusFrame.h" #import "MJStatusCell.h" @interface ViewController () //@property (nonatomic,strong) NSArray *status; /** * 存放所有cell的frame模型数据 */ @property (nonatomic,strong) NSArray *statusFrames; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // self.tableView.rowHeight = 400; } -(NSArray *)statusFrames{ if(_statusFrames == nil){ // 获取plist数据文件的全路径 NSString *path = [[NSBundle mainBundle] pathForResource:@"statuses.plist" ofType:nil]; // 根据全路径获取plist文件的NSArray数据 NSArray *dictArray = [NSArray arrayWithContentsOfFile:path]; // 创建一个存放模型数据的可变数组 NSMutableArray *statusFrameArray = [NSMutableArray array]; // 遍历循环dictArray中的字典数据 for (NSDictionary *dict in dictArray) { // 将字典数据复制给MJStatus模型 MJStatus *status = [MJStatus statusWithDict:dict]; // 创建MJStatusFrame模型对象 MJStatusFrame *statusFrame = [[MJStatusFrame alloc] init]; statusFrame.status = status; // 将MJStatusFrame模型存放进statusFrameArray数组中 [statusFrameArray addObject:statusFrame]; } // 赋值 _statusFrames = statusFrameArray; } return _statusFrames; } -(BOOL)prefersStatusBarHidden{ return YES; } #pragma mark - 实现数据源方法 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ NSLog(@"numberOfRowsInSection"); return self.statusFrames.count; } -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ MJStatusCell *cell = [MJStatusCell cellWithTableView:tableView]; cell.statusFrame = self.statusFrames[indexPath.row]; NSLog(@"cellForRowAtIndexPath -- 第%d行",indexPath.row); return cell; } #pragma mark - 实现数据源的代理 -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ MJStatusFrame *statusFrame = self.statusFrames[indexPath.row]; NSLog(@"heightForRowAtIndexPath -- 第%d行",indexPath.row); return statusFrame.cellHeight; } @end
项目程序链接
相关文章推荐
- 编程英语
- Qt实现无边框窗体的移动
- DOS命令行下编译运行java文件
- SpringMVC中四个基本注解
- 在ZendStudio中增加新的php模板
- Java调用python,出现“无法解析的编译问题,PythonInterpreter无法解析为类型”
- Spring注解详解
- 【Java基础】IO总结
- Qt-----发布应用程序
- Java的基本设计结构
- JDK 6 目录结构介绍以及JDK中的工具研究
- QML中多个动画的操作
- Eclipse java工程中配置opencv
- 转载:C#实现接口回调
- Python基础(四)之条件判断和循环
- java 实现PageRank算法
- eclipse加速之禁用JS、jsp等文件的语法验证,eclipsejs
- C++基础::构造函数
- java 重载和覆盖的区别
- C# winform初学者实例