【QQ好友列表-设置HeaderView Objective-C语言】

一、咱们一起来看

通知

刚才咱们是不是给大家说到

创建好模型了

是不是单元格,我们需要自定义单元格了

自定义单元格的步骤:

我相信大家现在脑子里,应该有那个代码的思路了吧

1)首先,是不是要新建一个类型啊

这个类型应该建在哪个里面

通知

是不是应该建在我们的View里面

通知

View里面

通知

选择上面

通知

这个我们View应该叫、是不是用来描述我们的Cell的、是用来描述什么的、是用来描述一个朋友的一个单元格吧

通知

所以、它第一、继承自UITableViewCell

第二、起名字的时候、可以给它起它Friend

通知

CZFriendCell

好,点“Next”

通知

点“Create”

通知

好,然后在这个里面

通知

1)首先,第一步,我们注意看

我们既然这里有了一个自定义Cell,也就意味着

通知

我们在控制器里面,我们这个地方,将来是不是要用自定义Cell来替代啊

既然要用自定义Cell、来替代

那么我们是不是可以把这段代码

通知

封装到一个类方法里面

2)同时,我们是要给它再增加一个属性

通知

我们先给它增加一个这么一个属性

先给它增加一个friendModel、这么一个属性

OK,给它增加这么一个属性

通知

叫做

通知

这个应该是个什么类型

@Class

通知

CZFriend

通知

CZFriend类型、应该叫

通知

应该叫做

通知

这个名称叫做:friendModel

通知

叫friendModel

这么一个属性

好,然后,有了这个属性以后

需要给它再封装一个类方法

类方法用来就是

通知

封装这段代码

通知

OK,封装这段代码

所以说,我们应该再给它加一个

通知

类方法

通知

叫做friendCellWith什么

tableView

为什么WithTableView

通知

为什么WithTableView:

通知

因为,我们在这里,是不是要根据tableView

通知

根据tableView,来从缓存池里面取可用的单元格吧

通知

要把这个参数传进来,所以说,我们这里要给它封装一个withTableView

好,那么检查一下这个

通知

friendCell……

通知

FriendCell……

这两个地方都是FriendCell

WithTableView

通知

没有问题,

好,把这两个,给它实现一下

通知

第一个,

通知

1)第一个,我们直接给它来一个,加号:+ friendCellWithTableView

+ (instancetype)friendCellWithTableView:(UITableView *)tableView

通知

然后把刚才那段代码拷进来

通知

这个地方,都要变成什么

通知

是不是变成

通知

是不是变成CZFriendCell,啊

是不是变成我们自己的这个Cell,啊

通知

这儿也变成我们自己的Cell

通知

这儿也变成我们自己的Cell

通知

OK,这个地方,都变成自己的Cell

因为,系统单元格就够用了,所以说,我们不需要重写

通知

initWithStyle方法

它默认,系统单元格里面,就够用了

然后,在这个地方,直接return cell;

通知

好,然后就是我们这里,有了这个方法以后,

接下来,在控制器里面

通知

在控制器这个地方,是不是要变成

通知

通过我们调那个类方法,来创建单元格啊

通知

CZFriendCell……

没有,因为还没有引入头文件吧

通知

对,没有导入头文件

#import “CZFriendCell.h”

通知

然后,在下边,这个地方,我们来

通知

CZFriendCell *cell = [CZFriendCell

通知
通知

这样创建好以后,接下来,我们是不是,它“点”friendModel,啊

通知

就能把我们的这个friend,赋值给这个属性

但是,在这个set方法当中,

通知

在这个set方法当中,我是不是没有重写它的set方法啊

表示我们在赋值里面,是不是没有把这个模型数据,设置给单元格啊

所以说,我们要

2)重写friendModel属性的set方法

在这个自定义单元格当中,找到set方法

通知

- setFriendModel:

- (void)setFriendModel:(CZFriend *)friendModel{

_friendModel = friendModel;

}

在这个里面,第一步要做的就是

通知

就是什么

就是赋值,注意,重写set方法,永远第一步,就是赋值

通知

//接下来要做的就是,

//把模型中的数据设置给单元格的子控件

通知

//设置的时候,注意看,因为我们这里系统单元格就够用了

//所以说,我们直接设置imageView、textLabel、detailLabel

//就OK了

//好,一个一个设置、当前这个单元格的

通知

//self. 当前这个单元格的

通知

self.imageView.

通知

self.imageView.image =

通知

self.imageView.image 等于什么 = UIImage imageNamed:

通知

imageNamed:这个地方,是不是要从

通知

模型里面取

通知

要从这个模型里面取

通知

看一下,friend导进来了吗

通知

friend导进来了没有

没有

导入头文件

#import “CZFriend.h”

通知

#import “CZFriend.h”

通知

然后,这里就

通知

friendModel“点”

通知

friendModel.icon

这是它的头像吧,这是它的头像

通知

