【微博-计算Cell子控件的frame Objective-C语言】

在iOS开发中,设置UITableViewCell时,通常需要计算并设置子视图的frame。文章详细讲解了如何根据模型数据动态设置头像、昵称、会员图标、正文和配图的frame,包括计算文字的大小、处理配图的显示和隐藏,以及处理单元格重用时的数据更新。此外,还介绍了如何根据文字内容动态计算UILabel的高度,并封装了一个计算文字大小的方法。
摘要由CSDN通过智能技术生成

一、计算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,

接下来,在设置数据这个地方,

会员

你只要根据它是不是vip,判断是否应该显示这个图标,就OK了,

明白,这里不需要就是动态每次都设置它的图片,

不需要,设置一次就够了,

如果,

如果

如果,model.isVip

vip

如果它是会员,我就让

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;

NO

//self.imgViewPicture.hidden = NO,这个图片框,是不是显示出来了,

} else {

//else,如果要是没有配图,没有配图,注意听,

//既然就没有配图,你还需要设置什么东西吗,

//不需要,但是如果没有配图,这个图片框还能显示出来吗,

//是不是隐藏掉吧,

//隐藏图片框

self.imgViewPicture.hidden = YES;

}

配图

有人说,你都没配图,你隐藏它干啥了,没配图,不隐藏它,也行吗,

如果说,你就是一个新创建的一个Cell,刚刚创建那个Cell,

你没有配图,图片框是不是没有东西,

是不是什么都显示不出来,

也没事儿,

还是,如果说,你要重用上一个单元格的Cell,

这个时候,上一个单元格,它是有配图的,

你重用了上一个单元格,如果你这里没有配图,你如果要不让它隐藏的话,上一个单元格里面,图片框里面,是不是原来有图片,你如果不隐藏,是不是直接给你显示出来了,

这就是当我们进行单元格重用的时候,一定要注意,把原来单元格的那些可能会影响你的数据,是不是都给它设置一下啊,

明白吧,重用别人的东西,一定要干干净净、干干净净,

好,所以说,这里,如果要是没有配图,那么就隐藏图片框,

//如果没有配图,隐藏图片框,

self.imgViewPicture.hidden = YES;

好,这样的话,把我们的数据设置好了,

现在,我们在这个settingData

settingData

现在,在我们这个settingData方法里面,

在这个settingData方法里面,把我们所有的这些控件,数据设置好了,

数据设置好了

设置好数据以后,接下来,在settingFrame里面,我们是不是一个一个要设置它们的什么,设置一个frame,坐标吧,

settingFrame

四、来,我们设置一下这个坐标,

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,

margin

//然后呢,第一个头像的X、Y、宽、和高都有了,你说它frame有没有,

self.imgViewIcon.frame = CGRectMake(iconX,iconY,iconW,iconH);

这样

//这样的话,这几个是不是都有了,

//那么,现在我们看,第一个控件,是不是坐标有了,

//然后呢,数据有了,

数据

//控件是不是本身也有了,

//现在只有第一个头像控件,是不是一切都有了,

//咱们看看它能显示出来吗,

头像

//有了吧

//头像是不是显示出来了,

//状态栏,爽吗,不爽,干掉,

//怎么干掉,找到控制器,

找到控制器

//在控制器中,prefersStatusBarHidden,

隐藏状态栏

//再运行,

状态栏

//看一下,状态栏,没有啦,这样的话,每一个头像,是不是显示出来了,

//接下来,我们是不是要显示第二个,是不是昵称啊,

2)昵称

一个一个算坐标,就OK了,

昵称

分析

分析

我们说,这个昵称,怎么算,昵称距离左边,X等于什么啊,

等于这个头像的这个最大的X,再加一个10,

margin

头像的最大的X,再加一个10,

来,算一下,

昵称,就是我们这个什么,就是CGFloat,nameX,

CGFloat nameX =

等于什么啊,等于我们这个头像的最大的X,

大X

等于我们这个头像的最大的X,在加上10,

