前几天在gitHub看到个不错的效果,就是DaiExpandCollectionView,效果如图:
 
所以赶紧下下来源码看看他怎么实现的,打开源码看了半天,发现他没写什么关于动画的代码啊。。。
经高人指点,才明白原来他是利用了UICollectionViewFlowLayout的隐式动画!
 
所谓隐式动画,就是系统自带的动画了,其实也不是什么高大上的东西,关键是我怎么就没想到可以这么用!
 
研究了半天人家的源码,基本了解了他实现的思路,然后发现他的这个库用起来比较不方便,需要继承他的collectionView,而且不能自定义cell大小,不能很好的适配各种尺寸的屏幕,
但这个库我确实很喜欢,所以就自己仿写了一个,就是LXMExpandLayout,顺便解决下上面发现的问题,地址在这里: https://github.com/Phelthas/LXMExpandLayout
效果如图:
                  
 
 
还是来说说思路和原理的问题
基本思路是:
     继承系统的UICollectionViewFlowLayout,利用UICollectionViewFlowLayout已有的各种属性和效果,对其做出适当的修改已达到自己想要的效果
 
具体来说就是:
1,重载  - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect;方法,
用 [super layoutAttributesForElementsInRect:newRect]获取各个元素在 UICollectionViewFlowLayout中的layoutAttributes。
然后修改其属性
 
2,属性可不是随便改的,这个得给原作者点个赞,他想出来的这个规则,让这个属性的修改简单了好几倍。
这个规则就是:选中的item放大到这个item的旁边只能放得下一个没有放大的item!!!
这个规则的牛X之处在于:这样放大的item的右边,刚好可以放得下原来跟他同一行的剩下的item,进而需要修改属性的item就是原来跟需要放大的item同一行的item,剩下item,只需要简单的上下平移或者根本不用动!!!
 
3,知道了这个规则,就有了方向,可以大胆动手改了,选中的item用transform属性做平移和放大,其他的简单修改frame就可以了
这里怎么取出来和选中item同一行的其他item呢?
有个不错的方法,就是: self.sameRowItemArray = [super layoutAttributesForElementsInRect:CGRectMake(0, selectedAttributes.frame.origin.y, self.collectionViewWidth, self.itemHeight)];注意是super的方法,不是self~~
 
4,关键的时刻到了,怎么让collectionView执行隐形动画呢?
这个也是从原作者那里学到的,就是调用系统的 - (void)performBatchUpdates:(void (^)(void))updates completion:(void (^)(BOOL finished))completion;方法。我把它封装成了一个collectionView的分类,方便配合我的LXMExpandLayout使用。
这个方法会使collectionView重新调用其layout去重新布局,而且是带动画的哦~~
 
5,直接调用performBatchUpdates方法的话,动画是线性的,那怎么样才能有弹簧的效果呢?
这里又从原作者那里学到一招:用一个UIView animation的block将则个performBatchUpdates包起来
这样就可以用UIView的animation动画代替performBatchUpdates的默认动画。利用iOS7自带的弹簧动画方法
+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay usingSpringWithDamping:(CGFloat)dampingRatio initialSpringVelocity:(CGFloat)velocity options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion NS_AVAILABLE_IOS(7_0);
效果杠杠的~~
 

6,发现个UICollectionView的系统bug,关于UICollectionViewFlowLayout的
UICollectionViewFlowLayout 的 - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect 方法返回的数组中有indexpath重复的对象,解决办法见:http://stackoverflow.com/questions/12927027/uicollectionview-flowlayout-not-wrapping-cells-correctly-ios/13389461#13389461  
 
其他还有一些细节需要注意的,代码里我已经写了注释了,这里就不在说了
具体这个库怎么使用,也已经写在gitHub上了,也就不罗嗦了。
有问题欢迎留言讨论~~
 
2015-06-27更新
添加拖动排序效果,参考的https://github.com/ra1028/RACollectionViewReorderableTripletLayout 的效果。
本来以为这个效果不会太难的,结果写了写简直蛋都碎了。。。写了好几天,比我想象的复杂好多,有好多需要注意的地方,估计还有很多隐藏的bug。。。慢慢发现慢慢修复吧。
值得记录一下的是:
1,利用手势的代理方法,让两个手势协同作用。
具体就是

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer;方法和

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer方法。

加入适当的判断,就可以实现手势的协同。本例就是用这种方法让longPressGesture和panGesture协同作用实现拖动效果。

2,让scrollView自动滑动的方法
其实是利用一个定时器在需要的时候逐步设置scrollView的contentOffset,
需要注意的是:这时候pan手势的translation距离是不变的,但是view的位置却应该变。。。说起来都是泪啊!
因为设置了contentOffset,view的frame其实是应该变的,但是这时候手没动,所以pan手势的各种值都不会变,所以只能手动记录这个变化。。。

