UICollectionViews有了简单的重排功能
一、前言
我是UICollectionView的忠实粉丝。这个类比起它的老哥UITableView类具有更高的可定制性。现在我用collection view的次数要比用table view还多。随着iOS9的到来,它支持简单的重排。在此之前,重排不可能有现成的方法,同时这样做也是件痛苦的工作。现在让我们来看看API,你可以在下载本项目源码,看具体的实现过程。
二、实现过程
添加简单重排的最简单的方式是用UICollectionViewController。它现在有了一个新的属性叫installsStandardGestureForInteractiveMovement(为交互式移动工作设置标准手势),这个属性的添加使得我们可以用标准手势来对cell单元进行重新排序。该属性默认值为true,这意味着我们只需要重载一个方法就可以让它正常工作。
override func collectionView(collectionView: UICollectionView,
    moveItemAtIndexPath sourceIndexPath: NSIndexPath,
    toIndexPath destinationIndexPath: NSIndexPath) {
    // move your data order
}
Collection view推断每个item(元素)可以被移动,因为moveItemAtIndexPath函数被重载了。

当我们想使用一个带有collection view的简单的UIViewController时,事情变得更加复杂。我们还需要实现之前提到的UICollectionViewDataSource的方法,但我们需要重写installsStandardGestureForInteractiveMovement。别担心,这些也很容易被支持。UILongPressGestureRecognizer是一个持续的、完全支持平移的手势识别器。
override func viewDidLoad() {
    super.viewDidLoad()
            longPressGesture = UILongPressGestureRecognizer(target: self, action: "handleLongGesture:")
        self.collectionView.addGestureRecognizer(longPressGesture)
}
    func handleLongGesture(gesture: UILongPressGestureRecognizer) {
        switch(gesture.state) {
        case UIGestureRecognizerState.Began:
            guard let selectedIndexPath = self.collectionView.indexPathForItemAtPoint(gesture.locationInView(self.collectionView)) else {
                break
            }
            collectionView.beginInteractiveMovementForItemAtIndexPath(selectedIndexPath)
        case UIGestureRecognizerState.Changed:
            collectionView.updateInteractiveMovementTargetPosition(gesture.locationInView(gesture.view!))
        case UIGestureRecognizerState.Ended:
            collectionView.endInteractiveMovement()
        default:
            collectionView.cancelInteractiveMovement()
        }
    }
我们储存了被选择的索引路径,这个路径从 longPressGesture handler(长按手势处理器)中获得,这个路径还取决于它是否有任何我们允许的,跟平移手势相关的值。接下来我们根据手势状态调用一些新的 collection view 方法:
beginInteractiveMovementForItemAtIndexPath(indexPath: NSIndexPath)?开始在特定的索引路径上对cell(单元)进行Interactive Movement(交互式移动工作)。updateInteractiveMovementTargetPosition(targetPosition: CGPoint)?在手势作用期间更新交互移动的目标位置。】endInteractiveMovement()?在完成手势动作后,结束交互式移动cancelInteractiveMovement()?取消Interactive Movement。
这让处理平移手势更容易理解了。

机器反应跟标准的 UICollectionViewController 一样,真的很酷,但是还有更酷的--我们能对自定义的 collection view layout(collection集合视图布局)申请重排,下面是在 waterfall layout(瀑布布局)里对 Interactive Movement 的测试。

嗯哼,看起来很酷,但如果我们不想在移动 cell(单元)的时候改变它们的大小,那该怎么做?被选择的 cell(单元)的大小在 Interactive Movement 期间应该保持原样。这是可行的。UICollectionViewLayout 有附加的方法来处理重排。
func invalidationContextForInteractivelyMovingItems(targetIndexPaths: [NSIndexPath],
    withTargetPosition targetPosition: CGPoint,
    previousIndexPaths: [NSIndexPath],
    previousPosition: CGPoint) -> UICollectionViewLayoutInvalidationContext
func invalidationContextForEndingInteractiveMovementOfItemsToFinalIndexPaths(indexPaths: [NSIndexPath],
    previousIndexPaths: [NSIndexPath],
    movementCancelled: Bool) -> UICollectionViewLayoutInvalidationContext
第一个函数在元素的 Interactive Movement 期间被调用,它带有 target(目标元素)和先前的 cell 的indexPaths(索引地址)。第二个与第一个函数类似,但它只在 Interactive Movement 结束后才调用。通过这些知识我们能通过一点小窍门,实现我们的需求。
internal override func invalidationContextForInteractivelyMovingItems(targetIndexPaths: [NSIndexPath],
    withTargetPosition targetPosition: CGPoint,
    previousIndexPaths: [NSIndexPath],
    previousPosition: CGPoint) -> UICollectionViewLayoutInvalidationContext {
    var context = super.invalidationContextForInteractivelyMovingItems(targetIndexPaths,
        withTargetPosition: targetPosition, previousIndexPaths: previousIndexPaths,
        previousPosition: previousPosition)
    self.delegate?.collectionView!(self.collectionView!, moveItemAtIndexPath: previousIndexPaths[0],
        toIndexPath: targetIndexPaths[0])
    return context
}
取得当前正在移动的cell的之前的和目标索引路径,然后调用 UICollectionViewDataSource 方法来移动这些 item(元素)。