CGFloat nameX = CGRectGetMaxX(CGRect rect)

最大的X
在这里插入图片描述

//等于一个谁,

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,吧,

头像的Y

//头像的Y,加上头像的高度,减去昵称的高度,除以2,是不是就是这点儿,

这点

//头像的Y +(头像的高度,减去昵称的高度)除以2 = 这点儿,

//能看明白吗,再给你画一下啊,它的这一点的Y值,

Y

//它的这一点的Y值,是不是首先等于头像的上面这个Y值,

Y值

//这个Y值,加上这点儿的距离,

这点儿

//这点儿的距离,怎么算呢,

//就是等于它整个的高度,减去它(昵称)自身的告诉,然后呢,剩下是不是这两段儿的和,

高度

//除以2,是不是上面这点儿距离啊,

//就是头像的Y值,加上这点儿距离,是不是就是这个昵称的Y值,

//但是,你这里要算昵称的Y值,是不是首先得算出这个昵称的高度啊,

//昵称的高度,我们是不是现在,还没有定死啊,我们现在要根据这个Label里面,文字的多少,来计算出文字的高度,

//我们现在不管它的高度有没有吧,高度,我们现在没有定义它的高度吧,

//你想定义的话,你当然可以把它的高度定死,是不是也是可以的,

//但是,如果你希望让它大小、高度,随着字体的变化,变化的话,这个时候,是不是最好别定死啊,

//但是,定死,是不是也行,因为字体,如果变大,你这个Label是不是也变高了吧,如果你要没有给它固定大小的话,是不是,

//是不是肯定会随着字体的变化而变化吗,

//所以说,我们这里,首先可以根据文字来算出一个Label的一个高度,

//那么这个我就先告诉大家,这里就是要给大家交代一个知识点

//即便你这个Label高度可以知道,也就交代一个知识点,

//就是说,我们有一个Label,Label里面,有一些文字,

//在你不知道Label大小的前提下,只要Label里面有文字,可以根据Label里面的文字来算出这个Label有多大,

Label

//明白,可以根据文字来算出Label有多大,

//那么,接下来,就告诉大家,首先,就是它的Y值,

Y值

//根据Label中文字的内容,来动态计算Label的高和宽

动态

//那么,在继续之前,我们先思考这么一个东西,

//比如说,这是一个Label,

这是一个Label

//这是一个Label,里面是一堆文字,

文字

//里面是一堆文字,那么,影响这个Label大小的因素,有哪些,

大小

1)第一,字体大小,是不是影响Label大小啊,

比如说,现在看到的Label,是不是这么点儿大,

大小

然后呢,我一个字都不动,一个字都不增加,一个字都不减少,

就这点字,

但是,我只要改一下字体大小,

字体
字体
Label

Label是不是就随着变大了吧,

所以说,第一,字体的大小,会影响Label,的大小,

2)第二,如果你要是固定死了Label的宽度,高度,是不是也会随着变化啊,

高度

第二,如果你要是固定死了Label的宽度,高度是不是也会随着变化啊,

比如说,Label这么宽,高度是这么高,

Label这么宽,高度是这么高,

高度

是不是越来越高了 ,

所以说,你是否限制这个Label的最大的宽和最大的高,是不是也是一个影响,

比如说,你限制了Label最宽是多少宽,当这个文字,达到这个宽度以后,是不是就该向下把这个撑的高一些了,

所以说,影响Label的大小的因素,

1)一是里面的字体的大小,

2)第二是“是否限制这个Label的高和宽“,

这两个因素,会影响Label,的大小,

那么,接下来,咱们就看一下,如何来根据Label里面的文字,来计算Label的大小呢,

这里已经把方法给大家摆好了,

Label
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方法,来算一下这个文字的大小,

size

最后,这个Label,是不是要来个Size,吧,我们说,最后这个Label,我们要它的大小,是一个Size吧,

CGSize nameSize =

现在我们要根据文字算大小,要获取昵称,怎么获取昵称,

self.lblNickName.text

根据文字算大小

