UILabel SizeToFit 在 UICollectionViewCell 中不起作用

UILabel SizeToFit Not working in UICollectionViewCell

这是我的代码

        class DescriptionsViewController: UIViewController {
        
        override func viewDidLoad() {
            super.viewDidLoad()
            
            collectionView.delegate = self
            collectionView.dataSource = self
            let layout = TagFlowLayout()
            layout.estimatedItemSize = CGSize(width: 140, height: 40)
            collectionView.collectionViewLayout = layout
        }
    }

    class Row {
    var attributes = [UICollectionViewLayoutAttributes]()
    var spacing: CGFloat = 0

    init(spacing: CGFloat) {
        self.spacing = spacing
    }

    func add(attribute: UICollectionViewLayoutAttributes) {
        attributes.append(attribute)
    }

    func tagLayout(collectionViewWidth: CGFloat) {
        let padding = 10
        var offset = padding
        for attribute in attributes {
            attribute.frame.origin.x = CGFloat(offset)
            offset += Int(attribute.frame.width + spacing)
        }
    }
}

    class TagFlowLayout: UICollectionViewFlowLayout {
    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        guard let attributes = super.layoutAttributesForElements(in: rect) else {
            return nil
        }

        var rows = [Row]()
        var currentRowY: CGFloat = -1

        for attribute in attributes {
            if currentRowY != attribute.frame.origin.y {
                currentRowY = attribute.frame.origin.y
                rows.append(Row(spacing: 10))
            }
            rows.last?.add(attribute: attribute)
        }

        rows.forEach {
            [=10=].tagLayout(collectionViewWidth: collectionView?.frame.width ?? 0)
        }
        return rows.flatMap { [=10=].attributes }
    }
}

    extension DescriptionsViewController : UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return sourse.Ingredients.count
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionViewCell",for: indexPath) as? collectionViewCell else {
            
            return collectionViewCell()
        }
        
        cell.label.text = sourse.Ingredients[indexPath.row] //[indexPath.section]
        cell.label.preferredMaxLayoutWidth = collectionView.frame.width - 16
        cell.label.sizeToFit()
            
        return cell
    }
    
} // uicollectionViewDatasourse,UICollectionViewDelegate

    class collectionViewCell: UICollectionViewCell{
    
    @IBOutlet weak var label: UILabel!
    
    override func awakeFromNib() {
        super.awakeFromNib()
        
        self.layer.cornerRadius = label.frame.size.height / 2.0
        self.backgroundColor = #colorLiteral(red: 0.3647058904, green: 0.06666667014, blue: 0.9686274529, alpha: 1)
    }
} //UICollectionViewCell

文字会超出背景色且背景色无法适配文字长度

问题存在于您的 Xib 约束中。当您的标签无法获得正确的框架时,sizeToFit 将不起作用。

如果你想让标签适应你的文本长度,你可以试试。

  • Snapkit
view.contentView.addSubview(label)
label.snp.makeConstraints {
 [=10=].centerY.equalToSuperview()
 [=10=].leading.trailing.equalToSuperview().inset(customOffset)
}
  • 西布
Juset set the same constraints, ___centeY, leading, trailing___, as by SnapKit(I am not familiar how to in Xib, so sorry about no cases)
  • 原代码

这可能有帮助

class tageCollectionViewCell: UICollectionViewCell{
    
    var label: UILabel!
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupView()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func setupView() {
        label = UILabel()
        //... add your custom character
        contentView.addSubview(label)
        label.translatesAutoresizingMaskIntoConstraints = false
        let constraints = [
            label.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
            label.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
            label.trailingAnchor.constraint(equalTo: contentView.trailingAnchor)
        ]
        NSLayoutConstraint.activate(constraints)
    }
}

我添加了一些代码并回答了我的问题。

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: sourse.Ingredients[indexPath.item].size(withAttributes: [NSAttributedString.Key.font : UIFont.systemFont(ofSize: 17)]).width + 25, height: 30)
}

但我认为这不是最佳答案,因为这个源代码可以检测他们只是添加 .width + 25

显然这段代码不是“动态的”,但它确实有效。