【问题标题】:How to get all UICollectionViewCells to share the same height?如何让所有集合视图单元格共享相同的高度?
【发布时间】:2021-05-26 22:42:31
【问题描述】:

我有一个 UICollectionView,其中 Cell 没有填充它们的垂直空间。我应该进行哪些调整以确保每个单元格填满整个单元格区域?或者至少它们所在行的高度相同?

这里是故事板

UICollectionViewFlowLayout

class AddServiceFlowLayout: UICollectionViewFlowLayout {
    let cellsPerRow: Int
    
    init(cellsPerRow: Int, minimumInteritemSpacing: CGFloat = 0, minimumLineSpacing: CGFloat = 0, sectionInset: UIEdgeInsets = .zero) {
        self.cellsPerRow = cellsPerRow
        super.init()
        
        self.minimumInteritemSpacing = minimumInteritemSpacing
        self.minimumLineSpacing = minimumLineSpacing
        self.sectionInset = sectionInset
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func prepare() {
        super.prepare()
        
        guard let collectionView = collectionView else { return }
        let marginsAndInsets = sectionInset.left + sectionInset.right + collectionView.safeAreaInsets.left + collectionView.safeAreaInsets.right + minimumInteritemSpacing * CGFloat(cellsPerRow - 1)
        let itemWidth = ((collectionView.bounds.size.width - marginsAndInsets) / CGFloat(cellsPerRow)).rounded(.down)
        itemSize = CGSize(width: itemWidth, height: itemWidth)
    }
    
    override func invalidationContext(forBoundsChange newBounds: CGRect) -> UICollectionViewLayoutInvalidationContext {
        let context = super.invalidationContext(forBoundsChange: newBounds) as! UICollectionViewFlowLayoutInvalidationContext
        context.invalidateFlowLayoutDelegateMetrics = newBounds.size != collectionView?.bounds.size
        return context
    }
    
}

UICollectionViewCell

class AddServiceViewCell: UICollectionViewCell {

    @IBOutlet weak var labelStackView: UIStackView!
    @IBOutlet weak var tvServiceName: UILabel!
    @IBOutlet weak var tvQuantityNeeded: UILabel!
    
    public var onCellTapped: (() -> ())?

    override func awakeFromNib() {
        super.awakeFromNib()
        self.layer.cornerRadius = 10.0
    }

    override func prepareForReuse() {
        super.prepareForReuse()
        self.tvServiceName.text = nil
        self.tvQuantityNeeded.show()
    }
    
    public static func nib() -> UINib {
        return UINib.init(nibName: identifier, bundle: Bundle(for: ServiceLineItemCell.self))
    }
    
    public func configure(with service: TowService){
        self.tvServiceName.text = service.description
        
        if(service.calculated){
            self.tvQuantityNeeded.hide()
        }
    }
    
    public func eventTriggered()
    {
        onCellTapped?()
    }

}

UIViewController

class AddServiceViewController: UIViewController {
    
    @IBOutlet weak var collectionView: UICollectionView!
    
    private let columnLayout = AddServiceFlowLayout(
        cellsPerRow: 3,
        minimumInteritemSpacing: 10,
        minimumLineSpacing: 10,
        sectionInset: UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
    )
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.title = "Add Service"
        
        // Register cell classes
        self.collectionView!.delegate = self
        self.collectionView!.dataSource = self
        self.collectionView!.collectionViewLayout = columnLayout
        self.collectionView!.contentInsetAdjustmentBehavior = .always
        self.collectionView!.register(AddServiceViewCell.nib().self, forCellWithReuseIdentifier: AddServiceViewCell.identifier)

        
    }

// removed for brevity ....

// MARK: UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout
extension AddServiceViewController : UICollectionViewDelegateFlowLayout, UICollectionViewDelegate, UICollectionViewDataSource {
    
    
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return allServices.count
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: AddServiceViewCell.identifier, for: indexPath) as! AddServiceViewCell
        cell.configure(with: allServices[indexPath.row])
        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        self.onConfirmAdd(allServices[indexPath.row])
    }
}

【问题讨论】:

  • 您是否尝试过使用 'collectionView sizeForItemAt' 设置每个单元格的大小?

标签: ios swift storyboard


【解决方案1】:

这是路线图

1- 你需要实现sizeForItemAt

2- 假设您每行有 3 列,创建一个函数,从您的模型中接受 3 个项目(与当前 indexPath.item 一起引入)并手动计算该模型中每个字符串的最大高度

3- 返回最大高度,这样您将为同一行的所有单元格设置该高度

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-10
    • 2021-12-14
    • 1970-01-01
    • 2018-12-23
    相关资源
    最近更新 更多