iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程(二)
说明:该部分完成对自定义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>
1011@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;
3233//接口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{
15if (self = [super init]) {
16//使用KVC17 [self setValuesForKeysWithDictionary:dict];
18 }
19return self;
20}
2122/**
23 * 工厂方法
24 *
25 * @param dict 字典
26 *
27 * @return 模型
28*/29 +(instancetype)weiboModelWithDict:(NSDictionary *)dict
30{
31return [[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>
1011@class YYweiboModel;
12@interface YYweiboCell : UITableViewCell
131415 @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];
45if (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 }
78return 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];
103104//2.设置vip图标的数据
105//判断是否是vip,如果是那么就显示图标,并把字体设置为红色
106//注意这里的判断107if (_weibo.vip) {
108 self.vipView.hidden=NO;
109// [self.textLab setTintColor:[UIColor redColor]];110 self.nameLabel.textColor=[UIColor redColor];
111 }else112 {
113 self.vipView.hidden=YES;
114 self.nameLabel.textColor=[UIColor blackColor];
115 }
116117118//所以的vip图标都是一样的,没有必要每次都设置,只需要在构造方法中设置一次就可以了。
119// self.vipView.image=[UIImage imageNamed:@"vip"];
120121//3.设置正文内容的数据122 self.textLab.text=_weibo.text;
123124//4.设置配图的数据125 self.pictureView.image=[UIImage imageNamed:_weibo.picture];
126127//5.设置微博昵称数据128 self.nameLabel.text=_weibo.name;
129}
130131132/**
133 * 设置子控件的Frame
134*/135 -(void)settingFrame
136{
137//1.设置头像的frame138 CGFloat padding=10;
139 CGFloat iconViewX=padding;
140 CGFloat iconViewY=padding;
141 CGFloat iconViewW=30;
142 CGFloat iconViewH=30;
143144 self.iconView.frame=CGRectMake(iconViewX, iconViewY, iconViewW, iconViewH);
145146//2.设置微博昵称的frame
147//昵称的X值=头像的最大的x值+padding148 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);
153154//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);
161162//4.设置正文的frame163 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);
167168//5.设置配图的frame169if (_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 }
176177#warning 未完成
178}
179180181/**
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;
196return 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;
1516@end1718@implementation YYViewController
1920 - (void)viewDidLoad
21{
22 [super viewDidLoad];
23}
2425#pragma mark -懒加载
26 -(NSArray *)weibos
27{
28if (_weibos==Nil) {
29 NSString *fullpath=[[NSBundle mainBundle]pathForResource:@"statuses.plist" ofType:nil];
30 NSArray *arrayM=[NSArray arrayWithContentsOfFile:fullpath];
3132 NSMutableArray *models=[NSMutableArray arrayWithCapacity:arrayM.count];
33for (NSDictionary *dict in arrayM) {
34 YYweiboModel *weibomodel=[YYweiboModel weiboModelWithDict:dict];
35 [models addObject:weibomodel];
36 }
37 _weibos=[models copy];
38 }
39return _weibos;
40}
4142#pragma mark- 数据源方法
43//返回多少组
44//这里可以不写,默认返回一组45 -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
46{
47return1;
48}
49//每组多少行50 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
51{
52return self.weibos.count;
53}
54//每组每行的数据-设置cell55 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
56{
57//1.到缓存中去取cell58static NSString *ID=@"ID";
59//2.没有则创建cell60 YYweiboCell *cell=[tableView dequeueReusableCellWithIdentifier:ID];
61if (cell==nil) {
62 cell=[[YYweiboCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
63 }
6465//3.设置cell的数据66 cell.weibo=self.weibos[indexPath.row];
67//4.返回cell68return cell;
6970}
7172#pragma mark-设置每一组的高度
73 -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
74{
75//这里暂时给出一个高度,以后会做进一步的处理76return200;
77}
78#pragma mark- 隐藏状态栏
79 -(BOOL)prefersStatusBarHidden
80{
81return YES;
82}
83@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);
这里把计算过程封装在了下面的方法中:
1
/*
*
2
* 计算文本的宽高
3
*
4
* @param str 需要计算的文本
5
* @param font 文本显示的字体
6
* @param maxSize 文本显示的范围
7
*
8
* @return 文本占用的真实宽高
9
*/
10 - (CGSize)sizeWithString:(NSString *)str font:(UIFont *)font maxSize:(CGSize)maxSize
11{
12 NSDictionary *dict = @{NSFontAttributeName : font};
13// 如果将来计算的文字的范围超出了指定的范围,返回的就是指定的范围
14// 如果将来计算的文字的范围小于指定的范围, 返回的就是真实的范围15 CGSize size = [str boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:dict context:nil].size;
16return size;
17 }
原文:http://www.cnblogs.com/dondre/p/4093317.html
【说明】:本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:254677821)!