iOS中的界面多选功能--(UICollectionView)

news/2024/7/23 13:56:18
文/Jacob_Pan(简书作者)
原文链接:http://www.jianshu.com/p/9d28ebd0f5a2
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

最近做项目接触了一些需要实现多选的功能,但总结起来方法类似;实现此功能的方法有很多,接下来介绍一种方法,利用UICollectionView实现。

 


我们都知道,UICollectionView可以被认为更高级的UITableView,因此UITableView里面可以实现的在UICollectionView都可以实现,尤其针对类似瀑布流那样的界面,UICollectionView功能更强大,更方便。

本文没有介绍UICollectionView的Cell定制,代理的设置,数据模型,userView的封装等,如有兴趣可参照下面我做的简易Demo。

 


对于多选功能,显然我们会用到UICollectionView的两个方法:

- (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath;

- (BOOL)collectionView:(UICollectionView *)collectionView shouldDeselectItemAtIndexPath:(NSIndexPath *)indexPath; // called when the user taps on an already-selected item in multi-select mode

同时用户可能会多次选择、取消操作,也就是说我们允许多次点击(multiple touch),为了更好处理这样操作,UICollectionView提供方法:

- (void)performBatchUpdates:(void (^ __nullable)(void))updates completion:(void (^ __nullable)(BOOL finished))completion; // allows multiple insert/delete/reload/move calls to be animated simultaneously. Nestable.

注意:在建立UICollectionView时,它的allowsMultipleSelection属性一定设置成YES。

 


在Demo中创建了一个Button,点击全选,按钮title改变,再次点击全部取消,此时需要对UICollectionView中的indexPath.item进行遍历,则创建了一个NSMutableIndexSet来增加和删除:

@property (nonatomic, strong) NSMutableIndexSet* selectedIndexSet;

当前没有选择时,我们会把它加入进去;选择后再次选择,会删除它。部分代码如下:

if ([self collectionView:self.contactsPickerView shouldSelectItemAtIndexPath:indexPath]) {

[self.contactsPickerView selectItemAtIndexPath:indexPath animated:YES scrollPosition:UICollectionViewScrollPositionNone];

[self.selectedIndexSet addIndex:indexPath.item];

}

if ([self collectionView:self.contactsPickerView shouldDeselectItemAtIndexPath:indexPath]) {

[self.contactsPickerView deselectItemAtIndexPath:indexPath animated:YES];

[self.selectedIndexSet removeIndex:indexPath.item];

}

到此为止,读者也许已经想到,针对全选和全不选,只要遍历即可,下面为本人用的方法:

全选:for (NSUInteger index = 0; index < count; ++index) {

NSIndexPath *indexPath = [NSIndexPath indexPathForItem:index inSection:0];

if ([self collectionView:self.contactsPickerView shouldSelectItemAtIndexPath:indexPath]) {

[self.contactsPickerView selectItemAtIndexPath:indexPath animated:YES scrollPosition:UICollectionViewScrollPositionNone];

[self.selectedIndexSet addIndex:indexPath.item];

}

}

全不选:[self.selectedIndexSet enumerateIndexesUsingBlock:^(NSUInteger index, BOOL * _Nonnull stop) {

NSIndexPath *indexPath = [NSIndexPath indexPathForItem:index inSection:0];

if ([self collectionView:self.contactsPickerView shouldDeselectItemAtIndexPath:indexPath]) {

[self.contactsPickerView deselectItemAtIndexPath:indexPath animated:YES];

[self.selectedIndexSet removeIndex:indexPath.item];

}

}];

 


按钮标题也要随之改变,因此综上所述按钮的实现方法为:

- (IBAction)handleToggleSelectionBtn:(id)sender {

NSUInteger count = [self.contacts count];

BOOL allEnabledContactsSelected = [self allEnabledContactsSelected];

if (!allEnabledContactsSelected) {

[self.contactsPickerView performBatchUpdates:^{

for (NSUInteger index = 0; index < count; ++index) {

NSIndexPath *indexPath = [NSIndexPath indexPathForItem:index inSection:0];

if ([self collectionView:self.contactsPickerView shouldSelectItemAtIndexPath:indexPath]) {

[self.contactsPickerView selectItemAtIndexPath:indexPath animated:YES scrollPosition:UICollectionViewScrollPositionNone];

[self.selectedIndexSet addIndex:indexPath.item];

}}} completion:^(BOOL finished) {

[self updateToggleSelectionButton];

}];} else {

[self.contactsPickerView performBatchUpdates:^{

[self.selectedIndexSet enumerateIndexesUsingBlock:^(NSUInteger index, BOOL * _Nonnull stop) {

NSIndexPath *indexPath = [NSIndexPath indexPathForItem:index inSection:0];

if ([self collectionView:self.contactsPickerView shouldDeselectItemAtIndexPath:indexPath]) {

[self.contactsPickerView deselectItemAtIndexPath:indexPath animated:YES];

[self.selectedIndexSet removeIndex:indexPath.item];

}}];} completion:^(BOOL finished) {

[self updateToggleSelectionButton];

}];}}

在此基本功能已经实现,但详细具体细节本文没有给出,只是给出一种思路;如果现在你的感觉是:

 


不要着急:请看Demo

百度云升级

转载于:https://www.cnblogs.com/Free-Thinker/p/5231484.html


http://www.niftyadmin.cn/n/515665.html

相关文章

Vue 路由的使用及嵌套的子路由

目的&#xff1a;vue项目开发时用到子路由的嵌套 1.一开始使用&#xff1a; <component v-bind:is"content"></component> 解决子组件的 切换的。通过改变content的赋值来实现加载子组件。 2. 但是当路径发生变化是比如多了子路由1中的组件就不能 满足…

关于web调用摄像头和进行反扫二维码等到信息

目的&#xff1a;实现web在浏览器中得到二维码&#xff08;外部信息&#xff09; 过程&#xff1a;1. 调用摄像头2.拍照3.解析二维码数据4.返回到网页中 总结&#xff1a;使用了别人的开源解析二维码&#xff0c;具体实现方法还没搞懂 步骤1&#xff1a;实现摄像头调用 <…

关于web网页Js请求头的设置

目的&#xff1a;完成在vue项目里的请求头设置&#xff0c;并在webapi中获取头&#xff0c;然后执行一定的操作&#xff08;vue.net webapi)。 结果&#xff1a;顺利完成&#xff0c;web请求头缺乏全面的l了解&#xff0c;真正的企业项目中都会对请求的拦截处理。 步骤&#…

#父与子的编程之旅#第十二章

第12章主要介绍列表和字典。列表很好理解&#xff0c;和C语言里面的数组差不多&#xff0c;字典是python里面的新知识&#xff0c;重点关注。 列表什么是列表&#xff1f;列表可以说是一个方括号括起来的大集合。如&#xff1a;可以是字符串的集合&#xff0c;family [Mom,Dad…

EF生成数据库(使用控制台命令)

转载&#xff1a;https://blog.csdn.net/killcwd/article/details/52023226 1.先设置好实体类 2.创建一个继承DbContext的上下文类 3. Context类&#xff08;类名和下的方法同名&#xff09;&#xff1a; public Context() : base("namexxxxxx&quo…

2周《机电传动控制》学习笔记

一、阅读电机发展简史 ①电机发展简史资料中&#xff0c;一开始便提及了“法拉第发现了载流导体在磁场中的受力情况”。这是一个很经典的故事&#xff0c;我在高中学法拉第电磁感应定律时就听说过。但我有一点疑问&#xff0c;法拉第在做实验的时候就有了电吗&#xff1f;电不是…

关于阿里图标引用

https://blog.csdn.net/qq_36742720/article/details/83472288 此博客有详细介绍。

ACM/ICPC 之 最长公共子序列计数及其回溯算法(51Nod-1006(最长公共子序列))

这道题被51Nod定为基础题&#xff08;这要求有点高啊&#xff09;&#xff0c;我感觉应该可以算作一级或者二级题目&#xff0c;主要原因不是动态规划的状态转移方程的问题&#xff0c;而是需要理解最后的回溯算法。 题目大意&#xff1a;找到两个字符串中最长的子序列&#xf…