分析手动构建复杂的Cell—(新浪为例)
cell的最终实现效果如下:
先要分析每个cell有什么东西。具体每个cell什么东西,都是一些从接口获取得到的,所以数据就对应我们的model。
在设计阶段,合理的设计非常有必要。我能想到的是,通过抽象出比较共同的东西。这一点最好和接口对应起来。请求评论的接口,返回参数和主页微博列表请求参数,有哪些共同的属性。对于微博来说,有uid,weiboid等等。所以,根据接口返回的数据,我们抽象出一个基本类型。代表model的基类。
现在我们有数据了,有一个比较好的方式,就是用严格的MVC来做。和我们抽象出的接基类,对应的就是框架(frame)基类。在frame类中,有一个model,负责提取model里面的数据然后再frame类中具体去布局。
比如这里的XlBaseText其属性定义就是右图所示。几乎关于微博,还是评论微博,还是转发的接口都有这几个共同的字段。所以这就作为所有内容的基类。
说说隐藏的get和set吧。在get中,个性化数据返回格式。比如左图的,创建日期的get方法。将获取的的json数据,根据实际需要的根式,在get中个性化处理。返回正确的格式。
其实这里完全可以抽象出一个公用的方法,就是格式化时间的方法。
1、用从json获取的日期格式,初始化NSDateFormate。
2、自定义我们需要的格式,将日期转换为字符串。
3、得到时间间隔
4、判断时间差,格式化返回字符串
其实在get中设置,在set中是实现懒加载。
有必要再说说set,如果通过代码不均。我们应该在给一个框架模型的model赋值的时候,就计算好model里面属性要显示到界面的具体位置,达到高内聚的效果。而不是一一的把数据都赋值好了之后,然后再到其他类中去完成frame。比如下面的XlBaseTextCellFrame中:定义好了model里面数据显示在界面的框架。
那么在给model赋值的时候就应该给各各框架确定好大小。
在这里只设置了部分控件的frame,因为还有很多个性化的需求,在主页中的cell需要显示发送园和时间,而评论的cell就不需要。所以在basetextframe中只做了相同元素的不均。如下图
在来述说,结合view的时候了
mdeol已经包含了数据和frame,那么view则只需要提供相应的控件就行了
来看
这是对应.m
注意添加子控件一定要在init中。因为马上就要用到子控件进行赋值。
赋值的过程还是在frame的set方法中进行,这样一旦给frame赋好了值,那么子控件就有数据和frame了。
然后就可以优雅的赋值了。分层思想
#pragma mark 3.1、设置子控件内容
- (void)settingSubViewForContent
{
// 1、设置头像
[_avata setUser:_cellFrame.dataModel.user ofType:_cellFrame.avataType];
// 2、设置昵称
_screenName.text = _cellFrame.dataModel.user.screenName;
if (_cellFrame.dataModel.user.mbtype == kMbTypeNone) {
_screenName.textColor = kScreenNameColor;
} else {
_screenName.textColor = kMBScreenNameColor;
}
// 3 设置会员图标
if (_cellFrame.dataModel.user.mbtype == kMbTypeNone) {
_mbIcon.hidden = YES;
} else {
_mbIcon.hidden = NO;
}
// 4、设置时间
_time.text = _cellFrame.dataModel.createdAt;
// 5、设置来源
_source.text = _cellFrame.dataModel.source;
// 6、设置正文
_text.text = _cellFrame.dataModel.text;
}
#pragma mark 3.2、设置子控件Frame
- (void)settingSubViewForFrame
{
// 1、设置头像尺寸位置
_avata.frame = _cellFrame.avataRect;
// 2、设置昵称尺寸位置
_screenName.frame = _cellFrame.screenNameRect;
// 3、设置会员图标尺寸位置
_mbIcon.frame = _cellFrame.mbIconRect;
// 4、设置时间尺寸位置
_time.frame = _cellFrame.timeRect;
// 5、设置来源标签位置
_source.frame = _cellFrame.sourceRect;
// 6、设置正文尺寸位置
_text.frame = _cellFrame.textRect;
}
到了这里其实大部分已经差不多了。还有一点注意的是,在获得网络请求在tableviewVC中一定要将请求的数据包装成我们的cellframe。如下
- (NSArray *)statusFrameTranslateFromStatusArray:(NSArray *)statusArray
{
//保存获取的微博列表的数组
NSMutableArray *statusFrameArray = [NSMutableArray array];
for (XlStatus *status in statusArray) {
XlHomeStatusCellFrame *statusCellFrame = [[XlHomeStatusCellFrame alloc] init];
statusCellFrame.dataModel = status;
[statusFrameArray addObject:statusCellFrame];
}
return statusFrameArray;
}
这时候tableVC中的数据原就可以设置为cellframe了。包含了数据与框架