zoukankan      html  css  js  c++  java
  • iOS 关于自定义UICollectionViewLayout实现复杂布局

    UICollectionView的简单介绍

    UICollectionView的结构

    Cells
    Supplementary Views 追加视图 (类似Header或者Footer)
    Decoration Views 装饰视图 (用作背景展示)

    由两个方面对UICollectionView进行支持

    和tableView一样,即提供数据的UICollectionViewDataSource以及处理用户交互的UICollectionViewDelegate。

    另一方面 对于cell的样式和组织方式,由于collectionView比tableView要复杂得多,因此没有按照类似于tableView的style的方式来定义,而是专门使用了一个类来对collectionView的布局和行为进行描述,这就是UICollectionViewLayout

    而我们主要讲UICollectionViewLayout,因为这不仅是collectionView和tableView的最重要求的区别,也是整个UICollectionView的精髓所在

    UICollectionViewLayoutAttributes类的介绍

    一个UICollectionViewLayoutAttributes对象管理着一个Collection View中给定的一个Item的布局有关的属性。当被CollectionView要求时布局对象创建这个类的实例。

    open class UICollectionViewLayoutAttributes : NSObject, NSCopying, UIDynamicItem {
    
        
        open var frame: CGRect item的位置
    
        open var center: CGPoint item的中心点 这个中心点是在给定的Collection View坐标系中的点。设置这个属性的值也会更新frame属性中的origin的值。
    
        open var size: CGSize item的大小
    
        open var transform3D: CATransform3D item的放射变化 使用你指定的放射变换赋值给这个属性替换transform3D属性的值
    
        @available(iOS 7.0, *)
        open var bounds: CGRect
    
        @available(iOS 7.0, *)
        open var transform: CGAffineTransform item在平面上的变化
    
        open var alpha: CGFloat item的透明度 0 - 1
    
        open var zIndex: Int // default is 0 item指定在Z轴上的位置 这个属性被用来确定在布局时Item的前后顺序。大的zIndex值的Item会被显示在小的zIndex值的Item上面。这个属性使用相同的值的Item的顺序是不确定的。
      这个属性的值默认为0
    open var isHidden: Bool // As an optimization, UICollectionView might not create a view for items whose hidden attribute is YES open var indexPath: IndexPath Collection ViewItem的索引值。
      索引包含了一个Section的索引和一个Item在这个Section中的索引。这两个值标示在Collection View唯一的对应的Item的位置。 open var representedElementCategory: UICollectionElementCategory {
    get } Item的类型。
      你可以使用这个属性的值来区分这个布局属性是用于一个Cell还是Supplementary View还是Decoration View。 open var representedElementKind: String
    ? { get } // nil when representedElementCategory is UICollectionElementCategoryCell
        目标视图的布局指定标识符。
        你可以使用这个属性的值来标识Supplementary View或者Decoration View相关联的属性给定的目的。如果representedElementCategory属性为UICollectionElementCategoryCell,那么这个    属性为nil
    }
    typedef NS_ENUM(NSUInteger, UICollectionElementCategory) {
        UICollectionElementCategoryCell, // Cell
        UICollectionElementCategorySupplementaryView, // Supplementary View
        UICollectionElementCategoryDecorationView // Decoration View
    };

    自定义UICollectionViewLayout

    UICollectionViewLayout的功能是向UICollectionView提供布局信息 不仅包括cell的布局信息,也包括追加视图和装饰视图的布局信息。实现一个自定义layout的常规做法是继承UICollectionViewLayout类,然后重载下列方法:

    准备方法被自动调用 以保证layout实例的正确 为即将进行的layout作前期的计算

    open func prepare()

    返回指定区域中的Cell和View的属性

    返回的是包含UICollectionViewLayoutAttributes的数组  UICollectionViewLayoutAttributes可以是数组 追加视图(头尾视图)的信息

    func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]?
    返回对应于indexPath的位置的cell的布局属性
    func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes?
    返回对应于indexPath的位置的追加视图的布局属性,如果没有追加视图可不重载
    创建并返回一个表示给定索引值对应的Supplementary View的布局属性对象。
    使用这个方法为Collection View中的一个Supplementary View创建一个布局属性对象。和Cell一样,Supplementary View当前的数据是被Collection View数据源所管理的。但是和Cell不同的是,Supplementary View通常是为特殊目的而设计的。例如,HeaderFooterCell的放置位置不同,是提供给在单个的Section或者整个Collection View的。
    由你来决定如何使用indexPath参数来识别一个给定的Supplementary View。通常,你使用elementKind属性来确定Supplementary View的类型,然后使用indexPath的信息来识别不同Supplementary View实例。
    func layoutAttributesForSupplementaryView(ofKind elementKind: String, at indexPath: IndexPath) -> UICollectionViewLayoutAttributes?
    创建并返回一个表示给定索引值对应的Decoration View的布局属性对象。
    使用这个方法为Collection View中的一个Decoration View创建一个布局属性对象。Decoration ViewSupplementary View的一种,但是不会展示被Collection View数据源所管理的数据。相反,它们大多数为一个Section或者整个Collection View呈现视觉装饰效果。
    由你来决定如何使用indexPath参数来识别一个给定的Decoration View。通常,你使用decorationViewKind属性来确定Decoration View的类型,然后使用indexPath的信息来识别不同Decoration View实例。
    func layoutAttributesForDecorationView(ofKind elementKind: String, at indexPath: IndexPath) -> UICollectionViewLayoutAttributes?

    当边界发生改变的时候 是否应该刷新布局 如果YES则在边界变化(一般是scroll到其他地方)时,将重新计算需要的布局信息。

    func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool

    方法的调用顺序

    1)-(void)prepareLayout  设置layout的结构和初始需要的参数等。
    
    2)  -(CGSize) collectionViewContentSize 确定collectionView的所有内容的尺寸。
    
    3)-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect初始的layout的外观将由该方法返回的UICollectionViewLayoutAttributes来决定。
    
    4)在需要更新layout时,需要给当前layout发送 
         1)-invalidateLayout, 该消息会立即返回,并且预约在下一个loop的时候刷新当前layout
         2)-prepareLayout,
         3)依次再调用-collectionViewContentSize和-layoutAttributesForElementsInRect来生成更新后的布局。
  • 相关阅读:
    Atitit  atiMail atiDns新特性 v2  q39
    Atitit  atiMail atiDns新特性 v2  q39
    Atitit.aticmd v4  新特性q39 添加定时器释放功能
    Atitit.aticmd v4  新特性q39 添加定时器释放功能
    Atitit. Atiposter 发帖机 新特性 poster new feature   v7 q39
    Atitit. Atiposter 发帖机 新特性 poster new feature   v7 q39
    Atitit.编程语言and 自然语言的比较and 编程语言未来的发展
    Atitit.编程语言and 自然语言的比较and 编程语言未来的发展
    atitit.解决struts2 SpringObjectFactory.getClassInstance NullPointerException  v2 q31
    知也atitit.解决struts2 SpringObjectFactory.getClassInstance NullPointerException  v2 q31无涯 - I
  • 原文地址:https://www.cnblogs.com/huanying2000/p/8515272.html
Copyright © 2011-2022 走看看