iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程(二)
iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程(三·完结)
iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程(一)
http://www.cnblogs.com/wendingding/p/3766769.html
说明:该部分完成对自定义cell页面的基本搭建,尚未进行优化处理。且还存在很多问题,譬如每行的高度设置暂时是固定的,这些问题将会在下一篇文中解决。
一、实现效果
二、实现代码
数据模型部分:
YYweiboModel.h文件
1 // 2 // YYweiboModel.h 3 // 微博基本信息展示 4 // 5 // Created by 孔医己 on 14-6-2. 6 // Copyright (c) 2014年 itcast. All rights reserved. 7 // 8 9 #import <Foundation/Foundation.h> 10 11 @interface YYweiboModel : NSObject 12 /** 13 * 昵称 14 */ 15 @property(nonatomic,copy)NSString *name; 16 /** 17 * 正文 18 */ 19 @property(nonatomic,copy)NSString *text; 20 /** 21 * 头像 22 */ 23 @property(nonatomic,copy)NSString *icon; 24 /** 25 * 配图 26 */ 27 @property(nonatomic,copy)NSString *picture; 28 /** 29 * 是否是vip 30 */ 31 @property(nonatomic,assign)BOOL vip; 32 33 //接口 34 -(instancetype)initWithDict:(NSDictionary *)dict; 35 +(instancetype)weiboModelWithDict:(NSDictionary *)dict; 36 @end
YYweiboModel.m文件
1 // 2 // YYweiboModel.m 3 // 微博基本信息展示 4 // 5 // Created by 孔医己 on 14-6-2. 6 // Copyright (c) 2014年 itcast. All rights reserved. 7 // 8 9 #import "YYweiboModel.h" 10 11 @implementation YYweiboModel 12 13 -(instancetype)initWithDict:(NSDictionary *)dict 14 { 15 if (self = [super init]) { 16 //使用KVC 17 [self setValuesForKeysWithDictionary:dict]; 18 } 19 return self; 20 } 21 22 /** 23 * 工厂方法 24 * 25 * @param dict 字典 26 * 27 * @return 模型 28 */ 29 +(instancetype)weiboModelWithDict:(NSDictionary *)dict 30 { 31 return [[self alloc]initWithDict:dict]; 32 } 33 @end
视图部分:
YYweiboCell.h文件
1 // 2 // YYweiboCell.h 3 // 微博基本信息展示 4 // 5 // Created by 孔医己 on 14-6-2. 6 // Copyright (c) 2014年 itcast. All rights reserved. 7 // 8 9 #import <UIKit/UIKit.h> 10 11 @class YYweiboModel; 12 @interface YYweiboCell : UITableViewCell 13 14 15 @property(nonatomic,strong)YYweiboModel *weibo; 16 @end
YYweiboCell.m文件
1 // 2 // YYweiboCell.m 3 // 微博基本信息展示 4 // 5 // Created by 孔医己 on 14-6-2. 6 // Copyright (c) 2014年 itcast. All rights reserved. 7 // 8 9 #import "YYweiboCell.h" 10 #import "YYweiboModel.h" 11 12 #define YYNameFont [UIFont systemFontOfSize:15] 13 #define YYTextFont [UIFont systemFontOfSize:16] 14 15 @interface YYweiboCell() 16 /** 17 * 头像 18 */ 19 @property(nonatomic,weak)UIImageView *iconView; 20 /** 21 * vip图标 22 */ 23 @property(nonatomic,weak)UIImageView *vipView; 24 /** 25 * 微博昵称 26 */ 27 @property(nonatomic,weak)UILabel *nameLabel; 28 /** 29 * 配图 30 */ 31 @property(nonatomic,weak)UIImageView *pictureView; 32 /** 33 * 正文 34 */ 35 @property(nonatomic,weak)UILabel *textLab; 36 37 @end 38 39 @implementation YYweiboCell 40 41 //重写构造方法,让自定义的cell一创建出来就有五个子控件 42 - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 43 { 44 self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 45 if (self) { 46 //1.添加头像 47 UIImageView *img=[[UIImageView alloc]init]; 48 [self.contentView addSubview:img]; 49 self.iconView=img; 50 51 //2.添加昵称 52 UILabel *namelab=[[UILabel alloc]init]; 53 //在创建昵称的时候就要告诉它,将来要用15号字体显示 54 namelab.font=YYNameFont; 55 [self.contentView addSubview:namelab]; 56 self.nameLabel=namelab; 57 58 //3.vip 59 UIImageView *vipview=[[UIImageView alloc]init]; 60 vipview.image=[UIImage imageNamed:@"vip"]; 61 [self.contentView addSubview:vipview]; 62 self.vipView=vipview; 63 64 //4.正文 65 UILabel *textlab=[[UILabel alloc]init]; 66 //在创建正文的时候就要告诉它,将来要用16号字体显示 67 textlab.font=YYTextFont; 68 //设置正文在进行显示的时候进行换行 69 textlab.numberOfLines=0; 70 [self.contentView addSubview:textlab]; 71 self.textLab=textlab; 72 73 //5.图片 74 UIImageView *picture=[[UIImageView alloc]init]; 75 [self.contentView addSubview:picture]; 76 self.pictureView=picture; 77 } 78 return self; 79 } 80 81 /** 82 * 重写set方法 83 * 84 * @param weibo 微博 85 */ 86 -(void)setWeibo:(YYweiboModel *)weibo 87 { 88 //不要忘了,记录传递进来的模型 89 _weibo=weibo; 90 //给子控件赋值数据 91 [self settingData]; 92 //设置子控件的frame 93 [self settingFrame]; 94 } 95 96 /** 97 * 对子控件的数据进行设置 98 */ 99 -(void)settingData 100 { 101 //1.设置头像的数据 102 self.iconView.image=[UIImage imageNamed:_weibo.icon]; 103 104 //2.设置vip图标的数据 105 //判断是否是vip,如果是那么就显示图标,并把字体设置为红色 106 //注意这里的判断 107 if (_weibo.vip) { 108 self.vipView.hidden=NO; 109 // [self.textLab setTintColor:[UIColor redColor]]; 110 self.nameLabel.textColor=[UIColor redColor]; 111 }else 112 { 113 self.vipView.hidden=YES; 114 self.nameLabel.textColor=[UIColor blackColor]; 115 } 116 117 118 //所以的vip图标都是一样的,没有必要每次都设置,只需要在构造方法中设置一次就可以了。 119 // self.vipView.image=[UIImage imageNamed:@"vip"]; 120 121 //3.设置正文内容的数据 122 self.textLab.text=_weibo.text; 123 124 //4.设置配图的数据 125 self.pictureView.image=[UIImage imageNamed:_weibo.picture]; 126 127 //5.设置微博昵称数据 128 self.nameLabel.text=_weibo.name; 129 } 130 131 132 /** 133 * 设置子控件的Frame 134 */ 135 -(void)settingFrame 136 { 137 //1.设置头像的frame 138 CGFloat padding=10; 139 CGFloat iconViewX=padding; 140 CGFloat iconViewY=padding; 141 CGFloat iconViewW=30; 142 CGFloat iconViewH=30; 143 144 self.iconView.frame=CGRectMake(iconViewX, iconViewY, iconViewW, iconViewH); 145 146 //2.设置微博昵称的frame 147 //昵称的X值=头像的最大的x值+padding 148 CGFloat nameLabelX=CGRectGetMaxX(self.iconView.frame)+padding; 149 CGSize nameSize=[self sizeWithString:_weibo.name font:YYNameFont maxSize:CGSizeMake(MAXFLOAT,MAXFLOAT)]; 150 //昵称的Y值=(头像高度-整个文本字体的高度)*0.5+头像的Y值 151 CGFloat nameLableY=(iconViewH-nameSize.height)*0.5+iconViewY; 152 self.nameLabel.frame=CGRectMake(nameLabelX, nameLableY, nameSize.width, nameSize.height); 153 154 //3.设置vip图标的frame 155 //vip图标的x值=昵称的最大x值+间隙 156 CGFloat vipX=CGRectGetMaxX(self.nameLabel.frame)+padding; 157 CGFloat vipY=nameLableY; 158 CGFloat vipW=14; 159 CGFloat vipH=14; 160 self.vipView.frame=CGRectMake(vipX, vipY, vipW, vipH); 161 162 //4.设置正文的frame 163 CGFloat textLabX=iconViewX; 164 CGFloat textLabY=CGRectGetMaxY(self.iconView.frame)+padding; 165 CGSize textSize=[self sizeWithString:_weibo.text font:YYTextFont maxSize:CGSizeMake(300,MAXFLOAT)]; 166 self.textLab.frame=CGRectMake(textLabX, textLabY, textSize.width, textSize.height); 167 168 //5.设置配图的frame 169 if (_weibo.picture) { 170 CGFloat pictureX=iconViewX; 171 CGFloat pictureY=CGRectGetMaxY(self.textLab.frame)+padding; 172 CGFloat pictureW=100; 173 CGFloat pictureH=100; 174 self.pictureView.frame=CGRectMake(pictureX, pictureY, pictureW, pictureH); 175 } 176 177 #warning 未完成 178 } 179 180 181 /** 182 * 计算文本的宽高 183 * 184 * @param str 需要计算的文本 185 * @param font 文本显示的字体 186 * @param maxSize 文本显示的范围 187 * 188 * @return 文本占用的真实宽高 189 */ 190 - (CGSize)sizeWithString:(NSString *)str font:(UIFont *)font maxSize:(CGSize)maxSize 191 { 192 NSDictionary *dict = @{NSFontAttributeName : font}; 193 // 如果将来计算的文字的范围超出了指定的范围,返回的就是指定的范围 194 // 如果将来计算的文字的范围小于指定的范围, 返回的就是真实的范围 195 CGSize size = [str boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:dict context:nil].size; 196 return size; 197 } 198 @end
主控制器部分:
YYViewController.m文件
1 // 2 // YYViewController.m 3 // 微博基本信息展示 4 // 5 // Created by 孔医己 on 14-6-2. 6 // Copyright (c) 2014年 itcast. All rights reserved. 7 // 8 9 #import "YYViewController.h" 10 #import "YYweiboModel.h" 11 #import "YYweiboCell.h" 12 13 @interface YYViewController () 14 @property(nonatomic,strong)NSArray *weibos; 15 16 @end 17 18 @implementation YYViewController 19 20 - (void)viewDidLoad 21 { 22 [super viewDidLoad]; 23 } 24 25 #pragma mark -懒加载 26 -(NSArray *)weibos 27 { 28 if (_weibos==Nil) { 29 NSString *fullpath=[[NSBundle mainBundle]pathForResource:@"statuses.plist" ofType:nil]; 30 NSArray *arrayM=[NSArray arrayWithContentsOfFile:fullpath]; 31 32 NSMutableArray *models=[NSMutableArray arrayWithCapacity:arrayM.count]; 33 for (NSDictionary *dict in arrayM) { 34 YYweiboModel *weibomodel=[YYweiboModel weiboModelWithDict:dict]; 35 [models addObject:weibomodel]; 36 } 37 _weibos=[models copy]; 38 } 39 return _weibos; 40 } 41 42 #pragma mark- 数据源方法 43 //返回多少组 44 //这里可以不写,默认返回一组 45 -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 46 { 47 return 1; 48 } 49 //每组多少行 50 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 51 { 52 return self.weibos.count; 53 } 54 //每组每行的数据-设置cell 55 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 56 { 57 //1.到缓存中去取cell 58 static NSString *ID=@"ID"; 59 //2.没有则创建cell 60 YYweiboCell *cell=[tableView dequeueReusableCellWithIdentifier:ID]; 61 if (cell==nil) { 62 cell=[[YYweiboCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID]; 63 } 64 65 //3.设置cell的数据 66 cell.weibo=self.weibos[indexPath.row]; 67 //4.返回cell 68 return cell; 69 70 } 71 72 #pragma mark-设置每一组的高度 73 -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 74 { 75 //这里暂时给出一个高度,以后会做进一步的处理 76 return 200; 77 } 78 #pragma mark- 隐藏状态栏 79 -(BOOL)prefersStatusBarHidden 80 { 81 return YES; 82 } 83 @end
三、实现思路整理
//4.设置正文的frame
CGFloat textLabX=iconViewX;
CGFloat textLabY=CGRectGetMaxY(self.iconView.frame)+padding;
CGSize textSize=[self sizeWithString:_weibo.text font:YYTextFont maxSize:CGSizeMake(300,MAXFLOAT)];
self.textLab.frame=CGRectMake(textLabX, textLabY, textSize.width, textSize.height);
这里把计算过程封装在了下面的方法中:
/** * 计算文本的宽高 * * @param str 需要计算的文本 * @param font 文本显示的字体 * @param maxSize 文本显示的范围 * * @return 文本占用的真实宽高 */ - (CGSize)sizeWithString:(NSString *)str font:(UIFont *)font maxSize:(CGSize)maxSize { NSDictionary *dict = @{NSFontAttributeName : font}; // 如果将来计算的文字的范围超出了指定的范围,返回的就是指定的范围 // 如果将来计算的文字的范围小于指定的范围, 返回的就是真实的范围 CGSize size = [str boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:dict context:nil].size; return size; }