【问题标题】:iOS - implementing custom collection view layoutiOS - 实现自定义集合视图布局
【发布时间】:2020-08-18 13:46:23
【问题描述】:

我有一个工作的默认集合视图流布局,但我试图让我的单元格左对齐(不是默认的中心拉伸)。我从this post 得到了一些很好的答案。它说我需要使用自定义布局。但是你如何实现自定义布局呢?我创建了一个文件,它已准备就绪,但如何使用 Collection View 将它连接到 VC?

这是我的 Collection View 的 VC 中的内容: 为顶部的布局创建了一个出口

@IBOutlet weak var tagsLayout: TagsLayout!

我当前在底部默认流布局的实现:

extension ItemViewController: UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        
        let text = allTags[indexPath.row]
        let font: UIFont = UIFont(name: "Baskerville", size: 15) ??  UIFont.systemFont(ofSize: 17.0) // set here font name and font size
        let width = text.SizeOf(font).width
        return CGSize(width: width + 20.0 , height: 30.0) // ADD width + space between text (for ex : 20.0)
        }
//
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt: Int) -> CGFloat {

        return 4.0
    }

}

我在 viewdidload 中看到这可能是必要的,但 .delegate 无法识别/不在我的自定义布局中

        if let layout = self.collectionView.collectionViewLayout as? TagsLayout
        {
            layout.delegate = self
        }

标签布局:

import UIKit

class TagsLayout: UICollectionViewFlowLayout {
    
    
    
    required override init() {super.init(); common()}
    required init?(coder aDecoder: NSCoder) {super.init(coder: aDecoder); common()}
    
    private func common() {
        estimatedItemSize = UICollectionViewFlowLayout.automaticSize
        minimumLineSpacing = 10
        minimumInteritemSpacing = 10
    }
    
    override func layoutAttributesForElements(
                    in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        
        guard let att = super.layoutAttributesForElements(in:rect) else {return []}
        var x: CGFloat = sectionInset.left
        var y: CGFloat = -1.0
        
        for a in att {
            if a.representedElementCategory != .cell { continue }
            
            if a.frame.origin.y >= y { x = sectionInset.left }
            a.frame.origin.x = x
            x += a.frame.width + minimumInteritemSpacing
            y = a.frame.maxY
        }
        return att
    }
}

【问题讨论】:

    标签: ios swift uicollectionviewlayout collectionview


    【解决方案1】:

    只需在ItemViewControllerviewDidLoad方法中将collectionViewdelegate设置为self即可。

    class ItemViewController: UIViewController {
    
        @IBOutlet weak var tagsLayout: TagsLayout!
        @IBOutlet weak var collectionView: UICollectionView!
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            collectionView.collectionViewLayout = tagsLayout
            collectionView.delegate = self
        }
    }
    

    那么你可以通过简单的验证:

    extension ItemViewController: UICollectionViewDelegateFlowLayout {
    
        func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
            print("Now it getting called... :)")
            //...
        }
    }
    

    【讨论】:

    • 刚刚在您发送之前更新了我的帖子,说我有,但.delegate 未被识别/不是我的自定义布局的一部分。该委托方法在自定义布局类中的外观如何?谢谢
    • TagsLayout 继承自什么?将TagsLayout 代码添加到您的问题中。
    • UICollectionViewFlowLayout 已添加。
    • 好的,那么您在哪里将此布局分配给collectionView?我刚刚更新了上面的代码。您必须将collectionViewdelegate 设置为self。我已经添加了代码来将布局设置为上面的collectionView
    • 这是我的问题,哈哈。不知道该怎么做。我在 IB 中设置了自定义布局并将其连接到我发布的插座。
    猜你喜欢
    • 1970-01-01
    • 2017-05-22
    • 1970-01-01
    • 2015-06-12
    • 1970-01-01
    • 2016-07-09
    • 1970-01-01
    • 2014-11-13
    • 1970-01-01
    相关资源
    最近更新 更多