这是不是昵称,这是昵称吧,

昵称

NSString *nickName = self.lblNickName.text;

//获取昵称字符串

是不是我要获取这个字符串的大小啊,

字符串

这个字符串,应该占多大,

这个字符串,有个什么方法,bounding,

bounding

boundingRectWithSize:

1)第一个参数CGSize:你是否限制它,最大多大,

最大的宽和高,

就是,计算的时候,如果超出这么大,是不是就给你限制成这么大了,

是否是指定一个最大的大小,

Label

CGSizeMake(CGFloat width,CGFloat height)

这个最大的大小呢,我不指定,有多大,算多大,不指定,就是最大值,MAXFLOAT,后面这儿也是,MAXFLOAT,

MAXFLOAT

当然,你可以指定,我这里就是给大家演示一下,不指定了,

2)options:(NSStringDrawingOptions)

这个选项呢,我们可以用哪个呢,可以用这个选项,

选项

NSStringDrawingUsesLineFragmentOrigin

这个选项的意思,就是说,告诉它一种计算方式,我们就先用这个方式,

这个方式,相对来说,比较准,

准

3)第三个参数,attributes:(NSDictionary *)

第三个,我们这里是一个字典,

我们说,这个字典,要的是一个字体,里面可以设置字体的大小啦,字号啦,可以设置这些,

那么,根据这个字体,有了,是不是才能正确的计算出字符串的大小,

这个地方,我们一开始,不知道这儿应该填什么,

那么,我们就按住command键,进来看看,

进来
进来

它这个attributes,这个里面,是不是没有告诉我们应该填什么啊,

attributes

这个在哪儿去找,这个能填的值呢,在这里去找,

它这里有一个叫做NSFontAttributeName,

NSFontAttributeName

点开这个东西,

头文件

注意,这里有个头文件,叫什么啊,

头文件

NSAttributedString.h

头文件

哪个包下,

包

是不是UIKit,这个框架下,

在这个框架下,里面有这么几个常量值,

常量

这个NSFontAttributeName,

它就表示字体的意思,

你还可以给它添很多,比如说,背景色,

可以设置很多,

这个NSFontAttributeName,表示设置字体的意思,

这里是一个字典,

这里

既然是个字典,我们先给它来个字典,

字典

NSDictionary *attr = @{};

字典

字典

NSDictionary *attr = @{NSFontAttributeName};

font

那么,这就表示设置字体,

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];

就可以了,

nil

然后呢,注意看这个boundingRect,方法,返回的类型,是一个什么类型,CGRect类型吧,

返回CGRect类型

返回CGRect类型,

但是我们这里要的是什么类型,CGSize,类型吧,

所以说,直接用它“点”size

size

CGRect.size,

这样是不是就是拿到了当前,这么多文字,它实际的大小,

明白,这是拿到这么多文字它实际的大小,

5.然后,拿到这个大小以后,这里来个CGFloat,

CGFloat nameW = nameSize.width;

nameSize

CGFloat nameH = nameSize.height;

这样就拿到了它的宽和高,

宽和高
宽和高

拿到了它的宽和高,它的这个高度拿到了,

那么它上面这个小距离,怎么算,

它的这个高度拿到了之后,它的这个Y值,就等于,

icon的一个Y值,加上icon的高度,减去Label自身的高度,除以2啊,

除以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距离

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值,是一样的,

Y值

这个imageView的Y值,和它一样,

X值,就是昵称的最大的X,加一个margin,

然后呢,它大小,假设都是,咱们给它一个值吧,

假设,都是10,

都是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

and

- (CGSize)sizeWithText:(NSString *) andMaxSize

是否指定最大值,

- (CGSize)sizeWithText:(NSString *) andMaxSize:(CGSize)maxSize and

and

- (CGSize)sizeWithText:(NSString *) andMaxSize:(CGSize)maxSize andFont:

指定特定的一个字体,

and

- (CGSize)sizeWithText:(NSString *) andMaxSize:(CGSize)maxSize andFont:(UIFont *)font

