iOS开发UI篇 -- 0401微博主页-自定义cell
2015-07-14 23:02
501 查看
一、自定义cell详细步骤介绍
自定义cell,控件不固定(比如微博)1.新建一个继承自UITableViewCell的类重写initWithStyle:reuseIdentifier:方法
添加所有需要显示的子控件(不需要设置子控件的数据和frame, 子控件要添加到contentView中)
进行子控件一次性的属性设置(有些属性只需要设置一次, 比如字体\固定的图片) -- 初始化 ,添加到contentView中,赋值,设置一次性属性(比如字体,vipImage)
2.提供2个模型
数据模型: 存放文字数据\图片数据 -- 和Cell 中的控件相对应,同时和json中数据相对应,有用的数据都存储
frame模型: 存放数据模型\所有子控件的frame\cell的高度 -- 在setModel中设置各个控件的frame,并计算cellHeight;
3.cell拥有一个frame模型(不要直接拥有数据模型) -- 在setModelFrame中settingData 和 settingFrame;
4.在TableViewController提供一个NSArray *modelFrames; 在setting方法中获取网络数据,
-- statusFrame.status = status 在settingStatus中设置status的frame,在HomeViewController中从服务器获取status数据,
5.接下来 数据源 代理(cellHeight)
二、自定义cell最终总结
第一步 新建cell,重写initWithStyle:reuseIdentifier:第二步 创建Status 和 StatusFrame 模型
Status中的属性和cell中的控件相对应
StatusFrame中装各个控件的 frame 和 cellHeight
第三步 重写setStatus 和 setStatusFrame 方法
重写setStatus,计算各控件 frame 和 cellHeight
重写setStatusFrame方法,settingData 和 settingFrame
第四步 获取Status数据,写数据源和代理方法
ps:cell初始化的时候,初始化所有子控件
对于不一定显示的控件,我们在settingData的时候根据Status中有无此数据来设置该控件是否显示
将其余步骤都完成之后,在计算frame这一步我们可以一个个来计算,减少出错率!
获取到Status数据时,我们可以先NSLog看一看,在转模型,装到Frame中
整个WBTableViewController相当于:我们将33个双色球放到了大箱子中,用到第一个就取出第一个,用到第二个就取第二个。提高了性能,手机界面不会出现卡顿现象
三、demo奉上!
第一步 新建cell,重写initWithStyle:reuseIdentifier:
#import "WBStatusCell.h" @interface WBStatusCell () // 头像 @property(nonatomic,weak)UIImageView *iconImage; // 昵称 @property(nonatomic,weak)UILabel *nameLable; // vip @property(nonatomic,weak)UIImageView *vipImage; // 正文 @property(nonatomic,weak)UILabel *contentLable; // 图片 @property(nonatomic,weak)UIImageView *photoImage; @end @implementation WBStatusCell + (instancetype)cellWithTableView:(UITableView *)tableView{ static NSString *ID = @"status"; WBStatusCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; if(cell == nil){ cell = [[WBStatusCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID]; } return cell; } - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { // 头像 UIImageView *iconImage = [[UIImageView alloc] init]; // 在这里我们初始化控件,添加到contentView中,赋值,设置一次性属性(比如字体,vipImage) [self.contentView addSubview:iconImage]; self.iconImage = iconImage; // 昵称 UILabel *nameLable = [[UILabel alloc] init]; [self.contentView addSubview:nameLable]; nameLable.font = BJNameFont; self.nameLable = nameLable; // vip UIImageView *vipImage = [[UIImageView alloc] init]; [self.contentView addSubview:vipImage]; vipImage.image = [UIImage imageNamed:@"vip"]; self.vipImage = vipImage; // 正文 UILabel *contentLable = [[UILabel alloc] init]; [self.contentView addSubview:contentLable]; contentLable.font = BJContentFont; contentLable.numberOfLines = 0; self.contentLable = contentLable; // 图片 UIImageView *photoImage = [[UIImageView alloc] init]; [self.contentView addSubview:photoImage]; self.photoImage = photoImage; } return self; }
第二步 创建Status 和 StatusFrame 模型
Status的属性是和cell中控件对应的
// // WBStatus.h // WB // // Created by hubaojie on 15-7-14. // Copyright (c) 2015年 hubaojie. All rights reserved. // #import <Foundation/Foundation.h> @interface WBStatus : NSObject // 头像 @property(nonatomic,copy)NSString *icon; // 昵称 @property(nonatomic,copy)NSString *name; // vip @property(nonatomic,assign)BOOL vip; // 正文 @property(nonatomic,copy)NSString *content; // 图片 @property(nonatomic,copy)NSString *photo; // + (instancetype)statusWithDict:(NSDictionary *)dict; - (instancetype)initWithDict:(NSDictionary *)dict; @end
StatusFrame中装各个控件的 frame 和 cellHeight
// // WBStatusFrame.h // WB // // Created by hubaojie on 15-7-14. // Copyright (c) 2015年 hubaojie. All rights reserved. // #define BJNameFont [UIFont systemFontOfSize:14] #define BJContentFont [UIFont systemFontOfSize:14] #import <UIKit/UIKit.h> #import "WBStatus.h" @interface WBStatusFrame : NSObject @property(nonatomic,strong)WBStatus *status; // 头像 @property(nonatomic,assign,readonly)CGRect iconImageF; // 控件的尺寸不允许别人随便更改,所以这里采取了readonly // 昵称 @property(nonatomic,assign,readonly)CGRect nameLableF; // vip @property(nonatomic,assign,readonly)CGRect vipImageF; // 正文 @property(nonatomic,assign,readonly)CGRect contentLableF; // 图片 @property(nonatomic,assign,readonly)CGRect photoImageF; // cellHeight @property(nonatomic,assign,readonly)CGFloat cellHeight; // 特别:设置cell高度 @end
第三步 重写setStatus 和 setStatusFrame 方法
重写setStatus,计算各控件 frame 和 cellHeight
// // WBStatusFrame.m // WB // // Created by hubaojie on 15-7-14. // Copyright (c) 2015年 hubaojie. All rights reserved. // #import "WBStatusFrame.h" @implementation WBStatusFrame /** * 重写setStatus方法,设置控件尺寸 * * @param status <#status description#> */ - (void)setStatus:(WBStatus *)status{ _status = status; CGFloat padding = 10; // 头像 CGFloat iconX = padding; CGFloat iconY = padding; CGFloat iconW = 30; CGFloat iconH = 30; _iconImageF = CGRectMake(iconX, iconY, iconW, iconH); // 昵称 CGFloat nameX = CGRectGetMaxX(_iconImageF) + padding; CGFloat nameH = [self.status.name sizeWithFont:BJNameFont].height; CGFloat nameY = padding + (iconH - nameH) / 2; CGFloat nameW = [self.status.name sizeWithFont:BJNameFont].width; _nameLableF = CGRectMake(nameX, nameY, nameW, nameH); // vip CGFloat vipX = CGRectGetMaxX(_nameLableF) +padding; CGFloat vipY = nameY; CGFloat vipW = 14; CGFloat vipH = 14; _vipImageF = CGRectMake(vipX, vipY, vipW, vipH); // 正文 CGFloat contentX = padding; CGFloat contentY = CGRectGetMaxY(_vipImageF) + padding*2; CGSize contentSize = [self.status.content boundingRectWithSize:CGSizeMake(300, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:BJContentFont} context:nil].size; // CGSize contentSize = [self.status.content sizeWithFont:BJContentFont]; _contentLableF = (CGRect){{contentX,contentY},contentSize}; // 图片 if(self.status.photo){ CGFloat photoX = padding; CGFloat photoY = CGRectGetMaxY(_contentLableF) + padding*2; CGFloat photoW = 100; CGFloat photoH = 100; _photoImageF = CGRectMake(photoX, photoY, photoW, photoH); _cellHeight = CGRectGetMaxY(_photoImageF) + padding; }else{ _cellHeight = CGRectGetMaxY(_contentLableF) + padding; } // cellHeight } @end
重写setStatusFrame方法,设置frame和data
// // WBStatusCell.h // WB // // Created by hubaojie on 15-7-14. // Copyright (c) 2015年 hubaojie. All rights reserved. // #import <UIKit/UIKit.h> #import "WBStatusFrame.h" @interface WBStatusCell : UITableViewCell // @property(nonatomic,strong)WBStatusFrame *statusFrame; + (instancetype)cellWithTableView:(UITableView *)tableView; @end
- (void)setStatusFrame:(WBStatusFrame *)statusFrame{ _statusFrame = statusFrame; // 设置数据 [self settingData]; // 设置尺寸 [self settingFrame]; } /** * 设置数据 */ - (void)settingData{ WBStatus *status = self.statusFrame.status; // 头像 self.iconImage.image = [UIImage imageNamed:status.icon]; // 昵称 self.nameLable.text = status.name; // vip if(status.vip){ self.nameLable.textColor = [UIColor redColor]; // 在settingData中判断控件是否显示 self.vipImage.hidden = NO; }else{ self.nameLable.textColor = [UIColor blackColor]; self.vipImage.hidden = YES; } // 正文 self.contentLable.text = status.content; // 图片 if(status.photo) self.photoImage.image = [UIImage imageNamed:status.photo]; } /** * 设置尺寸 */ - (void)settingFrame{ // 头像 self.iconImage.frame = self.statusFrame.iconImageF; // 昵称 self.nameLable.frame = self.statusFrame.nameLableF; // vip self.vipImage.frame = self.statusFrame.vipImageF; // 正文 self.contentLable.frame = self.statusFrame.contentLableF; // 图片 self.photoImage.frame = self.statusFrame.photoImageF; }
第四步 获取Status数据,写数据源和代理方法
// // WBViewController.m // WB // // Created by hubaojie on 15-7-14. // Copyright (c) 2015年 hubaojie. All rights reserved. // #import "WBViewController.h" #import "WBStatus.h" #import "WBStatusFrame.h" #import "WBStatusCell.h" @interface WBViewController () @property(nonatomic,strong)NSArray *statusFrames; @end @implementation WBViewController - (NSArray *)statusFrames{ if(_statusFrames == nil){ NSString *path = [[NSBundle mainBundle] pathForResource:@"statuses.plist" ofType:nil]; NSArray *dictArray = [NSArray arrayWithContentsOfFile:path]; // NSLog(@"%@",dictArray); NSMutableArray *statusFrameArray = [NSMutableArray array]; for (NSDictionary *dict in dictArray) { WBStatusFrame *statusFrame = [[WBStatusFrame alloc] init]; WBStatus *status = [WBStatus statusWithDict:dict]; statusFrame.status = status; // 这一步关键:采用懒加载的方式设置statusFrame中的 数据 和 frame [statusFrameArray addObject:statusFrame]; } _statusFrames = statusFrameArray; } return _statusFrames; } - (void)viewDidLoad { [super viewDidLoad]; self.tableView.contentInset = UIEdgeInsetsMake(10, 0, 0, 0); } // 整个WBTableViewController相当于:我们 将33个双色球放到了大箱子中,用到第一个就取出第一个,用到第二个就取第二个。提高了性能,手机界面不会出现卡顿现象 #pragma mark - Table view data source 。。 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return self.statusFrames.count; // 采用懒加载的方式事先读取完数据 } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ // 1、创建cell WBStatusCell *cell = [WBStatusCell cellWithTableView:tableView]; // 2、设置cell数据 cell.statusFrame = self.statusFrames[indexPath.row]; // 用到哪个数据 就 调用哪个数据 // 3、返回cell return cell; } // 设置cell高度 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ WBStatusFrame *statusFrame = self.statusFrames[indexPath.row]; return statusFrame.cellHeight; } // 点击cell做出的操作 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ // 选中后取消选中 [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; } @end
相关文章推荐
- arduino uno 多机串口通信
- iOS多线程编程之NSOperation和NSOperationQueue的使用
- 欢迎使用CSDN-markdown编辑器
- UITableVIew的性能优化-重用原理
- [翻译] BAFluidView
- [Erlang_Question32]ibrowse流程及性能测试
- iOS Xcode 6报错:setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key v
- ueditor引入通用优酷视频
- Easyui Tab刷新
- UIScrollView 实现比例缩放
- UiAutomator喷射事件的源代码分析
- UIKit之浅析UIButton
- 关于继承UITableViewController若干问题
- Table的分割线偏移量设置 及其 UIEdgeInset详解
- iOS开发UI篇—UITabBarController简单介绍
- iOS --- 搜索框UISearchController的使用(iOS8.0以后替代UISearchBar + UISearchDisplayController的组合)
- NSArray, NSNumber, NSValue, NSSet, 数组排序
- UI基础(二)-图层
- IOS开发UI篇--一个侧滑菜单SlidingMenu
- UI_UItableView_AutoCell(自定义cell 高度)