UICollectionViewCell Auto Sizing(自适应高度)

cel.gif

研究了下UICollectionViewCell在自适应高度方面的资料,发现大部分都是得去重写preferredLayoutAttributesFitting方法,给我的感觉不是很符合像UITableViewCell自适应高度的那种思维,后来又了解了UIScrollView里面放着多个Label用AutoLayout去约束时候,要使用一个UIView去作为容器,所以,我在自定义UICollectionViewCell里面放多一个UIView,作为容器,代码的风格就显得比较符合UITableViewCell自适应高度的思维。

创建AutoSizingCollectionViewCell


import UIKit

class AutoSizingCollectionViewCell: UICollectionViewCell {
    
    var text :String? {
        didSet {
            textLabel.text = text
        }
    }
    
    private lazy var containerView = UIView()
    
    private lazy var textLabel = UILabel()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        globalSetup()
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        globalSetup()
    }
    
    private func globalSetup() {
        setupContainerView()
        setupContentLabel()
    }
    
    private func setupContainerView() {
        contentView.addSubview(containerView)
        containerView.translatesAutoresizingMaskIntoConstraints = false
        containerView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true
        containerView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true
        containerView.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
        containerView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
        containerView.heightAnchor.constraint(greaterThanOrEqualToConstant: 95.0).isActive = true
        containerView.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.size.width).isActive = true
    }
    
    private func setupContentLabel() {
        textLabel.numberOfLines = 0
        containerView.addSubview(textLabel)
        textLabel.translatesAutoresizingMaskIntoConstraints = false
        textLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 15.0).isActive = true
        textLabel.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -15.0).isActive = true
        textLabel.topAnchor.constraint(equalTo: containerView.topAnchor, constant: 10.0).isActive = true
        textLabel.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -10.0).isActive = true
    }
}

使用

//
//  ViewController.swift
//  UICollectionViewDemo
//
//  Created by grwong on 2018/4/27.
//  Copyright © 2018年 grwong. All rights reserved.
//

import UIKit

class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
    
    private lazy var layout: UICollectionViewFlowLayout = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .vertical
        layout.minimumLineSpacing = 0
        layout.estimatedItemSize = CGSize(width: UIScreen.main.bounds.size.width, height: 95.0)
        layout.itemSize = UICollectionViewFlowLayoutAutomaticSize
        return layout
    }()
    
    private lazy var colletionView = UICollectionView(frame:CGRect.zero, collectionViewLayout: layout)
    
    private lazy var resourceData = [
                            "Do any additional setup after loading the view, typically from a nib.",
                             "Do any additional setup after loading the view, typically from a nib.Do any additional setup after loading the view, typically from a nib.Do any additional setup after loading the view, typically from a nib.",
                             "Do any additional setup after loading the view, typically from a nib.Do any additional setup after loading the view, typically from a nib.Do any additional setup after loading the view, typically from a nib.Do any additional setup after loading the view, typically from a nib.Do any additional setup after loading the view, typically from a nib.Do any additional setup after loading the view, typically from a nib.",
                             "Do any additional setup after loading the view, typically from a nib.Do any additional setup after loading the view, typically from a nib.Do any additional setup after loading the view, typically from a nib.Do any additional setup after loading the view, typically from a nib.",
                             "Do any additional setup after loading the view, typically from a nib.Do any additional setup after loading the view, typically from a nib.Do any additional setup after loading the view, typically from a nib.",
                             "Do any additional setup after loading the view, typically from a nib.Do any additional setup after loading the view, typically from a nib.Do any additional setup after loading the view, typically from a nib.Do any additional setup after loading the view, typically from a nib.Do any additional setup after loading the view, typically from a nib.Do any additional setup after loading the view, typically from a nib."]

    override func loadView() {
        view = colletionView
        view.backgroundColor = .white
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        colletionView.dataSource = self
        colletionView.delegate = self
        colletionView.register(AutoSizingCollectionViewCell.self, forCellWithReuseIdentifier: "AutoSizingCollectionViewCell")
    }

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return resourceData.count
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "AutoSizingCollectionViewCell", for: indexPath) as? AutoSizingCollectionViewCell else { fatalError("Can't convert this cell") }
        cell.text = resourceData[indexPath.item]
        cell.backgroundColor = indexPath.row % 2 == 0 ? .orange : .yellow
        return cell
    }
}


Tips

要注意的点在于UICollectionViewFlowLayout里面的 estimatedItemSize 和 itemSize


image.png

如果报这样的约束错误,是因为ItemSize的宽跟cell实际宽度不一样


image.png
因为Cell会被容器的view撑大,所以需要这行被注释掉的代码
image.png
预估的sizewidth需要跟约束的width一样大
image.png

你可能感兴趣的:(UICollectionViewCell Auto Sizing(自适应高度))