毫无疑问,collection view的重排是一个出色的附加功能,UIKit前端框架工程师干得漂亮!												
UICollectionViews有了简单的重排功能的更多相关文章
- 现在,UICollectionViews有了简单的重排功能
		
原文:UICollectionViews Now Have Easy Reordering 我是UICollectionView的忠实粉丝.这个类比起它的老哥UITableView类具有更高的可定制性 ...
 - ASP.NET MVC 学习4、Controller中添加SearchIndex页面,实现简单的查询功能
		
参考:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/examining-the-edit-method ...
 - Web---创建Servlet的3种方式、简单的用户注册功能
		
说明: 创建Servlet的方式,在上篇博客中,已经用了方式1(实现Servlet接口),接下来本节讲的是另外2种方式. 上篇博客地址:http://blog.csdn.net/qq_26525215 ...
 - js+html+css简单的互动功能页面(2015知道几乎尖笔试题)http://v.youku.com/v_show/id_XMTI0ODQ5NTAyOA==.html?from=y1.7-1.2
		
js+html+css实现简单页面交互功能(2015知乎前端笔试题) http://v.youku.com/v_show/id_XMTI0ODQ5NTAyOA==.html? from=y1.7-1. ...
 - Spring 学习——基于Spring WebSocket 和STOMP实现简单的聊天功能
		
本篇主要讲解如何使用Spring websocket 和STOMP搭建一个简单的聊天功能项目,里面使用到的技术,如websocket和STOMP等会简单介绍,不会太深,如果对相关介绍不是很了解的,请自 ...
 - Django文件上传三种方式以及简单预览功能
		
主要内容: 一.文件长传的三种方式 二.简单预览功能实现 一.form表单上传 1.页面代码 <!DOCTYPE html> <html lang="en"> ...
 - 运用socket实现简单的ssh功能
		
在python socket知识点中已经对socket进行了初步的了解,那现在就使用这些知识来实现一个简单的ssh(Secure Shell)功能. 首先同样是建立两个端(服务器端和客户端) 需求是: ...
 - Jenkins实现简单的CI功能
		
步骤一:安装JDK.Tomcat,小儿科的东西不在此详细描述 步骤二:下载安装Jenkins下载链接:https://jenkins.io/download/ 步骤三:将下载的jenkins.war部 ...
 - jQuery实现简单前端搜索功能
		
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
 
随机推荐
- (二)mysql忘记root密码
			
(1)mysql 5.7.6以前版本 修改配置文件vim /etc/my.cnf [mysqld] skip-grant-tables 重启mysql systemctl restart mysqld ...
 - MySQL的数据类型和建库策略详解
			
无论是在小得可怜的免费数据库空间或是大型电子商务网站,合理的设计表结构.充分利用空间是十分必要的.这就要求我们对数据库系统的常用数据类型有充分的认识.下面我就将我的一点心得写出来跟大家分享. 一.数字 ...
 - Educational Codeforces Round 30 B【前缀和+思维/经典原题】
			
B. Balanced Substring time limit per test 1 second memory limit per test 256 megabytes input standar ...
 - HDU 2700 Parity(字符串,奇偶性)
			
Parity Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...
 - UOJ Rounds
			
UOJ Test Round #1 T1:数字比大小的本质是按(长度,字典序)比大小. T2:首先发现单调性,二分答案,用堆模拟,$O(n\log^2 n)$. 第二个log已经没有什么可优化的了,但 ...
 - [APIO2015]巴厘岛的雕塑
			
题目描述 印尼巴厘岛的公路上有许多的雕塑,我们来关注它的一条主干道. 在这条主干道上一共有 NN 座雕塑,为方便起见,我们把这些雕塑从 11 到 NN 连续地进行标号,其中第 ii 座雕塑的年龄是 Y ...
 - [BZOJ2753]滑雪与时间胶囊
			
第一问直接把可以走的边连起来bfs一遍即可 第二问可以用类似kruskal的方法,只不过排序的依据应该变为第一关键字为终点高度(从大到小),第二关键字为边权(从小到大),只排序可以走的边 因为同样高度 ...
 - [CF414E]Mashmokh's Designed Problem
			
题意:给一棵树,有三个操作:①询问两点$(x,y)$之间的距离②把$x$和原来的父亲断开并连到它的$h$级祖先,作为新父亲最右的儿子③询问与根节点距离为$k$的点中最右的点是哪个点 用出栈入栈序$s_ ...
 - [测试技术分享]DNS域传送漏洞测试
			
DNS域传送漏洞测试 1.简介: DNS(Domain Name System)也叫域名管理系统,它它建立在一个分布式数据库基础之上,在这个数据库里,保存了IP地址和域名的相互映射关系.正因为DNS的 ...
 - C# 6.0可能会支持模式匹配了
			
今天在CodePlex的Roslyn讨论区发现了一个帖子:Draft spec for records and pattern-matching in C#,估计MS计划在C# 6.0中支持模式匹配了 ...