把它剪切到下面来

self.imageView.image = [UIImage imageNamed:friendModel.icon];

通知

好,然后再让这个self. 第二个是什么

2)self.textLabel

通知
通知

self.textLabel.text = 等于什么

通知

self.textLabel.text = 等于模型里面的name属性吧

通知

self.textLabel.text = friendModel.name;

通知

是不是当前好友的昵称

3)self.detailTextLabel

通知

self.detailTextLabel.text = 等于friend模型里面

通知

等于friend模型里面的什么,intro吧

通知

self.detailTextLabel.text = friendModel.intro;

intro:个性签名吧

OK,设置完这几个以后

接下来,当控制器执行到这句话的时候

通知

是不是会把模型中的数据,设置给单元格的子控件吧

然后,这个时候,运行,看一下

能不能看到效果

通知

好,看一下

数据是不是进来了

数据是不是基本就没有问题,已经进来了吧

接下来

我们要做的第一件事儿,先把状态栏隐藏掉

第二,我们要的效果,不仅仅是数据要进来

要的还应该是什么,

是不是还得有那个分组的效果啊

通知

是不是不仅仅要有那个数据,还要有这个分组的效果啊

所以说,接下来,我们要做的就是,现在我们

这个数据已经有了

现在基本上,单元格数据,已经能显示出来了

通知

接下来,是不是要显示分组啊

OK,那么我们先把状态栏隐藏掉

首先打开我们的控制器

通知

隐藏状态栏

注意,现在隐藏状态栏,是不是始终是在控制器里面控制的啊

隐藏状态栏,以后我们还会学习其他办法来控制状态栏

通知

把注释复制过来

改成“隐藏状态栏”

通知

怎么写,- (BOOL)prefersStatusBarHidden

通知

2.好,隐藏掉状态栏以后,接下来,我们就要让它显示分组

通知

我们第一步要做的是什么,大家先尝试一下

我们看一下,每一个组,是不是都

通知

都有一个name、和online,啊

这两个东西吧

我们先尝试,把每一组的组名儿,显示到每一组的的那个HeaderView里面

通知

可以吧,显示到每一组的组头里面

那么,怎么设置每一组的组头的那个内容呢

通知

//设置每一组的组标题

通知

是不是组标题的返回值类型是个String类型

通知

- (NSString *)

通知

String类型,那么tableView

- (NSString *)tableView

哪个

titleForHeaderInSection,吧

通知

titleForHeaderInSection

通知

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{

}

这个是不是就是返回每个组的组标题啊

1)首先,在里面,拿到当前

通知

首先在里面,拿到当前这个组的组对象

通知

根据它这个section、根据组的索引

拿到当前组的组对象

通知

拿到当前组的组对象

然后,return 当前组的什么

通知
通知

return group.name;

这是不是就是返回每个组的名称了

然后,这个时候,我们再运行,看看

通知

看到了吗

每一组是不是有组标题了

这样是不是看起来,和我们那个示例程序,是不是差不多了,已经

通知

是不是已经差不多了

通知

和它展开的样子,是不是差不多了

但是,有点儿不一样,是什么

示例程序,人家这个组标题上是仅仅有一个文字吗

这是不是还能点击啊,这是按钮吧,

能点击的是按钮

证明里面还有按钮,还有Label

也就是说,我们这个方法

通知

是可以设置组标题,但是它是不是只能设置组标题的字符串内容啊

我们要的是设置组标题的什么,是不是要设置组标题里面,不仅仅有字符串,里面还有一些子控件吧

所以说,这个时候,这个方法,显然就不够了

这个方法,只能设置组标题里面显示对应的字符串

但是,我们要的是组标题里面,要显示其他子控件

所以说,这个时候不够用了吧

所以说,这个时候,就不够用了

通知

//设置每一组的组标题(下面的这个方法只能设置每一组的组标题字符串,但是我们要的是每一组中还包含其他子控件)

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{

CZGroup *group = self.groups[section];

return group.name;

}

所以说,不是字符串就能搞定的吧

所以说,这个时候,这个方法就,废了

通知

这个方法就不能用了

那么大家想想,既然你每一组里面,包含的是其他子控件

子控件是不是都是一个继承自UIView的

所以说,这里可以直接告诉大家,

你要想让每一组中,不仅是字符串、还要包含其他子控件的时候

这个时候,用的这个方法,返回值就是一个什么类型

- (UIView *)

通知

返回值就是一个UIView

UIView类型

通知

- (UIView *)tableView:

通知

然后,这个方法名儿,注意看,叫什么,

有两个,

1)一个叫:viewForHeaderInSection

2)一个叫:viewForFooterInSection

大家说,用哪个

是不是用下面这个

viewForHeaderInSection

通知

当你希望每一组的组标题,只显示字符串的时候

用上面这个方法:tableView:titleForHeaderInSection

通知

