第四天
微博数据展示:获取服务器数据,json数据的解析,MVC的使用,自定义cell高度的计算,一些分类的设计。已经是第四天了,虽然每天都有课程,但这个东西也基本完成了一大半吧,一些忘掉的知识也捡起来了。看了一下第一次写的笔记,做到这个程度可是花了将近十多天的时间,这次这么短的时间就做到了着,还是有一点复制粘贴的成分,但是大致的思维过程还是有的,也练了一下编码速度的。四天时间主要就是回顾一下之前做的一些事情,下一步不打算接着做下去了,要将第一次没完成的很多细节完善,争取做得更加完美。简单的记录下今天吧,很多课上的很没意思的说。
1.很明显需要自定义cell,而微博展示这种比较复杂的cell,我们在一开始就把所有要用到的控件加进去,然后再根据数据选择是否进行显示。
2.首先是要在home模块中向新浪请求数据,[self loadStatus],方法中我们需要使用账号的access_token作为请求参数,通过SVAccountTool工具类很容易得到。
1 - (void)loadStatus 2 { 3 AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; 4 5 NSMutableDictionary *pramas = [NSMutableDictionary dictionary]; 6 // 拿到当前账号 7 SVAccount *account = [SVAccountTool account]; 8 pramas[@"access_token"] = account.access_token; 9 10 [manager GET:@"https://api.weibo.com/2/statuses/home_timeline.json" parameters:pramas progress:^(NSProgress * _Nonnull uploadProgress) { 11 12 } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { 13 // 将字典数组转为模型数组(里面放的就是IWStatus模型) 14 NSArray *statusArray = [SVStatus mj_objectArrayWithKeyValuesArray:responseObject[@"statuses"]]; 15 // 创建frame模型对象 16 NSMutableArray *statusFrameArray = [NSMutableArray array]; 17 for (SVStatus *status in statusArray) { 18 SVStatusFrame *statusFrame = [[SVStatusFrame alloc] init]; 19 // 传递微博模型数据 20 statusFrame.status = status; 21 [statusFrameArray addObject:statusFrame]; 22 } 23 // 赋值 24 self.statusFrames = statusFrameArray; 25 // 刷新表格 26 [self.tableView reloadData]; 27 } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { 28 NSLog(@"status error--%@", error); 29 }]; 30 }
3.在请求数据后,服务器会返回json数据,为了面向模型开发,添加SVStatus模型和SVUser模型,并根据新浪返回数据和我们需要的数据为其添加成员变量。(在这里第一次的时候是先进行了数据解析,直接在系统的cell上展示了头像、用户名等数据,这次做就直接自定义cell)
1 #import <Foundation/Foundation.h> 2 @class SVUser; 3 @interface SVStatus : NSObject 4 /** 5 * 微博创建时间 6 */ 7 @property (nonatomic, copy) NSString *created_at; 8 /** 9 * 微博ID 10 */ 11 @property (nonatomic, copy) NSString *ID; 12 /** 13 * 微博内容 14 */ 15 @property (nonatomic, copy) NSString *text; 16 /** 17 * 微博来源 18 */ 19 @property (nonatomic, copy) NSString *source; 20 /** 21 * 微博配图的缩略图地址 22 */ 23 @property (nonatomic, copy) NSString *thumbnail_pic; 24 /** 25 * 转发数 26 */ 27 @property (nonatomic, assign) int retwweted_count; 28 /** 29 * 评论数 30 */ 31 @property (nonatomic, assign) int reposts_count; 32 /** 33 * 点赞数 34 */ 35 @property (nonatomic, assign) int attitudes_count; 36 /** 37 * 发微博的人 38 */ 39 @property (nonatomic, strong) SVUser *user; 40 /** 41 * 转发的微博 42 */ 43 @property (nonatomic, strong) SVStatus *retweeted_status; 44 @end
1 #import <Foundation/Foundation.h> 2 3 @interface SVUser : NSObject 4 /** 5 * 用户的ID 6 */ 7 @property (nonatomic, copy) NSString *idstr; 8 /** 9 * 用户的昵称 10 */ 11 @property (nonatomic, copy) NSString *name; 12 /** 13 * 用户的头像 14 */ 15 @property (nonatomic, copy) NSString *profile_image_url; 16 17 /** 18 * 会员等级 19 */ 20 @property (nonatomic, assign) int mbrank; 21 /** 22 * 会员类型 23 */ 24 @property (nonatomic, assign) int mbtype; 25 @end
4.典型的cell高度不确定时,分析微博的结构,而微博的结构根据内容会有所不同,基本为三种:只有文字、文字和配图、带有转发的微博。不管哪种,按照从上到下的顺序,就可以将其分为三个部分:头像昵称、主要内容和转评赞条。为了确定位置,会再添加一个计算frame的模型SVStatusFrame,用来计算每一个控件在整个cell的位置。在SVStatusFrame中只需要重写status的setter方法,在给status设置值得时候,根据不同的值进行计算控件的frame,最后得出整个cell的高度。目前在SVStatusFrame的.h文件中哟很多关于字体、颜色的宏定义,还有目前对于头文件的引用也不是很规范,在基本效果完成之后会将他们进行抽取。
1 @interface SVStatusFrame : NSObject 2 @property (nonatomic, strong) SVStatus *status; 3 4 /** 顶部的view */ 5 @property (nonatomic, assign, readonly) CGRect topViewF; 6 /** 头像 */ 7 @property (nonatomic, assign, readonly) CGRect iconViewF; 8 /** 会员图标 */ 9 @property (nonatomic, assign, readonly) CGRect vipViewF; 10 /** 配图 */ 11 @property (nonatomic, assign, readonly) CGRect photoViewF; 12 /** 昵称 */ 13 @property (nonatomic, assign, readonly) CGRect nameLabelF; 14 /** 时间 */ 15 @property (nonatomic, assign, readonly) CGRect timeLabelF; 16 /** 来源 */ 17 @property (nonatomic, assign, readonly) CGRect sourceLabelF; 18 /** 正文\内容 */ 19 @property (nonatomic, assign, readonly) CGRect contentLabelF; 20 21 /** 被转发微博的view(父控件) */ 22 @property (nonatomic, assign, readonly) CGRect retweetViewF; 23 /** 被转发微博作者的昵称 */ 24 @property (nonatomic, assign, readonly) CGRect retweetNameLabelF; 25 /** 被转发微博的正文\内容 */ 26 @property (nonatomic, assign, readonly) CGRect retweetContentLabelF; 27 /** 被转发微博的配图 */ 28 @property (nonatomic, assign, readonly) CGRect retweetPhotoViewF; 29 30 /** 微博的工具条 */ 31 @property (nonatomic, assign, readonly) CGRect statusToolbarF; 32 33 /** cell的高度 */ 34 @property (nonatomic, assign, readonly) CGFloat cellHeight;
5.为了使cell不过于依赖控制器而存在,为其提供一个类方法来创建件cell,并在cell内部实现重用。在该方法中添加控件,添加控件分成了3个部分,其中的代码很简单的就是创建控件、设置只要不需改变的值、添加、保存起来。
1 // 全部的控件 2 @interface SVStatusCell() 3 /** 顶部的view */ 4 @property (nonatomic, weak) UIImageView *topView; 5 /** 头像 */ 6 @property (nonatomic, weak) UIImageView *iconView; 7 /** 会员图标 */ 8 @property (nonatomic, weak) UIImageView *vipView; 9 /** 配图 */ 10 @property (nonatomic, weak) UIImageView *photoView; 11 /** 昵称 */ 12 @property (nonatomic, weak) UILabel *nameLabel; 13 /** 时间 */ 14 @property (nonatomic, weak) UILabel *timeLabel; 15 /** 来源 */ 16 @property (nonatomic, weak) UILabel *sourceLabel; 17 /** 正文\内容 */ 18 @property (nonatomic, weak) UILabel *contentLabel; 19 20 /** 被转发微博的view(父控件) */ 21 @property (nonatomic, weak) UIImageView *retweetView; 22 /** 被转发微博作者的昵称 */ 23 @property (nonatomic, weak) UILabel *retweetNameLabel; 24 /** 被转发微博的正文\内容 */ 25 @property (nonatomic, weak) UILabel *retweetContentLabel; 26 /** 被转发微博的配图 */ 27 @property (nonatomic, weak) UIImageView *retweetPhotoView; 28 29 /** 微博的工具条 */ 30 @property (nonatomic, weak) UIImageView *statusToolbar; 31 @end
1 + (instancetype)cellWithtableView:(UITableView *)tableView 2 { 3 static NSString *ID = @"status"; 4 SVStatusCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; 5 if (cell == nil) { 6 cell = [[SVStatusCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID]; 7 } 8 return cell; 9 } 10 11 - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 12 { 13 self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 14 if (self) { 15 // 1.添加原创微博内部的子控件 16 [self setupOriginalSubviews]; 17 18 // 2.添加被转发微博内部的子控件 19 [self setupRetweetSubviews]; 20 21 // 3.添加微博的工具条 22 [self setupStatusToolBar]; 23 } 24 return self; 25 }
6.对于给cell上的控件赋值数据同样很简单,就是重写statusFrame的setter方法,再给他赋值的同时,将status数据传递过来。
1 /** 2 * 传递模型数据 3 */ 4 - (void)setStatusFrame:(SVStatusFrame *)statusFrame 5 { 6 _statusFrame = statusFrame; 7 8 // 1.原创微博 9 [self setupOriginalData]; 10 11 // 2.被转发微博 12 [self setupRetweetData]; 13 14 // 3.微博工具条 15 [self setupStatusToolbar]; 16 }
原文:http://www.cnblogs.com/sleen/p/5236568.html