UICollectionViewCell的动态高度是否以编程方式使用约束?

时间:2017-10-23 21:05:13

标签: swift uicollectionview uicollectionviewcell uicollectionviewflowlayout

我从未见过如此多的答案,而不是我为集合视图单元格设置动态高度。一些解决方案具有难以想象的代码量,这进一步证明了extension UIImage { var isPortrait: Bool { return size.height > size.width } var isLandscape: Bool { return size.width > size.height } var breadth: CGFloat { return min(size.width, size.height) } var breadthSize: CGSize { return CGSize(width: breadth, height: breadth) } var breadthRect: CGRect { return CGRect(origin: .zero, size: breadthSize) } var circleMasked: UIImage? { UIGraphicsBeginImageContextWithOptions(breadthSize, false, scale) defer { UIGraphicsEndImageContext() } guard let cgImage = cgImage?.cropping(to: CGRect(origin: CGPoint( x: isLandscape ? floor((size.width - size.height) / 2) : 0, y: isPortrait ? floor((size.height - size.width) / 2) : 0), size: breadthSize)) else { return nil } UIBezierPath(ovalIn: breadthRect).addClip() UIImage(cgImage: cgImage, scale: 1, orientation: imageOrientation) .draw(in: breadthRect) return UIGraphicsGetImageFromCurrentImageContext() } // classic 'circleMasked' stackoverflow fragment // courtesy Leo Dabius /a/29047372/294884 } 是一个集群的共识,因为这可以通过UICollectionView实现而不做任何事情,因为动态单元格高度是在约束被正确链接。但我想更好地处理集合视图。这是一场噩梦。

如果没有一百行代码,如何在Swift中以编程方式(没有故事板)将集合视图单元格的高度设置为动态内容大小?

您可以将以下内容插入到空白项目中,如果您有这种倾向,它将会运行清洁。

CollectionViewFlowLayout:

UITableView

CollectionViewController

class CollectionViewFlowLayout: UICollectionViewFlowLayout {

    // inits
    override init() {
        super.init()

        config()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    // config
    func config() {
        scrollDirection = .vertical
        minimumLineSpacing = 0
        minimumInteritemSpacing = 0
    }
}

CollectionViewCell

class CollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {

    // model properties
    let colorArray: [UIColor] = [.red, .green, .blue, .yellow]
    let labelArray: [String] = [
        "sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf",
        "sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf",
        "sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf",
        "sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf sconewolf"
    ]

    // view did load
    override func viewDidLoad() {
        super.viewDidLoad()

        config()
    }

    // config
    func config() {
        collectionView?.dataSource = self
        collectionView?.delegate = self
        collectionView?.backgroundColor = UIColor.gray
        collectionView?.contentInset = UIEdgeInsets(top: -20, left: 0, bottom: 0, right: 0)
        collectionView?.alwaysBounceVertical = true
        collectionView?.alwaysBounceHorizontal = false
        collectionView?.register(CollectionViewCell.self, forCellWithReuseIdentifier: "cell1")
    }

    // data source: number of items in section
    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return colorArray.count
    }

    // data source: cell for item
    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell1", for: indexPath) as! CollectionViewCell
        cell.backgroundColor = colorArray[indexPath.item]
        cell.label.text = labelArray[indexPath.item]
        return cell
    }

    // delegate: size for item
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

        return CGSize(width: view.frame.width, height: 200)
    }
}

1 个答案:

答案 0 :(得分:0)

this帖子的帮助下,我能够以编程方式创建动态UICollectionViewCell:

设置UICollectionView布局的estimatedItemSize,如下所示:

if let flowLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
    flowLayout.estimatedItemSize = CGSize(width: 1, height: 1)
}

在UICollectionViewCell的contentView中添加您的UIControls

self.contentView.translatesAutoresizingMaskIntoConstraints = false

let screenWidth = UIScreen.main.bounds.size.width

contentView.addSubview(msgLabel)

[
    msgLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 8),
    msgLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 8),
    msgLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -8),
    msgLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -8),
    msgLabel.widthAnchor.constraint(equalToConstant: screenWidth - 16)
    ].forEach{ $0.isActive = true }
  

将UILabel的numberOfLines设置为0