当你希望每一组的组标题里面,显示不仅仅是文字,还有其他控件的时候,用哪个

tableView:viewForHeaderInSection

4.OK,那么在这个方法中

1)在里面创建一个UIView

2)设置UIView的大小、和它单元格、那个HeaderView大小一样

3)然后在里面再创建一个按钮、加到这个UIView里面、再创建一个Label、加到这个UIView里面

4)最后把这个UIView,直接返回

是不是就搞定了

是不是基本就这个思路啊

告诉大家,大家想这个思路非常非常好,但是呢,不能这么做

为什么不能这么做呢

因为我们在这个方法当中

通知

将来是不是会有很多、可能会有很多组吧

可能会有很多组

意味着会有很多个HeaderView啊

有很多个HeaderView

这个HeaderView如果很多的话,就类似于我们单元格一样

我们希望它是不是可以“重用”啊

希望每一组里面这个HeaderView、你返回这个View

通知

要可以进行重用

如果说,是你自己创建的一个UIView,这个时候,你是不是还得自己写代码,来让这个UIView重用,放到缓存池里面,用的时候再从缓存池里面去拿

你是不是得自己写一堆代码,来维护这个缓存池

是不是还得自己去写代码,维护这个UIView ,让它重用啊

你直接返回的一个UIView,它是默认不能重用的

它是不具备这个重用功能的

就相当于我们上面这个Cell

通知

你这个UITableViewCell里面有一个方法,叫做

通知

tableView dequeueReusableCellWithIdentifier:ID

这个,是不是系统帮你实现的

你只要从ID里面拿、根据ID拿、是不是能拿到那个重用的Cell啊

那么,对于我们这个分组

对于这个方法也是

通知

因为里面将来可能会有很多组

每一组都是一个UIView

我们是不是希望这个里面这个重用的UIView、里面这个UIView能实现重用吧

如果说,你在里面手动自己创建这个全新的UIView,它是无法实现重用的

我们为了让这个组标题,返回这个UIView,能进行重用

所以说,我们在这里返回的,其实不是一个简单的UIView

而是返回的是一个什么,UITableViewHeaderFooterView

通知

我们要返回这么一个控件

通知

只有这个控件,它其实、我们点开看一下

通知

这个类型,继承自什么:UIView,吧

它是不是就是一个UIView啊

也就是说,这个东西,它本身,就是一个UIView

但是,它用这个UITableViewHeaderFooterView

用这个类,把UIView封装了一下

里面这个就具有了重用功能了

这个里面就具有重用功能了

明白我的意思吧

所以说,我们本来想的在这个数据源方法当中

直接返回一个自己写的UIView,就可以了

通知

但是,如果你直接这么写,它是无法重用的

为了要重用里面这个UIView

所以,这个时候里面不要直接用UIView

而是用一个UITableViewHeaderFooterView

用这个,就可以实现重用

因为它,也类似于一个UIView

所以说,将来我们首先要创建这么一个UITableViewHeaderFooterView

然后在里面,增加一些子控件

然后,这个子控件,是不是一个按钮、一个Label

就在这个里面,增加一个按钮、一个Label

然后,接下来,我们返回这个HeaderFooterView

然后,它是不是就可以实现重用了

通知

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{

//不要在这个方法中直接创建一个UIView对象返回,因为这样无法实现重用该UIView

//为了能重用每个Header中的UIView,所以这里要返回一个UITableViewHeaderFooterView

UITableViewHeaderFooterView

通知

按住command键,点开,看一下这个类型里面

通知

有些什么样的子控件

通知

UITableViewHeaderFooterView

这个类型里面,有一个什么,

1)textLabel

2)detailTextLabel

3)contentView

4)backgroundView

5)reuseIdentifier

是不是有这些属性啊,大家看起来,它和啥有点儿像

是不是这个和单元格有点儿像啊

通知

但是,我们要这个示例程序里面,这个UITableViewHeaderFooterView里面,是不是包含一个按钮,和一个Label

大家看看里面,有按钮吗

通知

没有吧

所以说,我们系统自带的这个UITableViewHeaderFooterView,是不是不够用,

所以说,我们这个时候,要怎么办

是不是也要我们自己再单独,写这么一个类型啊

也要单独写这么一个类型

然后在这个类型里面

init,初始化的时候,我们是不是也要给它创建一个我们自己的一个子控件,一个按钮

一个Label,进来

也是一个按钮、一个Label进来

OK,来,咱们一起来,把这个写一下

来,咱们接下来,在

通知

我们本来是不是要自定义这个东西啊

本来要自定义这个东西,

但是,我们先别着急

通知

自定义

我们说,这个方法中,无非最后要返回一个UITableViewHeaderFooterView

就OK了

返回这个View以后,里面有两个子控件

一个是按钮、一个是Label

将来,我们是不是也要设置这个按钮、和这个Label、里面的数据

是不是组标题、和这个数据要设置

通知

所以说,这个方法中的步骤

