服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - IOS - IOS实现简易版的QQ下拉列表

IOS实现简易版的QQ下拉列表

2021-01-23 16:53iOS开发网 IOS

在我们日常开发中tableView是用的非常多的控件, 无论在新闻应用, 视频, 聊天应用中都广泛使用, 那么今天小编也分享一个用tableView实现的类似QQ界面的下拉列表.效果很简单,有需要的朋友们可以参考借鉴。

下面我们通过实例代码来一步步看怎么实现, 首先建立了两个模型类, 一个friend, 一个friendgroup类. 数据源用的本地的一个plist文件. plist文件中包含了friendgroup的name,friends数组等属性.

friend.h 示例代码

?
1
2
3
4
5
#import <foundation/foundation.h>
 
@interface friend : nsobject
@property (nonatomic, copy) nsstring *name;
@end

friendgroup.h 示例代码

?
1
2
3
4
5
6
7
8
9
10
#import <foundation/foundation.h>
@interface friendgroup : nsobject
@property (nonatomic, copy) nsstring *name;
// 数组中存放的为friend类的实例对象
@property (nonatomic, copy) nsmutablearray *friends;
// 用来判断分组是否打开(opened属性正是实现下拉列表的关键)
@property (nonatomic, assign, getter = isopened) bool opened;
// 自定义方法用来赋值
-(void)setfriendgroupdic:(nsmutabledictionary *)dic;
@end

friendgroup.m 示例代码

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#import "friendgroup.h"
#import "friend.h"
@implementation friendgroup
 
-(void)setfriendgroupdic:(nsmutabledictionary *)dic
{
// 通过字典给friendgroup的属性赋值
 [self setvaluesforkeyswithdictionary:dic];
 nsmutablearray *temparray = [nsmutablearray array];
// 遍历friends属性数组
 for (nsmutabledictionary *dic in self.friends) {
  friend *friend = [[friend alloc] init];
  [friend setvaluesforkeyswithdictionary:dic];
  [temparray addobject:friend];
 }
 //重新对friends属性数组赋值,此时存的都是friend对象
 self.friends = [nsmutablearray arraywitharray:temparray];
}
@end

在viewcontroller中创建一个tableview

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#import "viewcontroller.h"
#import "sectionview.h"
#import "friendgroup.h"
#import "friend.h"
#define ktableviewreuse @"reuse"
@interface viewcontroller ()<uitableviewdelegate, uitableviewdatasource, sectionviewdelegate>
@property (nonatomic, strong) uitableview *tableview;
// 数组中存放friendgroup的实例对象
@property (nonatomic, strong) nsmutablearray *allarray;
@end
 
@implementation viewcontroller
 
- (void)viewdidload {
 [super viewdidload];
 self.allarray =[nsmutablearray array];
 [self creattableview];
 [self getdata];
}
 
- (void)creattableview {
 self.tableview = [[uitableview alloc] initwithframe:self.view.bounds style:uitableviewstyleplain];
 _tableview.delegate = self;
 _tableview.datasource = self;
 [_tableview registerclass:[uitableviewcell class] forcellreuseidentifier:ktableviewreuse];
 [self.view addsubview:_tableview];
}
// 获取数据
- (void)getdata {
 nsstring *filepath = [[nsbundle mainbundle] pathforresource:@"friends.plist" oftype:nil];
 nsarray *temparray = [nsarray arraywithcontentsoffile:filepath];
 for (nsmutabledictionary *dic in temparray) {
  friendgroup *friendgroup = [[friendgroup alloc] init];
  [friendgroup setfriendgroupdic:dic];
  [self.allarray addobject:friendgroup];
 }
 [self.tableview reloaddata];
}
 
- (cgfloat)tableview:(uitableview *)tableview heightforheaderinsection:(nsinteger)section {
 return 50;
}
// sectionview必须实现的协议方法
- (void)touchaction:(sectionview *)sectionview {
 
}
#pragma mark - tableview delegate
-(uiview *)tableview:(uitableview *)tableview viewforheaderinsection:(nsinteger)section
{
 friendgroup *friendgroup = [self.allarray objectatindex:section];
 //放一个封装的view,view上有一个label和imageview,自带touch事件,点击触发协议方法
 sectionview *sectionview = [[sectionview alloc] initwithframe:cgrectmake(0, 0, 375, 50)];
 sectionview.delegate = self;
 sectionview.tag = section + 1000;
 sectionview.textlabel.text = friendgroup.name;
 sectionview.group = friendgroup;
 return sectionview;
}
#pragma mark - tableview datasource
- (nsinteger)numberofsectionsintableview:(uitableview *)tableview {
 return _allarray.count;
}
- (nsinteger)tableview:(uitableview *)tableview numberofrowsinsection:(nsinteger)section {
 return [_allarray[section] friends].count;
}
- (uitableviewcell *)tableview:(uitableview *)tableview cellforrowatindexpath:(nsindexpath *)indexpath {
 uitableviewcell *cell = [tableview dequeuereusablecellwithidentifier:ktableviewreuse];
 friendgroup *friendgroup = _allarray[indexpath.section];
 friend *friend = friendgroup.friends[indexpath.row];
 cell.textlabel.text = friend.name;
 return cell;
}
#pragma mark - memory waring
- (void)didreceivememorywarning {
 [super didreceivememorywarning];
 // dispose of any resources that can be recreated.
}
 
 
@end

