iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程(二)
2014-11-12 19:43
951 查看
iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程(二)
说明:该部分完成对自定义cell页面的基本搭建,尚未进行优化处理。且还存在很多问题,譬如每行的高度设置暂时是固定的,这些问题将会在下一篇文中解决。
一、实现效果
二、实现代码
数据模型部分:
YYweiboModel.h文件
YYweiboModel.m文件
视图部分:
YYweiboCell.h文件
YYweiboCell.m文件
主控制器部分:
YYViewController.m文件
三、实现思路整理
设置frame时的思路和一些注意点:
(1)
一个控件没有frame肯定显示不出来
设置frame的过程中需要从哪里入手呢?以后遇到要为很多控件设置frmae的时候。建议先找控件之间的关系,先找准一个固定不变的点,然后再计算不确定的控件的frmae.总要有一个点,再来计算其他的东西。
在这个应用中找到规律,先设置头像的,再设置其他的。
在真实开发中间隙等是由美工提供的。计算x,y,w,h等得值。分别计算所有控件的frame,注意这是依赖于数据的。
(2)
获取控件的最大值CGRectMaxX(SELF.ICONvIEW.FRAME)或取头像最大的x值。
在ios7中计算文字的宽度和高度?
需要传递一个字体。影响文本的宽度和高度的因素:(1)字体的大小;(2)存放文本的最大的范围。在计算文本的宽高时,应该告诉这两个。
_weibo.name sizewithFont:nil ios7以前的方法
ios7以后要传4个参数
boundingRectWthSize:(cgsize).....将来能够显示文本的范围,宽和高。
nsdictionary *dict=@{NSfontattributename:宏}
在创建昵称的时候就要告诉它,将来以15号的字体显示。(注意不要忘了这一点,否则计算出来的不准确)
不限制其宽度和高度的大小:MAXFLOAT
计算文本的宽高,把这个功能封装。接受三个参数,字符串,字体,Maxsize.返回值为CGSIZE.
需要计算的文本
文本显示的字体
文本显示的范围
文本占用的真实宽高。
注意:有关字体的计算,在创建的时候就要指定其将要显示的字号是多大。
内容文本的宽高和昵称不一样,正文会换行,那么就限制一下其宽度,不限制高度就可以了。
cell的高度不够,需要在viewdioad中设置cell的高度(大失所望)
默认label只显示一行。当创建正文的时候,还要设置让其自定换行。设置为0
(3)
如果没有配图的话就不计算它的宽高,把计算的过程放到if大括号里边。
设置配图的问题:有的又配图,有的没有配图(cell滚动离开视野放到缓存池中)。问题在于,如果需要一个没有配图的,这时候去缓存中去取,取到的是一个有配图的那不是就冲突了么?
如何解决这个问题:
在设置数据的时候进行判断,如果有配图,那么就设置数据,.hidden=no;
如果没有配图的话那就不让它显示。hidden=YES.
注意点:在tableview中有一个复用的问题,有显示就要有隐藏。这是一个陷阱。一定要记住。
(4)
所有的vip图标都是同一个,可以在init初始化方法中对vip图标进行设置。
此时出现了一个新的问题。所有的宽高计算一次就可以了,但是这里每次滚动都会调用计算,没有必要。
四、重要说明
IOS7以后计算文本的宽度和高度:
//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);
这里把计算过程封装在了下面的方法中:
说明:该部分完成对自定义cell页面的基本搭建,尚未进行优化处理。且还存在很多问题,譬如每行的高度设置暂时是固定的,这些问题将会在下一篇文中解决。
一、实现效果
二、实现代码
数据模型部分:
YYweiboModel.h文件
// // YYweiboModel.h // 微博基本信息展示 // // Created by 孔医己 on 14-6-2. // Copyright (c) 2014年 itcast. All rights reserved. // #import <Foundation/Foundation.h> @interface YYweiboModel : NSObject /** * 昵称 */ @property(nonatomic,copy)NSString *name; /** * 正文 */ @property(nonatomic,copy)NSString *text; /** * 头像 */ @property(nonatomic,copy)NSString *icon; /** * 配图 */ @property(nonatomic,copy)NSString *picture; /** * 是否是vip */ @property(nonatomic,assign)BOOL vip; //接口 -(instancetype)initWithDict:(NSDictionary *)dict; +(instancetype)weiboModelWithDict:(NSDictionary *)dict; @end
YYweiboModel.m文件
// // YYweiboModel.m // 微博基本信息展示 // // Created by 孔医己 on 14-6-2. // Copyright (c) 2014年 itcast. All rights reserved. // #import "YYweiboModel.h" @implementation YYweiboModel -(instancetype)initWithDict:(NSDictionary *)dict { if (self = [super init]) { //使用KVC [self setValuesForKeysWithDictionary:dict]; } return self; } /** * 工厂方法 * * @param dict 字典 * * @return 模型 */ +(instancetype)weiboModelWithDict:(NSDictionary *)dict { return [[self alloc]initWithDict:dict]; } @end
视图部分:
YYweiboCell.h文件
// // YYweiboCell.h // 微博基本信息展示 // // Created by 孔医己 on 14-6-2. // Copyright (c) 2014年 itcast. All rights reserved. // #import <UIKit/UIKit.h> @class YYweiboModel; @interface YYweiboCell : UITableViewCell @property(nonatomic,strong)YYweiboModel *weibo; @end
YYweiboCell.m文件
// // YYweiboCell.m // 微博基本信息展示 // // Created by 孔医己 on 14-6-2. // Copyright (c) 2014年 itcast. All rights reserved. // #import "YYweiboCell.h" #import "YYweiboModel.h" #define YYNameFont [UIFont systemFontOfSize:15] #define YYTextFont [UIFont systemFontOfSize:16] @interface YYweiboCell() /** * 头像 */ @property(nonatomic,weak)UIImageView *iconView; /** * vip图标 */ @property(nonatomic,weak)UIImageView *vipView; /** * 微博昵称 */ @property(nonatomic,weak)UILabel *nameLabel; /** * 配图 */ @property(nonatomic,weak)UIImageView *pictureView; /** * 正文 */ @property(nonatomic,weak)UILabel *textLab; @end @implementation YYweiboCell //重写构造方法,让自定义的cell一创建出来就有五个子控件 - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { //1.添加头像 UIImageView *img=[[UIImageView alloc]init]; [self.contentView addSubview:img]; self.iconView=img; //2.添加昵称 UILabel *namelab=[[UILabel alloc]init]; //在创建昵称的时候就要告诉它,将来要用15号字体显示 namelab.font=YYNameFont; [self.contentView addSubview:namelab]; self.nameLabel=namelab; //3.vip UIImageView *vipview=[[UIImageView alloc]init]; vipview.image=[UIImage imageNamed:@"vip"]; [self.contentView addSubview:vipview]; self.vipView=vipview; //4.正文 UILabel *textlab=[[UILabel alloc]init]; //在创建正文的时候就要告诉它,将来要用16号字体显示 textlab.font=YYTextFont; //设置正文在进行显示的时候进行换行 textlab.numberOfLines=0; [self.contentView addSubview:textlab]; self.textLab=textlab; //5.图片 UIImageView *picture=[[UIImageView alloc]init]; [self.contentView addSubview:picture]; self.pictureView=picture; } return self; } /** * 重写set方法 * * @param weibo 微博 */ -(void)setWeibo:(YYweiboModel *)weibo { //不要忘了,记录传递进来的模型 _weibo=weibo; //给子控件赋值数据 [self settingData]; //设置子控件的frame [self settingFrame]; } /** * 对子控件的数据进行设置 */ -(void)settingData { //1.设置头像的数据 self.iconView.image=[UIImage imageNamed:_weibo.icon]; //2.设置vip图标的数据 //判断是否是vip,如果是那么就显示图标,并把字体设置为红色 //注意这里的判断 if (_weibo.vip) { self.vipView.hidden=NO; // [self.textLab setTintColor:[UIColor redColor]]; self.nameLabel.textColor=[UIColor redColor]; }else { self.vipView.hidden=YES; self.nameLabel.textColor=[UIColor blackColor]; } //所以的vip图标都是一样的,没有必要每次都设置,只需要在构造方法中设置一次就可以了。 // self.vipView.image=[UIImage imageNamed:@"vip"]; //3.设置正文内容的数据 self.textLab.text=_weibo.text; //4.设置配图的数据 self.pictureView.image=[UIImage imageNamed:_weibo.picture]; //5.设置微博昵称数据 self.nameLabel.text=_weibo.name; } /** * 设置子控件的Frame */ -(void)settingFrame { //1.设置头像的frame CGFloat padding=10; CGFloat iconViewX=padding; CGFloat iconViewY=padding; CGFloat iconViewW=30; CGFloat iconViewH=30; self.iconView.frame=CGRectMake(iconViewX, iconViewY, iconViewW, iconViewH); //2.设置微博昵称的frame //昵称的X值=头像的最大的x值+padding CGFloat nameLabelX=CGRectGetMaxX(self.iconView.frame)+padding; CGSize nameSize=[self sizeWithString:_weibo.name font:YYNameFont maxSize:CGSizeMake(MAXFLOAT,MAXFLOAT)]; //昵称的Y值=(头像高度-整个文本字体的高度)*0.5+头像的Y值 CGFloat nameLableY=(iconViewH-nameSize.height)*0.5+iconViewY; self.nameLabel.frame=CGRectMake(nameLabelX, nameLableY, nameSize.width, nameSize.height); //3.设置vip图标的frame //vip图标的x值=昵称的最大x值+间隙 CGFloat vipX=CGRectGetMaxX(self.nameLabel.frame)+padding; CGFloat vipY=nameLableY; CGFloat vipW=14; CGFloat vipH=14; self.vipView.frame=CGRectMake(vipX, vipY, vipW, vipH); //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); //5.设置配图的frame if (_weibo.picture) { CGFloat pictureX=iconViewX; CGFloat pictureY=CGRectGetMaxY(self.textLab.frame)+padding; CGFloat pictureW=100; CGFloat pictureH=100; self.pictureView.frame=CGRectMake(pictureX, pictureY, pictureW, pictureH); } #warning 未完成 } /** * 计算文本的宽高 * * @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; } @end
主控制器部分:
YYViewController.m文件
// // YYViewController.m // 微博基本信息展示 // // Created by 孔医己 on 14-6-2. // Copyright (c) 2014年 itcast. All rights reserved. // #import "YYViewController.h" #import "YYweiboModel.h" #import "YYweiboCell.h" @interface YYViewController () @property(nonatomic,strong)NSArray *weibos; @end @implementation YYViewController - (void)viewDidLoad { [super viewDidLoad]; } #pragma mark -懒加载 -(NSArray *)weibos { if (_weibos==Nil) { NSString *fullpath=[[NSBundle mainBundle]pathForResource:@"statuses.plist" ofType:nil]; NSArray *arrayM=[NSArray arrayWithContentsOfFile:fullpath]; NSMutableArray *models=[NSMutableArray arrayWithCapacity:arrayM.count]; for (NSDictionary *dict in arrayM) { YYweiboModel *weibomodel=[YYweiboModel weiboModelWithDict:dict]; [models addObject:weibomodel]; } _weibos=[models copy]; } return _weibos; } #pragma mark- 数据源方法 //返回多少组 //这里可以不写,默认返回一组 -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } //每组多少行 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.weibos.count; } //每组每行的数据-设置cell -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { //1.到缓存中去取cell static NSString *ID=@"ID"; //2.没有则创建cell YYweiboCell *cell=[tableView dequeueReusableCellWithIdentifier:ID]; if (cell==nil) { cell=[[YYweiboCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID]; } //3.设置cell的数据 cell.weibo=self.weibos[indexPath.row]; //4.返回cell return cell; } #pragma mark-设置每一组的高度 -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { //这里暂时给出一个高度,以后会做进一步的处理 return 200; } #pragma mark- 隐藏状态栏 -(BOOL)prefersStatusBarHidden { return YES; } @end
三、实现思路整理
设置frame时的思路和一些注意点:
(1)
一个控件没有frame肯定显示不出来
设置frame的过程中需要从哪里入手呢?以后遇到要为很多控件设置frmae的时候。建议先找控件之间的关系,先找准一个固定不变的点,然后再计算不确定的控件的frmae.总要有一个点,再来计算其他的东西。
在这个应用中找到规律,先设置头像的,再设置其他的。
在真实开发中间隙等是由美工提供的。计算x,y,w,h等得值。分别计算所有控件的frame,注意这是依赖于数据的。
(2)
获取控件的最大值CGRectMaxX(SELF.ICONvIEW.FRAME)或取头像最大的x值。
在ios7中计算文字的宽度和高度?
需要传递一个字体。影响文本的宽度和高度的因素:(1)字体的大小;(2)存放文本的最大的范围。在计算文本的宽高时,应该告诉这两个。
_weibo.name sizewithFont:nil ios7以前的方法
ios7以后要传4个参数
boundingRectWthSize:(cgsize).....将来能够显示文本的范围,宽和高。
nsdictionary *dict=@{NSfontattributename:宏}
在创建昵称的时候就要告诉它,将来以15号的字体显示。(注意不要忘了这一点,否则计算出来的不准确)
不限制其宽度和高度的大小:MAXFLOAT
计算文本的宽高,把这个功能封装。接受三个参数,字符串,字体,Maxsize.返回值为CGSIZE.
需要计算的文本
文本显示的字体
文本显示的范围
文本占用的真实宽高。
注意:有关字体的计算,在创建的时候就要指定其将要显示的字号是多大。
内容文本的宽高和昵称不一样,正文会换行,那么就限制一下其宽度,不限制高度就可以了。
cell的高度不够,需要在viewdioad中设置cell的高度(大失所望)
默认label只显示一行。当创建正文的时候,还要设置让其自定换行。设置为0
(3)
如果没有配图的话就不计算它的宽高,把计算的过程放到if大括号里边。
设置配图的问题:有的又配图,有的没有配图(cell滚动离开视野放到缓存池中)。问题在于,如果需要一个没有配图的,这时候去缓存中去取,取到的是一个有配图的那不是就冲突了么?
如何解决这个问题:
在设置数据的时候进行判断,如果有配图,那么就设置数据,.hidden=no;
如果没有配图的话那就不让它显示。hidden=YES.
注意点:在tableview中有一个复用的问题,有显示就要有隐藏。这是一个陷阱。一定要记住。
(4)
所有的vip图标都是同一个,可以在init初始化方法中对vip图标进行设置。
此时出现了一个新的问题。所有的宽高计算一次就可以了,但是这里每次滚动都会调用计算,没有必要。
四、重要说明
IOS7以后计算文本的宽度和高度:
//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; }
相关文章推荐
- iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程(二) - 文顶顶
- iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程(一)
- iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程(一) - 文顶顶
- iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程(三·完结)
- iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程
- iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程(二)
- iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程(三·完结)
- iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程(一)
- iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程(一)
- iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程(三·完结)
- iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程(三·完结) - 文顶顶
- iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程(二)
- iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程
- iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程(二)
- ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局
- ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局
- ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局
- ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局
- ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局
- ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局