和这个方法中的步骤

通知

非常像

也是

1)获取模型数据

2)创建一个UITableViewHeaderFooterView

3)设置这个View的数据

4)返回这个View

是不是也是这个步骤啊

5.接下来,咱们就写这个方法里面那四个步骤

1)第一步,获取模型数据

通知

2)第二步,创建UITableViewHeaderFooterView

通知

3)第三步,设置数据

通知

4)第四步,返回view

通知

我们刚才在单元格里面,在这个方法中

通知

获取模型数据,是不是最后要获取到具体是哪一个朋友,这个模型吧

通知

但是,我们分组里面,只要

通知

获取到组模型、拿到组的标题、拿到组里面、当前在线人数

是不是就够了

所以说,我们,对于这个组来说

通知

不需要拿到具体的朋友吧

不需要,所以说,直接获取这个组模型就可以了,command + C、

通知

command + V

通知

我们拿到组模型以后,接下来,是不是要创建这个UITableViewHeaderFooterView了

我们看,这儿报错了,这儿是没有什么

通知

没有indexPath,吧

是不是直接就是这个section,啊

通知

把section,写过来

2)好,创建这个东西,UITableViewHeaderFooterView

创建这个UITableViewHeaderFooterView的时候,

和创建Cell的时候,非常非常像

static

通知

static NSString *ID = 等于什么

叫我们的,group

通知

是不是给它起一个重用ID

通知

给它起一个重用ID,

static NSString *ID = @“group_header_view”;

然后怎么办

dequeue吧

通知

UITableViewHeaderFooterView *来个什么

headerVw

通知

等于什么

猜一猜该怎么写啊

通知

UITableViewHeaderFooterView *headerVw = [

dequeue吧

还是是不是先从队列里面去取

通知

tableView dequeueReusableHeaderFooterViewWithIdentifier:ID

dequeueReusableCell吗,不是,是

dequeueReusableHeaderFooterView

通知
通知

明白了吗

给它传一个ID

通知

也就是说,我们dequeueReusableCell,是不是重用的是我们单元格啊

通知

dequeueReusableHeaderFooterView,是不是重用的我们这个View

通知

OK,然后呢,先从缓存吃里面拿,如果没有拿到,也就意味着什么

if(headerVw == nil),吧

通知

表示没有拿到吧

没有拿到,怎么办

headerVw = 等于啥

通知
通知

headerVw = [[UITableViewHeaderFooterView alloc] init

通知

initWithReusaIdentifier:ID

通知
通知

如果说,第一步,先从缓存池里面拿,拿到这个headerView

通知

如果没拿到,我就创建一个headerView

alloc,创建一个新对象

alloc,初始化的时候,给它按照这个ID来初始化

通知

这样的话,这个HeaderView,创建好以后,就自带了一个可重用的ID

3)创建好以后,接下来,要把这个组里面的数据

通知

设置给headerView

怎么设置

headerVw

通知

headerVw“点什么”

headerVw.group

是不是里面要给它增加一个group属性啊

通知

headerVw.group = 等于我们的group对象吧

通知

但是,我们这个系统的headerView里面,有group这个属性吗

通知

有这个group吗

通知

没有

同时,我们是不是也希望把这个代码,封装一下

通知

把这段代码,封装到这个类里面

通知

所以说,基于这两个需求

现在我们必须得怎样了

是不是必须得自己定义一个这个headerView了

因为

1)第一,我们希望把这个代码封装起来

2)第二,我们希望这个类里面,有这个属性

3)第三,这个headerView里面,默认需要有一个按钮、和一个Label

由于这三个原因

系统自带的这个HeaderView,是不是不够用了

所以说,我们要怎么办,是不是要自定义这个HeaderView

先写上return headerVw;

通知

OK,接下来,就要干啥

是不是接下来,要自定义一个类,自定义这个类,是不是继承自这个类啊

通知

来,我们在这个View里面

通知

右键-怎么办-New File吧

通知

选择什么,iOS-Source-Cocoa Touch Class吧

通知

iOS下面这个Source-点它-继承自谁

通知

是不是UITableViewHeaderFooterView,啊

通知

然后这个地方,来个什么,来个,我们是不是每一个组啊

给组定义headerView吧

所以叫CZGroupHeaderView

通知

这有个组,这个HeaderView

点击“Next”

点击“Finish”

通知

OK,好,这样的话,有了这个以后,接下来

通知

有了这个,我们将来,是不是要把这儿的这个代码

通知

这儿的这个代码,是不是替换成我们的代码

所以说,第一步,里面是不是应该创建一个headerView,这个方法

OK,我们要把这个方法,封装一下

通知

封装成一个类方法吧

是不是也要根据tableView来获取

通知

让tableView从缓存池里面获取,所以我们也要给它封装一个类方法

好,封装一个类方法

通知
通知

+ (instancetype)

通知

+ (instancetype)叫什么呢

