将自定义布局类连接到代码中的集合视图

时间:2018-08-23 15:20:11

标签: ios swift uicollectionview

我对自定义布局类有一个小问题,我需要通过代码而不是故事板将其连接到我的收藏夹视图,因为我是通过代码创建整个项目的。有任何帮助吗?

我的主班

import UIKit
import Firebase
class UserProfileController: UICollectionViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        collectionView?.backgroundColor = .white
        //fetchUser()
        collectionView?.dataSource = self
        collectionView?.delegate = self
        collectionView?.register(TestCell.self, forCellWithReuseIdentifier: mainCellId)    
    }


    fileprivate let mainCellId = "mainCellId"
    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: mainCellId, for: indexPath) as! TestCell

        return cell
    }

    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 15
    }
    override func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }
}

需要通过代码而不是故事板将其连接到集合视图的自定义布局类

import UIKit

struct UltraVisualLayoutConstants {
    struct Cell {
        static let standardHeight: CGFloat = 100
        static let featuredHeight: CGFloat = 280
//        static let standardWidth: CGFloat = 100
//        static let featuredWidth: CGFloat = 280
    }
}

class UltraVisualLayout: UICollectionViewLayout {
    //  amount which users need to scroll before featured cell changes\
    let dragOffset: CGFloat = 180.0
    var cache = [UICollectionViewLayoutAttributes]()
    //return item index of current featured cell
    var featuredItemIndex: Int {
        get {
            //use max to ensure that featureditemindex never be < 0
            return max(0 , Int(collectionView!.contentOffset.y / dragOffset))
        }
    }

    // returns value between 0 and 1 to represent how close the next cell becomes the featured cell
    var nextItemPercentegeOffset: CGFloat {
        get {
            return (collectionView!.contentOffset.y / dragOffset) - CGFloat(featuredItemIndex)
        }
    }    
    // return the width of collection view
    var width: CGFloat {
        get {

            guard let width = collectionView?.bounds.width else {return 0}
            return width
        }
    }
    // return the height of collection view
    var height: CGFloat {
        get {
            guard let height = collectionView?.bounds.height else {return 0}
            return height
        }
    }
    //returns the number of items in the collection view
    var numberOfItems: Int {
        get {
            return collectionView!.numberOfItems(inSection: 0)
        }
    }

    // MARK: UICollectionViewLayout
    // return the size of all content in collection view
     override var collectionViewContentSize: CGSize {
   let contentHeight = (CGFloat(numberOfItems) * dragOffset) + (height - dragOffset)
    return CGSize(width: width, height: contentHeight)
}
    override func prepare() {
        cache.removeAll(keepingCapacity: false)

        let standardHeight = UltraVisualLayoutConstants.Cell.standardHeight
        let featuredHeight = UltraVisualLayoutConstants.Cell.featuredHeight
        var frame = CGRect(x: 0, y: 0, width: 0, height: 0)
        var y: CGFloat = 0
        for item in 0..<numberOfItems {
            let indexPath = NSIndexPath(item: item, section: 0)
            let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath as IndexPath)
            attributes.zIndex = item
            var height = standardHeight
            if indexPath.item == featuredItemIndex {
                let yOffset = standardHeight * nextItemPercentegeOffset
                y = collectionView!.contentOffset.y - yOffset
                height = featuredHeight
            } else if indexPath.item == (featuredItemIndex + 1) && indexPath.item != numberOfItems {
                let maxY = y + standardHeight
                height = standardHeight + max((featuredHeight - standardHeight) * nextItemPercentegeOffset, 0)
                y = maxY - height
            }
         frame = CGRect(x: 0, y: y, width: width, height: height)
            attributes.frame = frame
            cache.append(attributes)
            y = frame.maxY
        }

    }

    // return all attributes in cache whose frame intersects with the rect passed to the method
    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        var layoutAttributes = [UICollectionViewLayoutAttributes]()
        for attributes in cache {
            if attributes.frame.intersects(rect) {
                layoutAttributes.append(attributes)
            }
        }
        return layoutAttributes
    }

    // return true so that layout is continuously invalidated as the user scrolls
    override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
        return true 
    }

1 个答案:

答案 0 :(得分:1)

如果您没有初始化器,则不能以编程方式设置布局。来自docs

  

布局

     

用于组织项目的布局对象。集合   视图存储对指定对象的强引用。 一定不能   无

由于您似乎正在使用故事板,因此必须在此处进行设置。

enter image description here

在代码中创建布局类后,单击情节提要上的集合视图时,它将显示出来。 默认布局将设置为,当您将其更改为自定义时,将显示一个新的班级字段。当您单击它时,它将列出您的布局类。您可以选择它并从那里进行设置。

但是,如果您以编程方式初始化情节提要,则只需要将其作为参数传递给初始化程序即可。

var collectionView = UICollectionView(frame: yourFrame, collectionViewLayout: customCollectionViewLayout)    // pass your custom collection view instance