Home > other >  UILabel SizeToFit Not working in UICollectionViewCell
UILabel SizeToFit Not working in UICollectionViewCell

Time:03-17

This is my code

        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 {
            $0.tagLayout(collectionViewWidth: collectionView?.frame.width ?? 0)
        }
        return rows.flatMap { $0.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

I want to show like this image but I get like this one

The text will beyond the background color and the background color can't adaptation the text length

CodePudding user response:

The problem exisit in your Xib constraints. When your label cannot get the right frame, sizeToFit will not work.

If you want the label adapt to your text length, you can try.

  • Snapkit
view.contentView.addSubview(label)
label.snp.makeConstraints {
 $0.centerY.equalToSuperview()
 $0.leading.trailing.equalToSuperview().inset(customOffset)
}
  • Xib
Juset set the same constraints, ___centeY, leading, trailing___, as by SnapKit(I am not familiar how to in Xib, so sorry about no cases)
  • Original Code

this may help

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.trailingAnchor),
            label.trailingAnchor.constraint(equalTo: contentView.leadingAnchor)
        ]
        NSLayoutConstraint.activate(constraints)
    }
}

CodePudding user response:

I added some code and answered my question.

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)
}

But I think it's not best answer because this source code can detection they just add .width 25.

Obviously this code is not "dynamic", but it does work.

  • Related