一、计算Cell子控件的frame
1.来,看一下,刚才我们已经做到把这个模型设置给自定义的cell了吧,
那么,在这个自定义Cell里面呢,我们是不是要开始设置数据了,
设置数据,我们,设置数据,其实很简单,就是把我们这里边的每一个控件,对应的值,从模型里面取出来,给了它,是不是就OK了,
2.第一个,我们设置的是这个头像,
头像,我们找到self.imgView……,里面有一个叫做什么,Icon吧,
self.imgViewIcon,这是头像吧,
“点”image,
self.imgViewIcon.image
self.imgViewIcon.image = [UIImage imageNamed:
这个地方,是不是要拿到模型,
3.我们这里模型,可以怎么拿,可以self.weibos,
来,我们把这个取出来吧,把这个取出来,注意看,
CZWeibo,
CZWeibo *model = self.weibo;
这样的话, 这个是不是就是那个模型,
这里就等于我们这个模型"点"icon,
为什么这里“点”不出来呢,因为我们这里,缺一个啥,
是不是缺一个头文件啊,
它是不是变色了,
这样的话,设置头像,
1)头像数据,设置好了,
就这么一句话,
2)OK,接下来,设置昵称,
self.lblNickName.text = model.name;
这是设置昵称,
3)设置会员,
注意,这个会员,有点儿不一样,
只要你是会员,头像是不是都是这个头像啊,
会员图标,是不是都是这个黄色,皇冠的这个图标,
会员图标,都是一样的,所以说,
不会说,你,比如说,头像,第一个人,头像是这个,第二个人,头像是这个,第三个人,头像是另外一个,每个人头像,是不是都可能不一样啊,
但是,会员图标,所有的人,只要是会员,图标是一样的,明白,
所以说,设置会员头像,这个数据,没有必要写在这里,
为什么呢,注意听,如果说,你把设置会员那个图标,那句话,写在这个setting方法里面,这个setting方法,在哪里调,
是不是在这个设置微博属性
是不是在这个设置微博属性这个方法里面调,
这个设置微博属性,set方法,这儿在哪儿调,
是不是这了去调用,
在这里调用话,每次调一次,就会重新设置一次这个会员的图标,
但是,会员图标,有必要每次都重新设置吗,
设置一次,是不是就够了,
反正都是一样的,
所以说,这句话,
这句话,没有必要,设置会员图标,没有必要放在这儿,
而是,可以放哪儿,,
在创建会员
在创建会员头像的时候,在创建的时候,直接在这里,
imgViewVip.image = [UIImage imageNamed:@“vip”];
这儿直接写死,vip,
就这么,在这里,写一次,就可以了,
创建控件的时候,直接设置一次头像是vip,
接下来,在设置数据这个地方,
你只要根据它是不是vip,判断是否应该显示这个图标,就OK了,
明白,这里不需要就是动态每次都设置它的图片,
不需要,设置一次就够了,
如果,
如果,model.isVip
如果它是会员,我就让
self.imgViewVip.hidden = NO;
如果是会员,就不隐藏,是不是就显示啊,
else {
//如果它不是会员呢,
//如果它不是会员,是不是就让它隐藏吧,
self.imgViewVip.hidden = YES;
}
就让它隐藏,
这就是设置会员头像是否显示,
注意,这个地方一定要这样写,一定要if——else,两个都写上,
因为,我们这里向上滚动的时候,
向上滚动的时候,这个Cell,等会儿要重用这个Cell啊,
Cell重用的时候,假如说,把第一个单元格,把第一行滚出去了,
然后呢,最后一行要滚进来一个,第一行,滚出去的是一个会员,滚进来的是一个不是会员,那么你这个不是会员的这个人,如果用了这个是会员的这个Cell,重用了这个Cell,这个时候,这个Cell,默认是皇冠,
就会把那个不是会员的皇冠,这儿默认也显示出来了,
所以说,对于每一条数据,在这里都要判断一下,
如果是会员,就显示,如果不是会员,就隐藏啊,
所以说,每一个单元格,设置的时候,都要重新判断一下,不然的话,在单元格重用的时候,就会造成你用了别人的单元格,别人那个图片,显示到你这儿来了,
4)正文,怎么设置,
self.lblText.text = model.text;
5)配图
配图,我们这里,也得判断一下,
如果说,这个人,比如说,你看,
如果说,这个人,有配图,
是不是就设置一下,配图,
同时让配图显示出来,
如果这个人就没有配图,
还有必要去设置一下吗,
同时是不是还得把这个配图隐藏啊,
对吧,所以这儿也要做一下判断,
也是得根据,有配图,还是没配图,
要做一个判断,
有人说,这个头像,为什么不做判断,有头像、没头像,
废话,头像都有吧……
昵称为什么不做判断,有昵称、没昵称,
昵称是不是也都有,
这些都有,
昵称颜色,那时候咱们再看,
好,配图,怎么判断,
if (model.picture){
//如果,当前这个模型,“点”picture,如果要是没有配图,是不是就是nil啊,如果要是nil,就表示没有配图,如果不是nil,就是YES,就表示有配图吧,
//如果有配图
//如果没有配图,就是nil,nil的话,就不执行if语句了,
//如果有配图,就不是nil,不是nil的话,才执行if语句,
//如果有配图,让self.imgViewPicture.image = [UIImage imageNamed:model.picture],是不是这么来设置一下,
self.imgViewPicture.image = [UIImage imageNamed:model.picture];
//注意啊,如果说,这个picture属性,是一个nil,
//如果是nil的话,直接写这句话,你把nil传进来,这句话是不是报错的,
//你读取一个空的一个图片的名称,这句话是不是会报异常,
//所以说,为了这个异常,你这儿也得判断一下啊,
//如果model.picture的值是nil,那么下面这句话执行会报异常
//所以这儿,我们得判断一下,
//同时,是不是还要把那个图片显示出来,
//显示图片框,
self.imgViewPicture.hidden = NO;
//self.imgViewPicture.hidden = NO,这个图片框,是不是显示出来了,
} else {
//else,如果要是没有配图,没有配图,注意听,
//既然就没有配图,你还需要设置什么东西吗,
//不需要,但是如果没有配图,这个图片框还能显示出来吗,
//是不是隐藏掉吧,
//隐藏图片框
self.imgViewPicture.hidden = YES;
}
有人说,你都没配图,你隐藏它干啥了,没配图,不隐藏它,也行吗,
如果说,你就是一个新创建的一个Cell,刚刚创建那个Cell,
你没有配图,图片框是不是没有东西,
是不是什么都显示不出来,
也没事儿,
还是,如果说,你要重用上一个单元格的Cell,
这个时候,上一个单元格,它是有配图的,
你重用了上一个单元格,如果你这里没有配图,你如果要不让它隐藏的话,上一个单元格里面,图片框里面,是不是原来有图片,你如果不隐藏,是不是直接给你显示出来了,
这就是当我们进行单元格重用的时候,一定要注意,把原来单元格的那些可能会影响你的数据,是不是都给它设置一下啊,
明白吧,重用别人的东西,一定要干干净净、干干净净,
好,所以说,这里,如果要是没有配图,那么就隐藏图片框,
//如果没有配图,隐藏图片框,
self.imgViewPicture.hidden = YES;
好,这样的话,把我们的数据设置好了,
现在,我们在这个settingData
现在,在我们这个settingData方法里面,
在这个settingData方法里面,把我们所有的这些控件,数据设置好了,
设置好数据以后,接下来,在settingFrame里面,我们是不是一个一个要设置它们的什么,设置一个frame,坐标吧,
四、来,我们设置一下这个坐标,
1.设置这个坐标,相对来说,就比较烦人了,
咱们现在一起来设置一下坐标
其实就是设置5个控件的frame吧,
第一个控件的frame,最好设置了,
1)头像
第一个控件,是不是一个头像,
注意,无论是第一行的头像、第二行的头像、第三行的头像、第四行的头像,
每一行这个头像,距离上边,距离左边,
这两个X、Y,是不是都是相等的,
这儿的X、Y,和下面是不是都是一样的啊,
假设,这个距离上边是10,距离左边也是10,
也就是说,每一行的头像,距离Y和X,假设都是10,
然后,每一行的头像的大小,宽度和高度,是不是也是一样的啊,
所以说,头像的坐标,非常好设置,
来看,怎么设置,
CGFloat iconW = 35;
CGFloat iconH = 35;
CGFloat iconX = 10;
注意,这个10,我们后边可能会很多次用到,
这个间距、这个间距、这两个之间的间距、是不是这一堆,间距,都是10啊,
所以说,我们这里的10,是一个间距,
所以说,我就先干什么,提取统一的一个间距吧,
//提取统一的间距
CGFloat margin = 10;
距离左边,就是一个margin,
CGFloat iconY = margin;
//距离上边,是不是也是个margin,
//然后呢,第一个头像的X、Y、宽、和高都有了,你说它frame有没有,
self.imgViewIcon.frame = CGRectMake(iconX,iconY,iconW,iconH);
//这样的话,这几个是不是都有了,
//那么,现在我们看,第一个控件,是不是坐标有了,
//然后呢,数据有了,
//控件是不是本身也有了,
//现在只有第一个头像控件,是不是一切都有了,
//咱们看看它能显示出来吗,
//有了吧
//头像是不是显示出来了,
//状态栏,爽吗,不爽,干掉,
//怎么干掉,找到控制器,
//在控制器中,prefersStatusBarHidden,
//再运行,
//看一下,状态栏,没有啦,这样的话,每一个头像,是不是显示出来了,
//接下来,我们是不是要显示第二个,是不是昵称啊,
2)昵称
一个一个算坐标,就OK了,
分析
我们说,这个昵称,怎么算,昵称距离左边,X等于什么啊,
等于这个头像的这个最大的X,再加一个10,
头像的最大的X,再加一个10,
来,算一下,
昵称,就是我们这个什么,就是CGFloat,nameX,
CGFloat nameX =
等于什么啊,等于我们这个头像的最大的X,
等于我们这个头像的最大的X,在加上10,
CGFloat nameX = CGRectGetMaxX(CGRect rect)
//等于一个谁,
CGFloat nameX = CGRectGetMaxX(self.imgViewIcon.frame);
//等于它的最大的X,吧,加上一个margin
CGFloat nameX = CGRectGetMaxX(self.imgViewIcon.frame) + margin ;
//那么,就等于我们头像的最大的X,加一个margin,是不是昵称的这个X,
//就等于我们头像的最大的X,加上一个margin,是不是昵称的这个X,
//昵称的Y,等于多少,
//昵称的Y,我们可以怎么算呢,昵称的Y,就是等于,注意看,
//昵称的Y,是不是等于,首先,上面,这个距离,是不是我们头像的Y,吧,
//头像的Y,加上头像的高度,减去昵称的高度,除以2,是不是就是这点儿,
//头像的Y +(头像的高度,减去昵称的高度)除以2 = 这点儿,
//能看明白吗,再给你画一下啊,它的这一点的Y值,
//它的这一点的Y值,是不是首先等于头像的上面这个Y值,
//这个Y值,加上这点儿的距离,
//这点儿的距离,怎么算呢,
//就是等于它整个的高度,减去它(昵称)自身的告诉,然后呢,剩下是不是这两段儿的和,
//除以2,是不是上面这点儿距离啊,
//就是头像的Y值,加上这点儿距离,是不是就是这个昵称的Y值,
//但是,你这里要算昵称的Y值,是不是首先得算出这个昵称的高度啊,
//昵称的高度,我们是不是现在,还没有定死啊,我们现在要根据这个Label里面,文字的多少,来计算出文字的高度,
//我们现在不管它的高度有没有吧,高度,我们现在没有定义它的高度吧,
//你想定义的话,你当然可以把它的高度定死,是不是也是可以的,
//但是,如果你希望让它大小、高度,随着字体的变化,变化的话,这个时候,是不是最好别定死啊,
//但是,定死,是不是也行,因为字体,如果变大,你这个Label是不是也变高了吧,如果你要没有给它固定大小的话,是不是,
//是不是肯定会随着字体的变化而变化吗,
//所以说,我们这里,首先可以根据文字来算出一个Label的一个高度,
//那么这个我就先告诉大家,这里就是要给大家交代一个知识点
//即便你这个Label高度可以知道,也就交代一个知识点,
//就是说,我们有一个Label,Label里面,有一些文字,
//在你不知道Label大小的前提下,只要Label里面有文字,可以根据Label里面的文字来算出这个Label有多大,
//明白,可以根据文字来算出Label有多大,
//那么,接下来,就告诉大家,首先,就是它的Y值,
//根据Label中文字的内容,来动态计算Label的高和宽
//那么,在继续之前,我们先思考这么一个东西,
//比如说,这是一个Label,
//这是一个Label,里面是一堆文字,
//里面是一堆文字,那么,影响这个Label大小的因素,有哪些,
1)第一,字体大小,是不是影响Label大小啊,
比如说,现在看到的Label,是不是这么点儿大,
然后呢,我一个字都不动,一个字都不增加,一个字都不减少,
就这点字,
但是,我只要改一下字体大小,
Label是不是就随着变大了吧,
所以说,第一,字体的大小,会影响Label,的大小,
2)第二,如果你要是固定死了Label的宽度,高度,是不是也会随着变化啊,
第二,如果你要是固定死了Label的宽度,高度是不是也会随着变化啊,
比如说,Label这么宽,高度是这么高,
Label这么宽,高度是这么高,
是不是越来越高了 ,
所以说,你是否限制这个Label的最大的宽和最大的高,是不是也是一个影响,
比如说,你限制了Label最宽是多少宽,当这个文字,达到这个宽度以后,是不是就该向下把这个撑的高一些了,
所以说,影响Label的大小的因素,
1)一是里面的字体的大小,
2)第二是“是否限制这个Label的高和宽“,
这两个因素,会影响Label,的大小,
那么,接下来,咱们就看一下,如何来根据Label里面的文字,来计算Label的大小呢,
这里已经把方法给大家摆好了,
看这里,
boundingRectWithSize,
bundingRectWithSize:CGSizeMake(MAXFLOAT,MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:font} content:nil]
[字符串对象 bundingRectWithSize:CGSizeMake(MAXFLOAT,MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:font} content:nil]
注意,这个方法是谁的方法,是字符串对象的方法,
因为Label里面,填充的,本身就是字符串啊,
Label里面,填充的本身,就是字符串,
你只要拿到Label里面填充的字符串内容,根据字符串内容,调字符串的boundingRectWithSize,
就可以计算出这么多的文字,应该显示多大,
1)第一个参数,CGSizeMake(MAXFLOAT,MAXFLOAT):表示是否限制它的高和宽,
假设,我不限制它的高和宽,
那么,你有多少文字,我就给你算,能算多大算多大,
那么,我就可以来个CGSizeMake(MAXFLOAT,MAXFLOAT),
这样的话,就不限制它的高和宽,
2)第二个参数,options:NSStringDrawingUsesLineFragmentOrigin:
是一种计算方式,是一种根据文字计算大小的方式,
我们暂时采用这种方式就好了,
NSStringDrawingUsesLineFragmentOrigin,
这种方式比较准一点儿,
这是一种计算文字大小的方式,
3)第三个参数,attributes:@{NSFontAttributeName:font}
第三个参数,就是,我们说影响大小的因素,我们说,还有字体啊,
字体可以影响它的大小,
所以说,第三个参数,就是指定一个字体,
4)第四个参数,context:nil,
第四个参数,我们给它先传一个nil,
这是我们这个方法,
好,所以说,我们就根据字符串的这个bounding方法,来算一下这个文字的大小,
最后,这个Label,是不是要来个Size,吧,我们说,最后这个Label,我们要它的大小,是一个Size吧,
CGSize nameSize =
现在我们要根据文字算大小,要获取昵称,怎么获取昵称,
self.lblNickName.text
这是不是昵称,这是昵称吧,
NSString *nickName = self.lblNickName.text;
//获取昵称字符串
是不是我要获取这个字符串的大小啊,
这个字符串,应该占多大,
这个字符串,有个什么方法,bounding,
boundingRectWithSize:
1)第一个参数CGSize:你是否限制它,最大多大,
最大的宽和高,
就是,计算的时候,如果超出这么大,是不是就给你限制成这么大了,
是否是指定一个最大的大小,
CGSizeMake(CGFloat width,CGFloat height)
这个最大的大小呢,我不指定,有多大,算多大,不指定,就是最大值,MAXFLOAT,后面这儿也是,MAXFLOAT,
当然,你可以指定,我这里就是给大家演示一下,不指定了,
2)options:(NSStringDrawingOptions)
这个选项呢,我们可以用哪个呢,可以用这个选项,
NSStringDrawingUsesLineFragmentOrigin
这个选项的意思,就是说,告诉它一种计算方式,我们就先用这个方式,
这个方式,相对来说,比较准,
3)第三个参数,attributes:(NSDictionary *)
第三个,我们这里是一个字典,
我们说,这个字典,要的是一个字体,里面可以设置字体的大小啦,字号啦,可以设置这些,
那么,根据这个字体,有了,是不是才能正确的计算出字符串的大小,
这个地方,我们一开始,不知道这儿应该填什么,
那么,我们就按住command键,进来看看,
它这个attributes,这个里面,是不是没有告诉我们应该填什么啊,
这个在哪儿去找,这个能填的值呢,在这里去找,
它这里有一个叫做NSFontAttributeName,
点开这个东西,
注意,这里有个头文件,叫什么啊,
NSAttributedString.h
哪个包下,
是不是UIKit,这个框架下,
在这个框架下,里面有这么几个常量值,
这个NSFontAttributeName,
它就表示字体的意思,
你还可以给它添很多,比如说,背景色,
可以设置很多,
这个NSFontAttributeName,表示设置字体的意思,
这里是一个字典,
既然是个字典,我们先给它来个字典,
NSDictionary *attr = @{};
字典
NSDictionary *attr = @{NSFontAttributeName};
那么,这就表示设置字体,
NSDictionary *attr = @{NSFontAttributeName};
设置一个多大的字体,我们这里给它来一个字体,
NSDictionary *attr = @{NSFontAttributeName : };
NSDictionary *attr = @{NSFontAttributeName:[UIFont systemFontOfSize:(CGFloat)]};
设置一个多大的字体呢,昵称吗,来一个12吧,
NSDictionary *attr = @{NSFontAttributeName : [UIFont systemFontOfSize:12]};
这样的话,就设置这个字体,是不是12啊,
12个点的一个字体,
然后,把这个字典传过来,
CGSize nameSize = [nickName boundingRectWithSize:CGSizeMake(MAXFLOAT,MAXFLOAT) options: NSStringDrawingUsesLineFragmentOrigin attributes:attr context:(NSStringDrawingContext *)];
然后,把这个字典传过来,
4)最后这个第四个参数,context:上下文,一般给它一个nil,就可以了,
CGSize nameSize = [nickName boundingRectWithSize:CGSizeMake(MAXFLOAT,MAXFLOAT) options: NSStringDrawingUsesLineFragmentOrigin attributes:attr context:nil];
就可以了,
然后呢,注意看这个boundingRect,方法,返回的类型,是一个什么类型,CGRect类型吧,
返回CGRect类型,
但是我们这里要的是什么类型,CGSize,类型吧,
所以说,直接用它“点”size
CGRect.size,
这样是不是就是拿到了当前,这么多文字,它实际的大小,
明白,这是拿到这么多文字它实际的大小,
5.然后,拿到这个大小以后,这里来个CGFloat,
CGFloat nameW = nameSize.width;
CGFloat nameH = nameSize.height;
这样就拿到了它的宽和高,
拿到了它的宽和高,它的这个高度拿到了,
那么它上面这个小距离,怎么算,
它的这个高度拿到了之后,它的这个Y值,就等于,
icon的一个Y值,加上icon的高度,减去Label自身的高度,除以2啊,
CGFloat nameY = iconY + (iconH - nameH)* 0.5 ;
这是不是就是它自身的一个Y值啊,
这样的话,它的X、Y、宽、和高、都有了,
然后,设置一下,
self.lblNickName.frame = CGRectMake(nameX,nameY,nameW,nameH);
好,这样算完以后,咱们看一下这个能不能运行,
看到了吗,首先,这个内容,是不是显示出来了,
但是,发现没有,你这里面的文字,是不是都是什么,是不是变的很大啊,
这里文字变得很大,是不是根本就不是你这里指定的12啊,
注意听,原因是,我们这里在计算的时候,告诉它按照12这个大小来计算啊,
但是,事实上,在你刚创建完这个Label的时候,刚创建完这个Label的时候,
刚创建完这个Label的时候,你指定这个Label的文字大小了吗,
根本就没有指定文字大小吧,
所以说,你计算的时候,按照12来计算,
但是,事实上,这个Label里面的文字,根本就不是12,
所以说,我们要把Label上的文字,也设置成12啊,
所以说,这儿,要注意啊,
这里要设置一下Label上的文字,
//设置Label的文字大小,
//怎么设置呢,就是我们的这个Label,
lblNickName.font = [UIFont systemFontOfSize:12];
也就是说,这个地方的12,是不是要和它下面,计算的时候所用的这个12,是不是得一样啊,
是不是都得是12才可以,
那么,有没有发现,这两个地方,用了同一个内容了吧,
这个地方,可以把这段代码,抽象成一个什么,
可以把它抽象成一个宏吧,
因为是,在这个程序中,看,这儿,是不是用了一次这个12,
计算的时候,要按照12,来计算,
但是,事实上,这个Label,是不是目前不是12,大小啊,
你得在这个Label创建好以后,得把这个Label,这个地方,也设置成12,
所以说,这儿和那儿,抽象成一个宏,
#define nameFont [UIFont systemFontOfSize:12]
#define nameFont [UIFont systemFontOfSize:12]
这个就是昵称的一个字体,
然后呢,拿到这个宏,
把这个宏放到哪儿呢,
对,是不是把我们这个地方,给它替换一下吧,
替换一下,
好,然后下面,计算的时候,
这儿,也用这个替换一下,
好,然后,再运行,
这个时候,就变成12了吧,
这个时候,变成12了,因为它实际大小,也是12,你计算的时候,也是根据12算的,所以说,你算出来的大小,刚好就是Label的大小,
刚好就是Label的实际大小,
这就是我们这儿这个东西,
来,这儿这个东西,怎么样,感觉,
来,我再把这个东西,给大家解释一下,
1)我现在是想根据这个Label,里面的文字,的大小,算一下这个文字应该用多大的Label,吧,
2)所以说,我得先拿到里面的这个文字,
3)然后呢,我知道这个里面,这个昵称Label,距离上边,这个距离,昵称Label距离左边,X,这个距离,X距离,是不是就等于,
X,距离,是不是等于icon的这个最大的X,加上一个margin,
所以说,它X,距离,就是icon的最大的X,加上一个margin,
CGFloat nameX = CGRectGetMaxX(self.imgViewIcon.frame) + margin;
4)然后,接下来,我们刚才说了半天,其实就是在干什么,
就是在去计算这个Label,里面文字的高和宽吧,
计算这个Label,里面文字的高和宽,怎么算呢,
我们需要拿到当前Label里面这个文字,
用这个文字,调它的boundingRectWithSize,方法,
在这个Size,方法中,第一个参数,就是它
1> 第一个参数,CGSizeMake(MAXFLOAT,MAXFLOAT):就是你是否限定它最大的大小,
我们这里不限定,不限定最大的大小,所以说,这里就CGSizeMake(MAXFLOAT,MAXFLOAT),
不限定最大的大小,
2> 第二个参数,options:这个options,就先记住,先记住,options,就是这么一个值,
NSStringDrawingUsesLineFragmentOrigin
你先记住它,用这个方式来算,用这个来算,
3> 第三个参数,attributes:
这个地方,需要指定它的字体,因为只有有了特定的字体,
是不是才能算它的大小,
你没有字体,是不是没法算这个大小,
没有字体,没法算大小,
所以说,这个地方,就是为了指定一个字体大小,
但是,这个字体大小呢,不能随随便便,指定一个数字,12、13,
必须是一个字典,
所以说,我们就先创建一个字典,
在这个字典中,这个就表示字体,
NSFontAttributeName
这个就给它一个,这个字体,nameFont,
这个字体呢,在哪儿呢,这是一个宏,
这个宏,就是在最上面定义的,这个宏,就对应的是系统的一个字体,是12,
是12大小,
系统的字体,是12大小,
然后,接下来,我在算大小的时候呢,就根据系统的字体,12这个大小,来算,
最后,这个大小,就是,按照12这种字体,不限定最大的大小,算一算这个大小,
那么,这个大小,就是根据这个字体,来算出来的,
5)然后,有了大小以后,我们就计算一下Y值,
然后呢,计算完毕以后,现在这个Label的X、Y、W、H,都有了,
直接把这个大小,设置给这个Label,的frame,是不是就OK了,
但是,你计算的时候,是使用,这个字体,算的,
事实上,你Label,显示的时候,也得用这个字体来显示,是不是才能匹配起来,
所以说,你在Label创建完毕以后,要设置一下Label的大小,
Label的字体,你也得用这个字体,
这样的话,这两个才能匹配起来,
否则,你算出来,可能这么点儿,但是它事实上,那么大,
或者,算出来那么大,但是事实上,没有那么大,
必须让它事实上,显示的大小,
和你这儿计算的时候,采用同样的大小,
这是我们计算Label的一个高和宽,
五、会员图标的frame
1.我们看会员
会员这里就是一个什么,会员这里就是一个imageView,
这个imageView,的Y值,是不是和这个Label的Y值,是一样的,
这个imageView的Y值,和它一样,
X值,就是昵称的最大的X,加一个margin,
然后呢,它大小,假设都是,咱们给它一个值吧,
假设,都是10,
2.好,那咱们算一下,
CGFloat vipW = 10;
CGFloat vipH = 10;
CGFloat vipX = CGRectGetMaxX(self.lblNickName.frame) + margin;
CGFloat vipY = nameY;
这样,四个值,是不是就有了,
然后呢,
self.imgViewVip.frame = CGRectMake(vipX,vipY,vipW,vipH);
再看一下,vip,有没有,
是不是vip,有了,
OK,这样的话,我们vip,是不是也有了,
六、正文
1.注意,这个正文,距离左边这个值,是不是等于我们icon,它距离左边的值,
2.正文,距离上面的值,等于icon,最大的Y值,加上一个margin,
3.然后,正文的大小,是不是也得动态的算一遍,
4.好,一起来给大家指定一下,
CGFloat textX = iconX;
CGFloat textY = CGRectGetMaxY(self.imgViewIcon.frame) + margin;
4.然后,接下来,是不是要计算它的一个大小,
注意,计算正文的大小的时候,和计算昵称的大小的时候,是不是一样的,
都是根据文字,是不是去计算这个大小,
所以说,这个代码,我有必要写两遍吗,
没有必要写两遍吧,
是不是可以封装一个方法,根据字符串,以及你传过来的字体,是不是计算它的大小,
是不是可以封装这么一个方法啊,
所以说,我们就把这个方法,先给它封装一下,
封装完毕以后,我们再来计算,
5.封装一下,
注意,这个计算文字大小,首先,你得给我传一个字符串过来,
1> 要计算那个字符串的大小,
2> 然后,给我传一个Size,过来,
是否限制,最大的高,最大的宽,
3> 然后,给我传一个字体,过来,
是不是传这三个参数,就OK了,
所以说,我们要写一个方法,有三个参数,
来,写一下,
我们这个返回值,是一个什么类型,CGSize,吧,
我们这个方法名儿,可以给它起一个,就是,sizeWithText
然后,第一个就是一个字符串吧,要计算这个字符串的,withText,
- (CGSize)sizeWithText:(NSString *) and
- (CGSize)sizeWithText:(NSString *) andMaxSize
是否指定最大值,
- (CGSize)sizeWithText:(NSString *) andMaxSize:(CGSize)maxSize and
- (CGSize)sizeWithText:(NSString *) andMaxSize:(CGSize)maxSize andFont:
指定特定的一个字体,
- (CGSize)sizeWithText:(NSString *) andMaxSize:(CGSize)maxSize andFont:(UIFont *)font
- (CGSize)sizeWithText:(NSString *) andMaxSize:(CGSize)maxSize andFont:(UIFont *)font {
//statement;
}
好,第一个没参数名,来个text,
这样的话,这个方法,就可以根据,你给我传过来的字符串,传过来的是否限制最大值,传过来的字体,
来算这个Label的大小,
当然,这个算法,和刚才是一模一样的,
直接拷贝,就可以了,
- (CGSize)sizeWithText:(NSString *)text andMaxSize:(CGSize)maxSize andFont:(UIFont *)font{
return [nickName boundingRectWithSize:CGSizeMake(MAXFLOAT,MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:attr context: nil] . size ;
}
当然,这个地方,用它的什么,
1)text,计算这个文字的什么,计算它的大小吧,
2)这儿,要换成什么,
maxSize吧,你给我规定是多大,最大多大,我就用最大多大,
3)options:NSStringDrawingUsesLineFragmentOrigin
options,就是这个,
4)attributes:
attributes,是不是把你这儿传过来的这个,font,就OK了,
然后,这个地方,要根据你传过来的这个font,要构建一个集合啊,
NSDictionary *attr =
因为,人家这儿是不是要的,必须是一个字典集合,
NSDictionary *attr = @{};
NSDictionary *attr = @{NSFontAttributeName:font};
必须根据你这个font,字体,来构建一个集合,然后这个地方,传这个集合,
OK,这样的话,就可以根据一个字符串,
//根据给定的字符串、最大值的size、给定的字体,来计算文字应该占用的大小
既然这里已经有这个方法了,
sizeWithText:
那么,接下来,我们刚才这段代码,是不是也可以稍微改造一下,
这儿就可以怎么写,
来个什么,self sizeWithText:(NSString *) andMaxSize:(CGSize) andFont:(UIFont *)font
sizeWithText:把这个nickName传进来,nickName,
andMaxSize:大小呢,CGSizeMake(MAXFLOAT,MAXFLOAT)
不指定大小,
andFont:font呢,nameFont,
OK,然后,这个就不需要了,
这样的话,我们把这个计算文字大小的代码,封装到一个方法了,
好,接下来,我们这里,又用到计算这个方法了,
6.正文这里,计算文字大小,
CGSize textSize = [self sizeWithText:self.lblText.text andMaxSize:CGSizeMake(MAXFLOAT,MAXFLOAT) andFont:nameFont];
1)把我们当前的正文的文字,传进来,
2)最大大小呢,不指定,CGSizeMake(MAXFLOAT,MAXFLOAT)
3)font:注意,正文的大小,是不是我们也得给正文一个大小啊
OK,假设,我们正文大小,比这个昵称,稍微大点儿啊,
正文,假设要用14号,
注意,你计算的时候,使用的14号,
事实上,这个Label,你设置的时候,是不是也得让它是14号,
是不是又是两个地方用,
所以说,又可以把这个字体,封装成一个宏,
#define textFont [UIFont systemFontOfSize:14]
正文,14号字,
textFont,然后,把这个textFont放哪儿呢,
首先,正文,你要给它设置一下它的大小,
是不是正文,等于这么大,
然后呢,接下来,你计算正文的坐标的时候,这个地方,也得给它一个什么啊,
这个地方,也得给它一个什么啊,
textFont,
好,这样的话,正文大小是不是就有了,
正文的大小有了,X、Y,有了,
是不是直接设置一下,就OK了,
CGFloat textW = textSize.width;
CGFloat textH = textSize.height;
self.lblText.frame = CGRectMake(textX,textY,textW,textH);
OK,设置好这个正文以后,我们再运行一下看看,
正文有了吗,有了吧,但是这个行高,是不是太低了,
7.我们先统一设置一下行高,
找到我们的控制器,在viewDidLoad,方法,里面,
//统一设置tableView的行高
self.tableView.rowHeight = 300;
来,看一下行高,这样的话,每一行的行高,是不是有了,
行挺高,但是注意,当正文的内容比较多的时候,它换行了吗,
没有换行,怎么让Label换行,还记得吗,
是不是要给它,它有个numberOfLines,设置成0,就可以了,
让Label,换行,注意,让Label换行,只要设置一次,就OK了吧,
是不是没有必要反复设置,
所以说,我们找到一个自定义Cell,
自定义Cell里面,在创建好这个控件的时候,
//设置正文的Label可以自动换行
lblText.numberOfLines
lblText.numberOfLines = 0;
给它设置成0,行,表示它可以自动换行,
再运行,
换行了吗,没有吧,
因为我们这时候,没有限制Label的宽度吧,
没有限制Label的宽度,它是不是一直给我挤过去了,
当然这个昵称,可以不限制这个宽度,
这个正文,是不是得给它限制一下宽度啊,
这个正文,我们要给它限制一下宽度,当你限制了它的宽度以后,它是不是才不会折行啊,
我们限制它多宽呢,
左边是10,
左边是10,右边是10,中间它的宽度,是不是应该是300,
OK,限制正文的宽度,是300,
找到,限制正文宽度是300,
限制正文宽度是300,
第一个,宽是不是300,
第一个,宽是不是给它限制一个300啊,
限制宽度300,高是随便吧,
再运行,
这样,是不是正常换行了吧,
好,这样的话,我们这几个坐标,已经算好了,
接下来,该算谁了,
接下来,是不是该算这个配图了,
七、配图
1.计算配图的这个,frame,