利用UICollectionViewFlowLayout的隐式动画实现UICollectionView的layout的动画调整(外加放大指定cell效果)的更多相关文章

  1. OC CollectionView和TableView自身高度的隐式递归计算,改变父试图布局

    CollectionView和TableView自身高度的隐式递归计算 1.前沿:我们一般会碰到这样的需求,一个tableview或者一个colletionview放在一个scrollview上边,而 ...

  2. Tips:取消UICollectionView的隐式动画

    http://www.cocoachina.com/ios/20151204/14211.html UICollectionView在reloadItems的时候,默认会附加一个隐式的fade动画,有 ...

  3. CALayer的隐式动画

    CALayer的使用 在我的理解中CALayer就是iOS中利用图层精简非交互式绘图.那么那些核心动画类.也就是变化图层的非交互式绘制规则而已.其中的本质就是将CALayer中的内容转化为map图.从 ...

  4. 非RootLayer的隐式动画

    非RootLayer都有隐式动画,默认0.25秒. // 1.开启 [CATransaction begin]; // 2.设置关闭 YES-关闭:NO-开启 [CATransaction setDi ...

  5. IOS第18天(3,CALayer隐式动画)

    ******隐式动画(手指拖拽Layer) #import "HMViewController.h" @interface HMViewController () @propert ...

  6. iOS:CALayer的隐式动画的详解

    CALayer的隐式动画属性: •每一个UIView内部都默认关联着一个CALayer,称这个Layer为Root Layer.所有的非Root Layer都存在着隐式动画,隐式动画的默认时长为1/4 ...

  7. IOS动画隐式,显式,翻页

    //  ViewController.m //  IOS动画0817 // //  Created by 张艳锋 on 15/8/17. //  Copyright (c) 2015年 张艳锋. Al ...

  8. iOS中的隐式动画

    隐式动画就是指  在 非 人为在代码中 定义动画  而系统却默认  自带   的动画  叫做隐式动画. 比如  改变 图层  的颜色  位置  和   透明度  的时候    都会  产生附带的渐变的 ...

  9. OC - 22.隐式动画

    简介 每个UI控件,默认自动创建一个图层(根图层),即每个UI控件对应于至少一个图层 每一个UIView内部都默认关联着一个CALayer,我们可用称这个Layer为Root Layer(根层)   ...

随机推荐

  1. scikit-learn 朴素贝叶斯类库使用小结

    之前在朴素贝叶斯算法原理小结这篇文章中,对朴素贝叶斯分类算法的原理做了一个总结.这里我们就从实战的角度来看朴素贝叶斯类库.重点讲述scikit-learn 朴素贝叶斯类库的使用要点和参数选择. 1. ...

  2. 如何为RD网关创建自建签名的证书

    创建安全的RD网关是一件非常好的事情,这样可以在公网环境下直接远程接入内部的已开启远程访问的主机服务器. 建立这个安全的RD网关需要的材料有RD网关本身,以及一个证书.由于一般情况下这些在RD网关后面 ...

  3. Callbacks vs Events

    前言:本文翻译自Dean Edwards的一篇文章,原文地址:http://dean.edwards.name/weblog/2009/03/callbacks-vs-events/. 文章主要指出了 ...

  4. 相克军_Oracle体系_随堂笔记001-概述

    一.Oracle官方支持 1.在线官方文档 http://docs.oracle.com/ 2.metalink.oracle.com,如今已经改成:http://support.oracle.com ...

  5. 从零开始,搭建博客系统MVC5+EF6搭建框架(5),博客详情页、留言、轮播图管理、右侧统计博文

    一.博客系统进度回顾 上一遍博客介绍到,系统已经实现到了发布以及前台布局展示,接下来就是实现一些,详情页,留言.轮播图管理.右侧博文统计信息实现. 二.博客系统详情页实现 2.1先来看看详情页展示的效 ...

  6. .NET正则表达式基础入门(三)

    括号 正则表达式中的括号能将多个字符或者表达式当做一组,即将他们看成一个整体.这样量词就可以修饰这一组表达式.阅读本章前,建议先下载我于CSDN上传的示例代码,下载无需分数,下载链接. 1.分组 假设 ...

  7. iOS阶段学习第35天笔记(Touch手势介绍)

    一.Touch手势 1.利用手势实现UIButton移动效果  实例代码 1) 创建一个继承自UIButton的类 MyButton.h  代码实现 #import <UIKit/UIKit.h ...

  8. CSS之深入探究Position

    这些天重新整理以前的代码,想对其进行优化,却出现了很多问题,其中一个就是Position,中间自己停下优化代码的工作,特意停下来深入研究了一下Position.现在来分享一下自己的体会吧! 首先我们从 ...

  9. jqgrid(转载)

    一.主要API接口getGridParam.setGridParam: getGridParam方法: getGridParam("url"): 获取当前的AJAX的URL get ...

  10. 突如其来的"中断异常",我(Java)该如何处理?

    一.何为异常? 1.生活中的实例 生活中存在许多不正常: 上班路上自行车掉链子 上厕所手机掉马桶 下班回家钥匙丢失 ....... 2.程序中的实例 我们的代码中也许存在许多纰漏,导致用户使用时程序突 ...