groupHeaderViewWithTableView:

通知
通知
通知

好,然后呢,接下来,我们就给它,实现一下

通知
通知

叫什么,+ groupHeaderViewWithTableView

是不是把这个代码拷过来

通知

第一句不变,static NSString *ID = @“group_header_view”;

通知

第二句变一下,UITableViewHeaderFooterView *headerVw = [tableView dequeueReusableHeaderFooterViewWithIdentifier:ID];

这儿,怎么办,

通知

变成自己写的这个类

通知

第三句也要变一下,if(headerVw == nil){

headerVw = [[UITableViewHeaderFooterView alloc] initWithReusaIdentifier:ID];

}

通知

这儿,怎么办,变成自己,

通知

这样的话,最后在里面,返回这个headerVw

return headerVw;

通知

这是不是就把那段代码给封装了

但是,因为我们希望我们这个HeaderView

创建好以后,里面默认是不是就得有一个这个

通知

按钮、和一个Label啊

所以说,我们需要重写这个initWithReuseIdentifier方法

通知

在这个方法里面,创建好以后,要先给它建两个子控件吧

1)一个是:按钮

2)一个是:Label

来,写一下

通知

- init……

通知

- initWith ReuseIdentifier:

通知

OK,在里面,怎么写

if(self = super init

通知

注意,我们不能调上面这个init吧,需要调哪个,

通知

是不是得调下面这个啊

通知

因为我们重写的是不是这个方法

通知

这儿写什么

通知

reuseIdentifier

通知

然后呢

通知

接下来,在这里边,是不是

1)创建子控件

//创建按钮

//创建Label

通知

是不是要创建这两个

最后,怎么办

返回谁啊

return self;

是不是就OK了

通知

2)好,创建按钮、和创建Label

通知

还是你先别管这个按钮:大小啦、什么都别管

先把这两个控件创建好,再说

OK,怎么写

UIButton

通知

UIButton *btnGroupTitle =

通知

等于什么,[[UIButton alloc] init];

通知

UIButton *btnGroupTitle = [[UIButton alloc] init];

然后呢,当前这个HeaderView

通知

当前这个HeaderView、和我们那个单元格一样,也是有一个叫做contentView

通知

这么一个东西

也是要把它的子控件,加到contentView里面

通知
通知

self.contentView addSubview:btnGroupTitle

通知

按钮这样就创建好了

2)创建Label

UILabel *lblCount = 等于什么

通知

UILabel *lblCount = [[UILabel alloc] init];

通知

然后呢,

[self.contentView addSubview:lblCount];

通知

这样的话,这两个子控件,是不是都创建好了

也就是说,当我们这个HeaderView创建好以后

里面是不是自带了这两个子控件了

OK,这样的话,就自带了这两个子控件了

接下来,我们在其他方法当中,是不是要给这两个子控件,设置数据,设置frame,等等一些东西吧

所以说,除了在当前这个方法中,要访问到这两个子控件以外,

在别的方法中,是不是也要访问这两个子控件

所以说,我们这里就要用一些属性,引用这些子控件

通知

因为是UI控件,所以说,最好用什么,weak吧

最好属性的标记用weak吧

通知

写一个类扩展

通知

这儿用什么,第一个是引用按钮吧

@property(nonatomic,weak)UIButton *btnGroupTitle;

通知

第二个是什么,Label吧

@property(nonatomic,weak)UILabel *lblCount;

用来标记当前第几个吗,对吧,一共有多少人,在线有多少人

通知

用这个来引用那两个子控件

所以说,当我们创建完子控件以后

通知

接下来,怎么办

self.btnGroupTitle = btnGroupTitle;

self.lblCount = lblCount;

通知
通知

好,这样的话,子控件,全都创建好了

那么,也就是说,现在我们这个地方

通知

还有必要这么来创建一个View吗

没有必要了

是不是要用我们自定义Cell、自定义View

用自定义HeaderView

所以说,这儿可以怎么办

通知

#import “CZGroupHeaderView.h”

是不是导入这个头文件啊

所以说,接下来,这儿怎么写

通知

CZGroupHeaderView *headerVw = 等于什么

通知

CZGroupHeaderView *headerVw = [CZGroupHeaderView groupHeaderViewWithTableView:(UITableView *)];

通知

CZGroupHeaderView *headerVw = [CZGroupHeaderView groupHeaderViewWithTableView:tableView];

通知

这样的话,就创建好这个HeaderView了吧

然后,HeaderView创建好了,里面子控件有了

接下来,我们是不是要给它实现、设置这个数据了

通知

要给它设置这个数据

把group模型,是不是传给它

现在我们这个自定义HeaderView里面,有这个group模型吗

通知

没有

通知

没有,所以说要怎么办,要给它加一个这个group模型

@class

通知

@class 叫什么

@class CZGroup;

通知

这儿写什么

通知

CZGroup,吧

通知