可以从上面代码看到, 创建了一个tableview. 并根据数组个数给分区数量赋值, 然后在tableview: viewforheaderinsection:方法里, 用一个自定的view给分区头视图赋值. 在tableview: cellforrowatindexpath:方法里给每个分区对应的cell进行了赋值. 先看一下效果.

IOS实现简易版的QQ下拉列表

从上图可以看到现在每个分区中对应有不同数量的row,但是还没有实现我们想要的效果.所以再往下继续看.

sectionview.m

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
-(void)touchesbegan:(nsset *)touches withevent:(uievent *)event
{
 [self.delegate touchaction:self];
}
/*
 [self.delegate touchaction:self];
 协议方法会刷新tableview,然后会刷新tableview的 viewforheaderinsection:方法
 就会重新布局sectionview所以会走layoutsubviews方法
 */
-(void)layoutsubviews
{
 [super layoutsubviews];
// 改变imageview的transform属性 点击时有开闭的效果
 [uiview animatewithduration:0.3 animations:^{
  _imageview.transform = _group.opened ? cgaffinetransformmakerotation(m_pi_2) : cgaffinetransformmakerotation(0);
 }];
}

点击sectionview时 就让代理人去执行协议方法,但是在vc的协议方法中什么都没写, 所以需要完善一下

?
1
2
3
4
5
6
7
8
- (void)touchaction:(sectionview *)sectionview {
// 通过前面设置的tag值找到分区的index
 nsinteger index = sectionview.tag - 1000;
 friendgroup *group = [self.allarray objectatindex:index];
// 每次点击, 状态变为与原来相反的值
 group.opened = !group.isopened;
 [self.tableview reloadsections:[nsindexset indexsetwithindex:index] withrowanimation:uitableviewrowanimationnone];
}

我们平时用的qq下拉列表, 未打开时不显示好友, 打开后才展示好友列表. 所以应该在numberofrowsinsection方法中要进行设置.

?
1
2
3
4
5
6
- (nsinteger)tableview:(uitableview *)tableview numberofrowsinsection:(nsinteger)section {
 friendgroup *group = [self.allarray objectatindex:section];
// 如果未打开 count为0 如果打开 count为group的属性数组对应的个数
 nsinteger count = group.isopened ? group.friends.count : 0;
 return count;
}

效果如下图

IOS实现简易版的QQ下拉列表

总结

以上就是ios实现简易版的qq下拉列表的全部内容,效果虽然很简单,但还会希望对大家开发ios有所帮助。

延伸 · 阅读

精彩推荐
  • IOSIOS开发之字典转字符串的实例详解

    IOS开发之字典转字符串的实例详解

    这篇文章主要介绍了IOS开发之字典转字符串的实例详解的相关资料,希望通过本文能帮助到大家,让大家掌握这样的方法,需要的朋友可以参考下...

    苦练内功5832021-04-01
  • IOSiOS 雷达效果实例详解

    iOS 雷达效果实例详解

    这篇文章主要介绍了iOS 雷达效果实例详解的相关资料,需要的朋友可以参考下...

    SimpleWorld11022021-01-28
  • IOSiOS中tableview 两级cell的展开与收回的示例代码

    iOS中tableview 两级cell的展开与收回的示例代码

    本篇文章主要介绍了iOS中tableview 两级cell的展开与收回的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    J_Kang3862021-04-22
  • IOSiOS通过逆向理解Block的内存模型

    iOS通过逆向理解Block的内存模型

    自从对 iOS 的逆向初窥门径后,我也经常通过它来分析一些比较大的应用,参考一下这些应用中某些功能的实现。这个探索的过程乐趣多多,不仅能满足自...

    Swiftyper12832021-03-03
  • IOS解析iOS开发中的FirstResponder第一响应对象

    解析iOS开发中的FirstResponder第一响应对象

    这篇文章主要介绍了解析iOS开发中的FirstResponder第一响应对象,包括View的FirstResponder的释放问题,需要的朋友可以参考下...

    一片枫叶4662020-12-25
  • IOSiOS布局渲染之UIView方法的调用时机详解

    iOS布局渲染之UIView方法的调用时机详解

    在你刚开始开发 iOS 应用时,最难避免或者是调试的就是和布局相关的问题,下面这篇文章主要给大家介绍了关于iOS布局渲染之UIView方法调用时机的相关资料...

    windtersharp7642021-05-04
  • IOSIOS 屏幕适配方案实现缩放window的示例代码

    IOS 屏幕适配方案实现缩放window的示例代码

    这篇文章主要介绍了IOS 屏幕适配方案实现缩放window的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要...

    xiari5772021-06-01
  • IOS关于iOS自适应cell行高的那些事儿

    关于iOS自适应cell行高的那些事儿

    这篇文章主要给大家介绍了关于iOS自适应cell行高的那些事儿,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的...

    daisy6092021-05-17