and

- (CGSize)sizeWithText:(NSString *) andMaxSize:(CGSize)maxSize andFont:(UIFont *)font {

//statement;

}

and

好,第一个没参数名,来个text,

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

maxSize吧,你给我规定是多大,最大多大,我就用最大多大,

规定

3)options:NSStringDrawingUsesLineFragmentOrigin

options,就是这个,

4)attributes:

font

attributes,是不是把你这儿传过来的这个,font,就OK了,

然后,这个地方,要根据你传过来的这个font,要构建一个集合啊,

集合

NSDictionary *attr =

因为,人家这儿是不是要的,必须是一个字典集合,

字典

NSDictionary *attr = @{};

字典

NSDictionary *attr = @{NSFontAttributeName:font};

font

必须根据你这个font,字体,来构建一个集合,然后这个地方,传这个集合,

OK,这样的话,就可以根据一个字符串,

//根据给定的字符串、最大值的size、给定的字体,来计算文字应该占用的大小

既然这里已经有这个方法了,

sizeWithText:

占用

那么,接下来,我们刚才这段代码,是不是也可以稍微改造一下,

这儿就可以怎么写,

怎么写

来个什么,self sizeWithText:(NSString *) andMaxSize:(CGSize) andFont:(UIFont *)font

size

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

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

numberOfLines

lblText.numberOfLines = 0;

给它设置成0,行,表示它可以自动换行,

再运行,

看一下

换行了吗,没有吧,

因为我们这时候,没有限制Label的宽度吧,

没有限制Label的宽度,它是不是一直给我挤过去了,

当然这个昵称,可以不限制这个宽度,

这个正文,是不是得给它限制一下宽度啊,

这个正文,我们要给它限制一下宽度,当你限制了它的宽度以后,它是不是才不会折行啊,

我们限制它多宽呢,

左边是10,

左边

左边是10,右边是10,中间它的宽度,是不是应该是300,

OK,限制正文的宽度,是300,

找到,限制正文宽度是300,

限制正文宽度是300

限制正文宽度是300,

第一个,宽是不是300,

宽

第一个,宽是不是给它限制一个300啊,

限制宽300

限制宽度300,高是随便吧,

再运行,

正文

这样,是不是正常换行了吧,

好,这样的话,我们这几个坐标,已经算好了,

接下来,该算谁了,

接下来,是不是该算这个配图了,

七、配图

1.计算配图的这个,frame,

配图
配图

2.来来来,计算配图,的frame,

注意看,这个配图,怎么算,

这是不是比较乱了,重新截一个,

算坐标

这个怎么算呢,其实这个很好算,

1)这个配图的X,是不是等于icon的一个X,

X

2)这个配图的Y,是不是等于这个正文的最大的Y值,再加上一个margin,就OK了,

正文

3)这个配图的高,假设是100,

4)这个配图的宽,假设是100,

是不是这个很简单,

来,我们看一下,计算一个它,

计算

来,回到我们这里,

配图

CGFloat picW = 100;

CGFloat picH = 100;

配图

CGFloat picX = iconX;

CGFloat picY = CGRectGetMaxY(self.lblText.frame) + margin;

配图的Y,等于什么,看看,等于我们这个正文的最大的Y值,加margin吧,

配图

然后呢,接下来,self“点”

self.imgViewPicture.frame = CGRectMake(picX,picY,picW,picH);

配图

来,运行一下,看看,

配图

第一个,没有配图,不显示,

第二个,有配图,显示,

第三个,没有配图,不显示,

第四个,有配图,显示,

配图

第五个,有配图,显示,

配图

好,这样的话,我们是不是有配图,就显示,没有配图,就不显示啊,

这样,这个配图,可以显示出来了,

接下来,就剩一个问题了,什么问题,

就剩一个这个,单元格的高度了吧,

但是,这个单元格的高度,还是一个比较麻烦的事儿,

好,这就是我们这个计算Cell子控件的frame,这么一个东西,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清风清晨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值