我们这里来个group

通知

好,现在的话,它是不是就有这个模型了

然后,在控制器里面,我们看

通知

是不是就能给它设置group这个模型了

那么我们接下来,要做的,就是什么

接下来,要做的就是,当我们在这个group模型的set方法里面,重写set方法

把当前group模型中的数据,设置给当前这个headerView中的子控件

同时设置子控件的frame、大小

就OK了吧

好,所以说,接下来,该干什么了

是不是重写这个、谁啊

重写这个group模型的set方法吧

通知

写个注释,下面这个是干什么

//封装一个类方法,来创建一个headerView

通知

下面这个呢

//重写initWithReuseIdentifier方法,在创建headerView的时候,同时创建子控件

通知

好,第三个,我们就重写group的set方法

//重写group属性的set方法

- (void)setGroup:(CZGroup *)group{

}

通知

当我们重写set方法的时候,首先要怎么办,

是不是先赋值啊

_group = group ;

通知

先赋值,然后接下来,就是干什么

//设置数据

//设置frame

通知

是不是基本就这个步骤

好,注意看,我现在呢,就给它设置一下它的数据,试试

怎么设置呢,当前self里面,首先我们看一下,

通知

里面是不是有个按钮吧

要让按钮里面显示的是,按钮的文字

是不是显示“我的好友”

让按钮里面显示图片,是不是显示这个小三角

通知

这个按钮里面显示的文字,每一组,显示的是不是都不一样

但是,按钮里面显示的图片,是不是都是同样的一个小三角

所以说,设置按钮上的文字,可以放到这个set方法当中

通知

但是,设置按钮上的图片,是不是可以放到它

通知

刚刚创建按钮的时候,就设置一下,就OK了

通知

因为图片,是不是始终都是一样的图片

通知

好,所以说,放到这里,就是设置按钮的图片

通知

//设置按钮的图片

通知

init方法中,设置不变的内容

set方法中,设置动态的内容

设置按钮的图片,因为每一组按钮,使用的图片都是一样的,没有必要每一次都设一次

所以说,只要设置一次,就够了

在这个创建按钮的同时,立刻设置按钮的图片

OK,怎么设置

通知

btnGroupTitle,吧

因为按钮的图片,就像按钮的文字一样,它是分状态的

在不同状态下,是不是可以显示不同的图片

所以说,它是通过set方法来设置吧

不是属性直接设置的

怎么写,setImage forState,吧

通知

btnGroupTitle setImage:[UIImage imageNamed: ] forState:(UIControlState)

通知

imageNamed:这儿给它来个什么,来一个

通知

看到了吗,左上角有个小图标

是不是buddy_header_arrow,这个图片啊

是不是箭头儿

状态是什么,UIControlStateNormal,吧

通知

OK,这样的话,是不是设置这个按钮,在我们的普通状态下,是不是显示这个图片

显示这个三角图片

通知

//设置按钮的图片(三角图片)

通知

设置完这个以后

紧接着,在我们这个setGroup方法里面

通知

在这个方法里面,我们是不是要设置按钮上的文字

设置数据就是,第一、设置按钮上的文字

//设置数据

//设置按钮上的文字

self.btnGroupTitle

通知

因为文字也是分不同状态的,所以说,也要怎么办,setTitle

通知

setTitle:叫什么

group.name

通知

为什么“点不出来”

没有导入头文件吧

通知
通知
通知

是不是有了

State呢,UIControlStateNormal,吧

[self.btnGroupTitle setTitle:group.name forState:UIControlStateNormal];

通知

OK,这样是不是设置按钮上的文字了

2)第二,我们设置好按钮上的文字以后,是不是还得要设置Label上的文字啊

通知

是不是还得要设置Label上的文字啊

Label上,是不是,一个是当前在线人数,一个是总人数吧

OK,所以说,设置Label上的文字

现在大家先别管这个Label在哪儿显示,因为没有设置frame

是不是显示不出来啊

但是我们可以设置数据嘛,

//设置lblCount上的文字

因为我们这个Label是不是不分状态啊

self.lblCount

通知

所以,Label上的文字,可以直接“点”text

通知

