现在,UICollectionViews有了简单的重排功能
原文:UICollectionViews Now Have Easy Reordering
我是UICollectionView的忠实粉丝。这个类比起它的老哥UITableView类具有更高的可定制性。现在我用collection view的次数要比用table view还多。随着iOS9的到来,它支持简单的重排。在此之前,重排不可能有现成的方法,同时这样做也是件痛苦的工作。现在让我们来看看API,你可以在GitHub找到相应的Xcode工程。
添加简单重排的最简单的方式是用UICollectionViewController。它现在有了一个新的属性叫installsStandardGestureForInteractiveMovement(为交互式移动工作设置标准手势),这个属性的添加使得我们可以用标准手势来对cell单元进行重新排序。该属性默认值为true,这意味着我们只需要重载一个方法就可以让它正常工作。
|
1
2
3
4
5
|
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是一个持续的、完全支持平移的手势识别器。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
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有附加的方法来处理重排。
|
1
2
3
4
5
6
7
8
|
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结束后才调用。通过这些知识我们能通过一点小窍门,实现我们的需求。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
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前端框架工程师干得漂亮!:)
P.S:我要感谢Douglas Hill对于代码完善的一些建议。
现在,UICollectionViews有了简单的重排功能的更多相关文章
- UICollectionViews有了简单的重排功能
代码地址如下:http://www.demodashi.com/demo/13213.html 一.前言 我是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 ...
随机推荐
- Android 中Activity生命周期分析(二):从AActivity 到BActivity过程分析
如果你没有动手去演示的话,你一定要去动手试试看,这个东西非学容易出错,面试中经常出现,好了,上代码: package com.king.review.base; import android.app. ...
- hdu 1575 Tr A (矩阵快速幂入门题)
题目 先上一个链接:十个利用矩阵乘法解决的经典题目 这个题目和第二个类似 由于矩阵乘法具有结合律,因此A^4 = A * A * A * A = (A*A) * (A*A) = A^2 * A^2.我 ...
- Android系统服务-WindowManager
WindowManager是Android中一个重要的服务 (Service ).WindowManager Service 是全局的,是唯一的.它将用户的操作,翻译成为指令,发送给呈现在界面上的 ...
- HDU 3336 (KMP next性质) Count the string
直接上传送门好了,我觉得他分析得非常透彻. http://972169909-qq-com.iteye.com/blog/1114968 #include <cstdio> #includ ...
- Samba 4.x.x全版本存在命令执行漏洞
Samba 4.0.0到4.1.10版本的nmbd(the NetBIOS name services daemon)被发现存在远程命令执行漏洞.CVE编号为CVE-2014-3560.目前官方已经发 ...
- BZOJ2252: [2010Beijing wc]矩阵距离
题解: 我脑子里都是翔??? bfs一下就行了 我居然还想什么kd tree!真是too naive,,, #include<cstdio> #include<cstdlib> ...
- uva 11624 Fire!(搜索)
开始刷题啦= = 痛并快乐着,学到新东西的感觉其实比看那些无脑的小说.电视剧有意思多了 bfs裸体,关键是先把所有的着火点放入队列,分开一个一个做bfs会超时的 发现vis[][]是多余的,完全可以用 ...
- POJ 2446 Chessboard (二分图匹配)
题意 在一个N*M的矩形里,用1*2的骨牌去覆盖该矩形,每个骨牌只能覆盖相邻的两个格子,问是否能把每个格子都盖住.PS:有K个孔不用覆盖. 思路 容易发现,棋盘上坐标和为奇数的点只会和坐标和为偶数的点 ...
- LeetCode Reverse Linked List (反置链表)
题意: 将单恋表反转. 思路: 两种方法:迭代和递归. 递归 /** * Definition for singly-linked list. * struct ListNode { * int va ...
- 【CSS】使用CSS改变超链接样式
超链接代码 <ahrefahref="http://www.divCSS5.com/"target="_blank" title="关于divC ...