'UILabel SizeToFit Not working in UICollectionViewCell
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


The text will beyond the background color and the background color can't adaptation the text length
Solution 1:[1]
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.
Solution 2:[2]
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.leadingAnchor),
label.trailingAnchor.constraint(equalTo: contentView.trailingAnchor)
]
NSLayoutConstraint.activate(constraints)
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | ouflak |
| Solution 2 |