self.lblCount.text = [NSString stringWithFormat:@“

通知

self.lblCount.text = [NSString stringWithFormat:@“%d /

这是当前在线人数

然后呢,总的人数

self.lblCount.text = [NSString stringWithFormat:@“%d / %d“

是不是这两个

self.lblCount.text = [NSString stringWithFormat:@“%d / %d“,

当前在线人数是什么,就是group里面的吧

group.online

通知

group.online,是不是当前在线人数

group里面的online,是当前在线人数

然后呢,group里面的什么,“点”friends

通知

“点”friends,“点”count

通知

是不是总的人数啊

1)一个是当前的在线人数

2)一个是总的人数

通知

这样的话,是不是就设置好了我们Label里面的文字

通知

这儿为什么又报错了

百分号d,试试

通知

我们看一下,这是什么类型

UInteger

UInteger,是不是,无符号的整型吧

我们用一个百分号d,试试

通知

先用这个吧,先用这个,无符号整型,先用这个百分号d,吧

这儿是不是没有警告吧,咱们等会儿看一下

OK,好,然后我们现在设置好数据了

6.接下来,是不是该设置frame了

我们在继续设置frame之前

为了让现在大家先看一下,写了半天,没有看到效果

为了先让大家看一下效果

我们先把这个headerView,给大家看一下,可以吧

我们现在只是自定义了一个headerView

自定义了一个HeaderView,以后,

我们在这个数据源方法里面

通知

是不是把这个headerView返回了

我们现在先看一下,能不能看到这个headerView

里面的子控件,现在是不是肯定是看不到的,因为你就没有设置它的那个frame,对吧

按钮、和那个什么,Label,肯定是看不到的吧

我们先看一下,现在写的效果是啥

看到那个headerView了吗

通知

有人说“没有”,仔细看

看到这个颜色有点儿不一样了吗

通知

来,我把这个headerView,给你加个背景色,你就看到了

通知

headerView,在这里吧

backgroundColor

在这个类方法中

通知

喜欢什么颜色,红色吧

通知

看看

通知

为什么没有

这儿是不是没有看到红色啊

我这儿是不是设的红色

通知

看到下边提示了没有

通知
通知

人家告诉你,设置HeaderView的backgroundColor,已经不推荐了、被否决了、被反对了、就是说已经过时了,这个方法已经过时了,不要使用这个headerView直接设置它的背景色

请用contentView.backgroundColor代替

通知

请用它的contentView的background来替代这种写法

是不是类似于我们的Cell,

cell是不是也是有一个contentView啊

通过contentView,来去设置,

所以说,这句话,废掉

通知

怎么办

通知

加一个contentView 吧

这样是不是OK了

通知

看到headerView了吗

通知

看到红色了吗

这里看到警告了吗?

通知

没有

所以说,现在我们headerView,是不是已经能显示了

但是,我刚才其实没有设置headerView的高和宽

但是,headerView默认是不是这么高,

通知

填满整个这个UITableView啊

也就是说,它默认是不是有个大小

看到里面的按钮、和Label了吗

没有,仔细看,

看到了吗?

通知

这是不是就是那个按钮、和那个Label吧,

是不是因为没有设置frame,所以它显示的乱七八糟的啊

我们接下来要做的,就是把这个按钮的frame,给它设置一下,就OK了吧

设置这些按钮的frame

7.好,注意看,我首先把按钮、和Label的frame,设置一下,让它能显示出来

但是,在我们继续之前,我觉得这个headerView,有点儿高度不够

看一下,我示例程序里的headerView,多高

通知

44吧

假如说是44

我希望这个高度也是44

通知

还记得咱们怎么去统一设置单元格的高度吗,行高

rowHeight,吧

tableView.rowHeight =

我们这里统一设置headerView的高度

也有一个属性

可以统一设置分组的标题的高度

来,看一下怎么设置

首先,找到控制器里面的viewDidLoad,方法

但是,有viewDidLoad,方法吗?

通知

没有,因为咱们这个是不是没有自动生成啊

没有自动生成,有关系吗

没关系

我们自己写一个,就OK了

通知

咋写

通知

注意,重写这些父类方法的时候,首先,里面一定要先

通知

调一下super,这个方法

通知

否则就可能有问题

在这个里面

//统一设置每组的组标题的高度

self.tableView

拿到tableView

通知

里面有一个属性,叫做,每一组,就是每一个什么,section

所以说,里面叫做sectionHeaderHeight

通知

是不是组标题的高度

self.tableView.sectionHeaderHeight = 44;

通知
通知

是不是高了

然后,这个HeaderView已经能看到了

高度也有了

接下来,我们是不是要设置一下HeaderView里面子控件的frame了

那么,找到我们这个地方

在我们headerView的、自定义headerView的这个类里面

通知

比如说,我就在这里,

通知

比如说,我就在设置数据的时候, 设置一下里面,按钮的高度

self.btnGroupTitle.frame =

通知

self.btnGroupTitle.frame = CGRectMake(

1)距左边是:0

2)距上边是:0

3)宽度假如说是:200

4)高度假如说是:44

通知

这样的话,是不是就设置好这个按钮的frame了

但是,有人说,你这是信口瞎说的

这几个数字吧

对,就是先瞎写一个,试试

通知

看到了吗

按钮是不是看到了

这就是按钮,是不是有了

也就是说,我们只要在这里给它一个frame,是不是就能显示了

8.Label,也给它一个frame

self.lblCount.frame = CGRectMake(

1)距左边是:100

2)距上边是:0

3)宽度是:50

4)高度是:44

通知

是不是瞎写的,瞎写的

command + R

通知

是不是也看到了

