UICollectionView高级进阶篇

By | 2015年8月30日

转载请注明出处:http://www.olinone.com/

HI,亲爱读者朋友们,又到了博客更新的时间,在经历了大半年的沉淀,目前博客日访问人次已突破400大关,最高峰达到2600人次,非常感谢各位朋友的来访,在以后的博客中争取为大家带来更多的干货。各位朋友如果有好的文章或者题材都可以推荐给我,有什么想了解的知识,都可以在下面跟我留言,或者@庞海礁的个人空间

在聊完几次理论后,今天给大家带来一篇关于UI的文章,看标题大家已经知道了,没错,就是大家所熟悉的UICollectionView。说起github上赫赫有名的卡片展示视图iCarousel,大多数iOS开发人员或多或少都有听过或使用过,其丰富的展示样式经常出现在某些APP的一级路径,其实,苹果公司针对卡片样式祭出了自己的解决方案——UICollectionView

废话少说,先上干货HJCarouselDemo

看完GIF展示的效果,各位是否已经蠢蠢欲动,这不就是iCarousel视图嘛,没错!但是今天我们采用UICollectionView实现这些效果。平常开发中,最熟悉的莫过于UICollectionViewFlowLayout,其实UICollectionViewFlowLayout相当于苹果提前定义的一个特殊UICollectionViewLayout。

先看看UICollectionViewLayout类的官方文档(好吧,原谅我半天打不开苹果网址,最近敏感期,各种和谐),还是直接看代码吧,总之,自定义UICollectionViewLayout,必须实现以下几个函数

  • collectionViewContentSize
  • layoutAttributesForElementsInRect:
  • layoutAttributesForItemAtIndexPath:
  • layoutAttributesForSupplementaryViewOfKind:atIndexPath: (if your layout supports supplementary views)
  • layoutAttributesForDecorationViewOfKind:atIndexPath: (if your layout supports decoration views)
  • shouldInvalidateLayoutForBoundsChange:

看函数名就可以知道各个函数实现的功能:第一个定位View的contentSize,第二个函数定义屏幕展示的范围和数量,第三个定义cell的布局,第四个和第五个是可选项,定义SupplementaryView以及DecorationView的布局,最后一个定义是否重新布局

UICollectionViewLayout的精髓在于你可以定义每个cell的UICollectionViewLayoutAttributes属性,包括

通过定义transform3D属性可以实现视图的旋转、放大以及透视等效果,具体实现参考HJCarouselDemo

在这里格外需要强调的一点,那就是page属性,当滑动停止时,希望UICollectionView滑动到卡片的中心,而不是任意位置

