献给初学iOS的小盆友们——微博app项目开发之十二自定义cell代码补全
来源:互联网 发布:淘宝上新速度 编辑:程序博客网 时间:2024/04/30 19:53
上节课我们主要讲解了我们是怎么一步一步把自定义cell打通的,主要方法就是引入了MVVM视图模型,这样我们就可以利用视图模型就提前把各个子控件的frame都计算好了。今天我们就是讲如何计算子控件frame,以及补全原创微博和转发微博的设计。
本节内容
- 计算cell子控件frame
- YGStatusCell代码补全
- 原创微博YGOriginalView代码补全
- 转发微博YGRetweetView 代码补全
本节资料
第十二节代码资料
12.1 计算cell子控件frame
在YGStatusFrame视图模型执行文件内,我们重写setStatus方法,表明一接到YGStatus数据模型,我们就把各个子控件计算好,代码如下:
- (void)setStatus:(YGStatus *)status{ _status = status; // 计算原创微博 [self setUpOriginalViewFrame]; CGFloat toolBarY = CGRectGetMaxY(_originalViewFrame); if (status.retweeted_status) { // 计算转发微博 [self setUpRetweetViewFrame]; toolBarY = CGRectGetMaxY(_retweetViewFrame); } // 计算工具条 CGFloat toolBarX = 0; CGFloat toolBarW = YGScreenW; CGFloat toolBarH = 35; _toolBarFrame = CGRectMake(toolBarX, toolBarY, toolBarW, toolBarH); // 计算cell高度 _cellHeight = CGRectGetMaxY(_toolBarFrame);}
我们首先计算了原创微博子控件的frame,然后判断微博是否有转发微博,如果有转发微博,我们就计算转发微博子控件的frame。最后计算工具条的纵坐标Y值时,也要考虑是否有转发微博。
下面就贴上原创微博怎么设置frame的:
#pragma mark - 计算原创微博- (void)setUpOriginalViewFrame{ // 头像 CGFloat imageX = YGStatusCellMargin; CGFloat imageY = imageX; CGFloat imageWH = 35; _originalIconFrame = CGRectMake(imageX, imageY, imageWH, imageWH); // 昵称 CGFloat nameX = CGRectGetMaxX(_originalIconFrame) + YGStatusCellMargin; CGFloat nameY = imageY; CGSize nameSize = [_status.user.name sizeWithFont:YGNameFont]; _originalNameFrame = (CGRect){{nameX,nameY},nameSize}; // vip if (_status.user.vip) { CGFloat vipX = CGRectGetMaxX(_originalNameFrame) + YGStatusCellMargin; CGFloat vipY = nameY; CGFloat vipWH = 14; _originalVipFrame = CGRectMake(vipX, vipY, vipWH, vipWH); } // 时间 CGFloat timeX = nameX; CGFloat timeY = CGRectGetMaxY(_originalNameFrame) + YGStatusCellMargin * 0.5; CGSize timeSize = [_status.created_at sizeWithFont:YGTimeFont]; _originalTimeFrame = (CGRect){{timeX,timeY},timeSize}; // 来源 CGFloat sourceX = CGRectGetMaxX(_originalTimeFrame) + YGStatusCellMargin; CGFloat sourceY = timeY; CGSize sourceSize = [_status.source sizeWithFont:YGSourceFont]; _originalSourceFrame = (CGRect){{sourceX,sourceY},sourceSize}; // 正文 CGFloat textX = imageX; CGFloat textY = CGRectGetMaxY(_originalIconFrame) + YGStatusCellMargin; CGFloat textW = YGScreenW - 2 * YGStatusCellMargin; CGSize textSize = [_status.text sizeWithFont:YGTextFont constrainedToSize:CGSizeMake(textW, MAXFLOAT)]; _originalTextFrame = (CGRect){{textX,textY},textSize}; // 原创微博的frame CGFloat originX = 0; //设置间隙 CGFloat originY = 10; CGFloat originW = YGScreenW; CGFloat originH = CGRectGetMaxY(_originalTextFrame) + YGStatusCellMargin; _originalViewFrame = CGRectMake(originX, originY, originW, originH);}
这里需要说明的是:在计算会员属性的frame时,需要判断用户是否是会员,但是以前我们设计的YGUser模型里没有VIP属性,所以我们现在在YGUser增加几个属性,用来接受返回的数据,然后判断是否是vip,头文件增加如下代码:
/** 会员类型 > 2代表是会员 */@property (nonatomic, assign) int mbtype;/** 会员等级 */@property (nonatomic, assign) int mbrank;@property (nonatomic, assign,getter=isVip) BOOL vip;
执行文件增加如下代码:
- (void)setMbtype:(int)mbtype{ _mbtype = mbtype; _vip = mbtype > 2;}
这里的意思就是当返回的数据mbtype大于2时,用户就是VIP,具体会员等级由mbrank决定。
如何计算转发微博frame:
#pragma mark - 计算转发微博- (void)setUpRetweetViewFrame{ // 昵称frame // 昵称 CGFloat nameX = YGStatusCellMargin; CGFloat nameY = nameX; // 注意:一定要是转发微博的用户昵称 CGSize nameSize = [_status.retweeted_status.user.name sizeWithFont:YGNameFont]; _retweetNameFrame = (CGRect){{nameX,nameY},nameSize}; // 正文 CGFloat textX = nameX; CGFloat textY = CGRectGetMaxY(_retweetNameFrame) + YGStatusCellMargin; CGFloat textW = YGScreenW - 2 * YGStatusCellMargin; // 注意:一定要是转发微博的正文 CGSize textSize = [_status.retweeted_status.text sizeWithFont:YGTextFont constrainedToSize:CGSizeMake(textW, MAXFLOAT)]; _retweetTextFrame = (CGRect){{textX,textY},textSize}; // 原创微博的frame CGFloat retweetX = 0; CGFloat retweetY = CGRectGetMaxY(_originalViewFrame); CGFloat retweetW = YGScreenW; CGFloat retweetH = CGRectGetMaxY(_retweetTextFrame) + YGStatusCellMargin; _retweetViewFrame = CGRectMake(retweetX, retweetY, retweetW, retweetH);}
以上代码所用的宏定义我们设置在了weibo.pch文件内了:
/* cell */#define YGStatusCellMargin 10#define YGNameFont [UIFont systemFontOfSize:13]#define YGTimeFont [UIFont systemFontOfSize:12]#define YGSourceFont YGTimeFont#define YGTextFont [UIFont systemFontOfSize:15]#define YGScreenW [UIScreen mainScreen].bounds.size.width
12.2 YGStatusCell代码补全
重写setStatusFrame方法,设置cell内三个子控件的位置和大小:
- (void)setStatusFrame:(YGStatusFrame *)statusFrame{ _statusFrame = statusFrame; // 设置原创微博frame _originalView.frame = statusFrame.originalViewFrame; _originalView.statusFrame = statusFrame; // 设置原创微博frame _retweetView.frame = statusFrame.retweetViewFrame; _retweetView.statusFrame = statusFrame; // 设置工具条frame _toolBar.frame = statusFrame.toolBarFrame;}
这里不要忘记给YGOriginalView 和YGRetweetView添加YGStatus Frame属性,以便传递视图模型。
12.3 原创微博YGOriginalView代码补全
这里我们在取得视图模型后,要重写setStatusFrame方法,来设置原创微博子控件的大小位置以及内容:
-(void)setStatusFrame:(YGStatusFrame *)statusFrame{ _statusFrame = statusFrame; // 设置frame [self setUpFrame]; // 设置data [self setUpData];}
这里我们抽取两给方法,一个专门设置子控件位置和大小,一盒专门设置内容,设置frame代码如下:
- (void)setUpFrame{ // 头像 _iconView.frame = _statusFrame.originalIconFrame; // 昵称 _nameView.frame = _statusFrame.originalNameFrame; // vip if (_statusFrame.status.user.vip) { // 是vip _vipView.hidden = NO; _vipView.frame = _statusFrame.originalVipFrame; }else{ _vipView.hidden = YES; } // 时间 _timeView.frame = _statusFrame.originalTimeFrame; // 来源 _sourceView.frame = _statusFrame.originalSourceFrame; // 正文 _textView.frame = _statusFrame.originalTextFrame;}
设置子控件内容如下:
- (void)setUpData{ YGStatus *status = _statusFrame.status; // 头像 [_iconView sd_setImageWithURL:status.user.profile_image_url placeholderImage:[UIImage imageNamed:@"timeline_image_placeholder"]]; // 昵称 if (status.user.vip) { _nameView.textColor = [UIColor redColor]; }else{ _nameView.textColor = [UIColor blackColor]; } _nameView.text = status.user.name; // vip NSString *imageName = [NSString stringWithFormat:@"common_icon_membership_level%d",status.user.mbrank]; UIImage *image = [UIImage imageNamed:imageName]; _vipView.image = image; // 时间 _timeView.text = status.created_at; // 来源 _sourceView.text = status.source; // 正文 _textView.text = status.text;}
最后还有几点需要注意,我们要给昵称,来源,时间和正文设置合适的字体大小和颜色,正文还要设置跨行,具体请参考资料代码。
12.4 转发微博YGRetweetView 代码补全
转发微博的子控件设置原理就跟原创微博一样了,首先,重写initWithFrame方法:
- (instancetype)initWithFrame:(CGRect)frame{ if (self = [super initWithFrame:frame]) { // 添加所有子控件 [self setUpAllChildView]; } return self;}
然后抽取的添加所有子控件的方法为:
// 添加所有子控件- (void)setUpAllChildView{ // 昵称 UILabel *nameView = [[UILabel alloc] init]; nameView.font = YGNameFont; [self addSubview:nameView]; _nameView = nameView; // 正文 UILabel *textView = [[UILabel alloc] init]; textView.font = YGTextFont; textView.numberOfLines = 0; [self addSubview:textView]; _textView = textView;}
这里只需要添加两个子控件,比原创微博的要简单些。
最后就是重写setStatusFrame方法,设置其子控件大小位置和内容:
- (void)setStatusFrame:(YGStatusFrame *)statusFrame{ _statusFrame = statusFrame; YGStatus *status = statusFrame.status; // 昵称 _nameView.frame = statusFrame.retweetNameFrame; _nameView.text = status.retweeted_status.user.name; // 正文 _textView.frame = statusFrame.retweetTextFrame; _textView.text = status.retweeted_status.text;}
是不是感觉这些代码敲起来巨爽,直接用点语法赋值即可,但愿你此时可以深刻理解到面向对象编程思想是多么方便。
这里还有两点需要说明:
第一:我们为了设置原创微博和转发微博子控件的背景图片,需要把两者继承的类改为UIImageView,这样才能设置图片。然后在各自的初始化方法里,添加其背景图片,并把用户交互打开,代码如下:
- (instancetype)initWithFrame:(CGRect)frame{ if (self = [super initWithFrame:frame]) { // 添加所有子控件 [self setUpAllChildView]; self.userInteractionEnabled = YES; self.image = [UIImage imageWithStretchableName:@"timeline_card_top_background"]; } return self;}
第二:为了让cell产生间隙效果,我们这里把原始微博的纵坐标往下移了10point。仔细在代码资源里找找在那里设置的吧。
第三:我在写代码的时候,不小心产生了一个错误叫(null): Linker command failed with exit code 1 (use -v to see invocation)
这个错误我找了好半天才找到,原来是我在某个地方错误的引用了.m文件引起的,这里指出来希望对大家有所帮助。而且以后在开发中,注意多保存文件,一个功能建立一个文件,多运行,这样就能缩小bug的寻找范围。
这节课就到这里吧,如果你运行项目就会看到我们已经得到了下图所示的微博效果啦。
是不是感觉有点像样了,下节课我们将会讲解如何对时间和来源处理,以及增加微博工具栏的处理。
- 献给初学iOS的小盆友们——微博app项目开发之十二自定义cell代码补全
- 献给初学iOS的小盆友们——微博app项目开发之十一自定义cell和MVVM模式
- 献给初学iOS的小盆友们——微博app项目开发之二自定义tabBar
- 献给初学iOS的小盆友们——微博app项目开发之八封装代码
- 献给初学iOS的小盆友们——微博app项目开发之三设置导航条
- 献给初学iOS的小盆友们——微博app项目开发之四设置导航功能
- 献给初学iOS的小盆友们——微博app项目开发之五新特性界面
- 献给初学iOS的小盆友们——微博app项目开发之六OAuth授权
- 献给初学iOS的小盆友们——微博app项目开发之十五微博配图
- 献给初学iOS的小盆友们——微博app项目开发之七第一次获取微博数据
- 献给初学iOS的小盆友们——微博app项目开发之九未读数设置以及后台播放
- 献给初学iOS的小盆友们——微博app项目开发之十显示昵称与最新微博数
- 献给初学iOS的小盆友们——微博app项目开发之十三微博时间和来源处理
- 献给初学iOS的小盆友们——微博app项目开发之十六搭建发送微博界面(上)
- 献给初学iOS的小盆友们——微博app项目开发之十七搭建发送微博界面(中)
- 献给初学iOS的小盆友们——微博app项目开发之十八搭建发送微博界面(下)
- 献给初学iOS的小盆友们——微博app项目开发之十四转发微博修正以及添加微博工具条
- 献给初学iOS的小盆友们------微博app项目开发之一项目初始化
- C++关键字unisigned的讨论
- onethink中修改ucenter用户的密码
- Oulipo(KMP算法)
- IOS的一些坑与技巧
- [读书笔记]操作系统综述
- 献给初学iOS的小盆友们——微博app项目开发之十二自定义cell代码补全
- Python批量更改文件名
- PHP之进制转换
- Android之PreferenceFragment的使用:
- CentOS6.5下Tomcat搭建Solr5.4.0集群
- pb
- Java 日期处理 Date 、Calendar 和TimeZone类
- 实用代码
- UVA 11354Bond(MST+LCA)