也就是说,我只要设置按钮、和Label的frame

它是不是就能显示出来了

那么,接下来,这个按钮的frame,它到底应该设置成多少呢,

我假设它是这么来设的

通知

我们假设,这就是一个headerView吧,我们假设headerView本身就这么大

然后呢,我设置headerView里面,它是不是有个按钮

我设置这个按钮、和它是一样大的

按钮和它是一样大的,可以吧

通知

首先,headerView里面,有个按钮

按钮和它是一样大的

通知

2)然后呢,里面又有一个Label

Label呢,假如说,也是和它是一样高的,但是没有它宽吧,这是Label

通知

Label,假如说,是这么宽,距右边,假如说,是个10

宽度,可以给它指定一个100

高度,和这个headerView,是一样高的

我就希望这么来设置,

然后呢,你既然要这么设置,大家想想

这个按钮的frame

通知

这个按钮的frame,是不是等于当前这个headerView的高和宽

然后,X、Y都是0、0

也就是说,按钮的frame,就等于这个headerView的bounds,吧

还记得吗,想想,一个控件的bounds

X、Y都是0、0

相对于自己,对吧

一个控件的bounds的size

高和宽,是不是就等于控件自己的高和宽

也就是说,如果你要让这个按钮的frame等于当前的这个headerView的bounds

也就意味着,这个按钮的X、Y是0、0

通知

显示到这个headerView

左上角

0、0

通知

然后呢,高度和宽度

和这个headerView,是不是一样高、一样宽

所以说,我是不是可以这么设置啊

OK,来,试试看

9.我在这个地方

通知

让按钮的frame , 等于什么

等于我们当前这个self.

是不是就是我们当前这个headerView

headerView的bounds

通知

是不是就等于这么大啊

然后呢,这是

//设置按钮的frame

通知

接下来,就是干什么,

//设置Label的frame

好,CGFloat ,这里来个

通知

来个什么,比如说是来个,Label的一个宽,lblW

假设是一个

CGFloat lblW = 100;

假设是100,可以吧

Label可以给它定义一个

CGFloat lblH =

它的高,假如说是,它的高,是不是等于我们当前这个headerView的自身的高度啊

是不是等于我们headerView自身的高度啊

通知

等于我们headerView自身的一个高度,和它一样高的

通知

所以说,我们这里给它,等于什么

CGFloat lblH = self.bounds.size;

通知

是不是等于这个headerView自身的高度

CGFloat lblX =

它的X,等于什么

通知

是不是等于这个headerView自身的宽度,减去一个10,这个边距,再减去它自身的宽度

好,它的X

CGFloat lblX = self.bounds.size.width - 10 - lblW ;

通知

这是不是就是Label自身的X

然后呢,这个Label

CGFloat lblY = 0;

是不是紧贴住这个headerView的上边吧

然后呢,接下来,我们这里就写一下吧

通知

第一个是等于什么,lblX,吧

通知

第二个呢,lblY,

第三个呢,lblW,

第四个呢,lblH,

self.lblCount.frame = CGRectMake(lblX,lblY,lblW,lblH);

通知

这样的话,是不是就设置好这个按钮的frame、和这个Label的frame了

通知

看到了吗

是不是按钮和Label,压根儿没显示出来

是不是和一开始,效果一样了

通知

是不是什么都看不到吧

是不是只能看到这么一个效果

也就是说,我们这儿设了frame,是不是和没设是一样的

OK,现在我们就想看一下,这个frame,到底是多少

通知

是不是咱们设错了,对吧

来,看一下这个frame

NSLog

通知

来,看一下

怎么打印frame

NSString,最后要的是一个String,吧

通知

StringFrom什么

通知

NSStringFromCGRect:(CGRect rect)

通知

NSLog(@“%@”,NSStringFromCGRect(self.btnGroupTitle.frame));

通知

对吧,打印按钮这个frame,啊

我们是不是就要看按钮最终的frame,啊

为什么没显示出来

我们再看一下这个Label的frame,最终是多少

拷贝过来

通知

为什么Label,也没显示出来

拷贝过来

通知
通知

看一下,command + R

通知

看到啥了

按钮的frame,是0、0、0、0

是不是都是0

因为按钮的frame是0

也就是说,这个self.bounds

是不是都是0,啊

self.bounds,都是0 ,啊

通知

所以说,你下面Label,是根据self.bounds来算的

self.bounds是0 , 它的size,

通知

它的size.width,也是0 ,0 减去10 , 再减去宽度100,

是不是就是负值了

通知

也就是说,因为现在这个headerView的bounds,都是0

所以说,你根据headerView的bounds,来算出来所有的坐标,都不准了

既然都不准,所以说,我们这里就看不到这个按钮、和Label,这些东西了

通知

为什么是这样,我们等会儿再给大家解释,先休息一下吧

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

清风清晨

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

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

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

打赏作者

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

抵扣说明:

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

余额充值