UICollectionViewLayout定义函数

  • – (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity

其中 ,proposedContentOffset为系统期望滑动到的位置,velocity为加速度,你可以通过这两个参数以及当前所在的位置计算出你希望它滑动到的位置,具体算法根据需求的不同来实现

有用过我们天天动听iOS客户端或者QQ音乐的朋友,可能都非常熟悉这个动画效果,天天动听的推荐页面以及QQ音乐的电台界面,是不是就这样,嘿嘿!重要的事说三遍,赶快下载天天动听客户端,跟我们一起摇摆起来~~~

番外篇

说完View,接下来聊聊Controller,谈什么了?谈谈它们之间的关系,最近业界对设计模式的话题讨论比较热烈,MVC、MVVM、MVP等等,不知道各位在实际开发中一般使用什么样的设计模式,有什么好的想法都可以在下面留言,下期再见!

60 thoughts on “UICollectionView高级进阶篇

  1. 匿名

    感谢分享这么好的demo,要是可以无限循环就更好了

    Reply
    1. 庞海礁 Post author

      感谢来访,以后写demo时可以考虑加上必要的注释

      Reply
  2. 匿名

    写的很好啊~要是有数组内图片无限循环就好了,另外问一下 能在storyboard中的View使用么?

    Reply
    1. 庞海礁 Post author

      这个只是collectionView的layout布局不属于试图,storyboard可以放collectionview

      Reply
      1. 大炮哥哥

        嗯,学习了,正在移植,小弟是新手,楼主大大有QQ之类的嘛~有不明白的请教下你~

        Reply
      2. 大炮哥哥

        感谢你的回复,正在移植中,但是遇到了一点问题,请问可以用QQ联系么?

        Reply
  3. 大炮哥哥

    写的很好啊,要是能无限循环数组内的图片就好了,另外问一下,可以在storyboard中的view使用吗?

    Reply
    1. 庞海礁 Post author

      很抱歉,为了用户体验,暂不考虑广告,谢谢来访!

      Reply
  4. 匿名

    如果点击第二个不会滚动到第二个,如果点击第3个第4个直接跳转到第一个 这是BUG么?
    HJCarouselAnimLinear 这个样式

    Reply
    1. 庞海礁 Post author

      是的,目前collectionview对scroll这块支持还有问题,我们只能自己定义scrollto的位置,demo里面有部分代码,但是与实际使用中的高度和宽度有关系,没法统一,只能自己调节!

      Reply
  5. Rick

    原文内容:“在这里格外需要强调的一点,那就是page属性,当滑动停止时,希望UICollectionView滑动到卡片的中心,而不是任意位置”
    这里的page感觉表达的不是很好呀。我还以为是UICollectiooViewAtrribute对象里面的属性,还认真仔细的找了找,发现没有。
    后来仔细想想感觉page的意思是要表达的UICollectionViewCell在滚动的时候停靠的处理

    Reply
    1. 庞海礁 Post author

      是的,想想系统控件貌似都没这个属性名,考虑到与page最相似,就用page了~

      Reply
    1. 庞海礁 Post author

      – (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
      函数中可以指定需要滚动到什么位置,可以自定义的

      Reply
  6. Pikdays

    不知道各位在实际开发中一般使用什么样的设计模式,有什么好的想法都可以在下面留言,下期再见!

    楼主来聊聊这个: VIPER

    Reply
  7. Pingback: 精品iOS阅读学习资料整理积累(2016年2月1日更新)-IT大道

  8. Pingback: iOS开发博客及资源 - BirdMichael

    1. 庞海礁 Post author

      其实你可以将collection的数量设置为无穷大,起始点设置为一个很大一个值模拟为无限循环的

      Reply
      1. 王宝安

        庞海礁,我这个想把活动的速度变慢,一次滑动一页,我应该怎样设置呢

        Reply
        1. 庞海礁 Post author

          如果做到每次滑动一页是很难的,毕竟滑动距离不同,不过可以修改期望滑动函数里面的终点距离

          Reply
  9. 匿名

    您好,我想了解下以下几个参数的计算依据/思想是怎样的,请教下博主:

    CGFloat delta = cY – attributesY;
    CGFloat ratio = – delta / (_itemHeight * 2);
    CGFloat scale = 1 – ABS(delta) / (_itemHeight * 6.0) * cos(ratio * M_PI_4);

    Reply
  10. HugSea

    您好,我想了解下以下几个参数的计算依据/思想是怎样的,请教下博主:

    CGFloat delta = cY – attributesY;
    CGFloat ratio = – delta / (_itemHeight * 2);
    CGFloat scale = 1 – ABS(delta) / (_itemHeight * 6.0) * cos(ratio * M_PI_4);

    Reply
    1. 庞海礁 Post author

      这个就是以中心为对齐点,计算两边的缩放比例

      Reply
    1. 庞海礁 Post author

      把数量设为最大,从中间起始位置就可以模拟循环了

      Reply
  11. 匿名

    能问下怎么设置行间距吗,找了半天没找到怎么设置啊

    Reply
        1. 庞海礁 Post author

          目前具体还没有提供接口,需要修改Layout源码,你可以看看修改centerY值

          Reply
          1. 恩,谢谢,之前试着改了下centerY的值,但是没改对,我在试试看

          2. 庞海礁 Post author

            好的,源码并不复杂,看一下还是能理解的,都是系统SDK

  12. 大神,能不能加下你qq,我通过修改centerY的值改了间距,但是模拟无限循环的时候,滑到几十张以后后面的就显示不出来了,给你留言没法发图,你帮我看一下,哪里还要改,看了好久,找不到原因啊。不修改间距就不会出现这个问题。我qq625158983

    Reply
  13. 改成功了,通过改centerY的值来改变间距的思路没太对,我是改了scale的值+了0.055就好了,再次感谢大神的demo

    Reply
  14. Pingback: 精品iOS阅读学习资料整理积累(2016年2月27日更新) – 项目经验积累与分享

  15. 匿名

    受教了 我以前都是自己手写ScrollerView来实现pageEnable的UICollecitonView

    Reply
  16. 匿名

    大神,请问一下,UICollectionViewLayout不能直接放在UICollectionView上使用吗?如果要放到UICollectionView上直接展示该怎么设置?

    Reply
  17. 匿名

    您好,请教下,使用您这种自定义的Layout布局,UIcollectionView 的 scrollToItem 方法就失效了?

    Reply

回复 匿名 取消回复

您的电子邮箱地址不会被公开。 必填项已用*标注