热门标签 | HotTags
当前位置:  开发笔记 > IOS > 正文

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

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

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

Friend.h 示例代码

#import 

@interface Friend : NSObject
@property (nonatomic, copy) NSString *name;
@end

FriendGroup.h 示例代码

#import 
@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 示例代码

#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

#import "ViewController.h"
#import "SectionView.h"
#import "FriendGroup.h"
#import "Friend.h"
#define kTableViewReuse @"reuse"
@interface ViewController ()
@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进行了赋值. 先看一下效果.

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

SectionView.m

-(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的协议方法中什么都没写, 所以需要完善一下

- (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方法中要进行设置.

- (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有所帮助。


推荐阅读
  • 免费获取:全面更新的Linux集群视频教程及配套资源
    本资源包含最新的Linux集群视频教程、详细的教学资料、实用的学习课件、完整的源代码及多种软件开发工具。百度网盘链接:https://pan.baidu.com/s/1roYoSM0jHqa3PrCfaaaqUQ,提取码:41py。关注我们的公众号,获取更多更新的技术教程。 ... [详细]
  • 本文提供了关于WSDL(Web Services Description Language)的详细参考资料链接,包括官方文档和深入解析,旨在帮助开发者更好地理解和使用WSDL进行Web服务的开发与集成。 ... [详细]
  • iOS开发中解决‘_OBJC_CLASS_$_JPUSHService’引用错误的方法
    本文详细探讨了在iOS开发过程中遇到的‘_OBJC_CLASS_$_JPUSHService’引用错误,并提供了一系列有效的解决方案。 ... [详细]
  • 如何使用Ionic3框架创建首个混合开发应用
    混合开发是指结合原生(Native)与网页(Web)技术进行移动应用开发的方法。本文将详细介绍如何利用Ionic3这一流行的混合开发框架,从环境搭建到创建并运行首个应用的全过程。 ... [详细]
  • 题目链接:请点击这里。本题将图形视为波动,其中波峰被淹没时部分数减少,而波谷被淹没时部分数增加。因此,需要预先处理所有波峰和波谷的位置。特别地,图形的两端点需要特殊处理,可以通过设置边界条件来简化问题。 ... [详细]
  • Python库在GIS与三维可视化中的应用
    Python库极大地扩展了GIS的能力,使其能够执行复杂的数据科学任务。本文探讨了几个关键的Python库,这些库不仅增强了GIS的核心功能,还推动了地理信息系统向更高层次的应用发展。 ... [详细]
  • 一款专为电脑维修店设计的U盘启动盘制作工具,支持多种操作系统安装与维护。 ... [详细]
  • 本文详细介绍如何在 macOS 上编译 FFmpeg 3.1.1,并将其集成到 iOS 项目中,包括必要的环境配置和代码示例。 ... [详细]
  • 本题来自 BZOJ2004,链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2004。题目要求计算特定条件下的方案数,采用动态规划(DP)解决。由于任意两站间的距离不超过 p,因此每 p 个站点中所有的公交车都必须至少停靠一次。 ... [详细]
  • 2014年4月17日,深入研究了邵杨的代码库,发现代码中的注释较为稀少,影响了理解的效率。同时,学习了一些Eclipse的高效操作技巧。 ... [详细]
  • 深入理解BIO与NIO的区别及其应用
    本文详细探讨了BIO(阻塞I/O)和NIO(非阻塞I/O)之间的主要差异,包括它们的工作原理、性能特点以及应用场景,旨在帮助开发者更好地理解和选择适合的I/O模型。 ... [详细]
  • 面临考试压力,急需解决四个编程问题,包括实现乒乓球的动态效果、计算特定日期是一年的第几天、逆序输出数字以及创建弹出菜单。每个问题的解决都能在TC3.0环境中获得50分。 ... [详细]
  • 在使用 iOS 应用时,遇到网络请求错误是常见的问题。本文将探讨两种常见的错误代码 -1003 和 -1001,并提供详细的解释和解决方案。 ... [详细]
  • iOS绘制就是采集点,贝塞尔曲线得到形状,绘图上下文去渲染出来AsanaDrawsana图形库,设计的挺好他可以画多种图形, ... [详细]
  • Web App vs Native App:未来的移动应用趋势
    随着移动互联网的发展,Web App和Native App之间的竞争日益激烈。对于开发者而言,选择哪一种技术路径更为明智?本文将深入探讨两种应用模式的特点及未来趋势。 ... [详细]
author-avatar
小白吃丸子
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有