Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
354 views
in Technique[技术] by (71.8m points)

ios - UICollectionViewCell dynamic height w/two dynamic labels & auto layout

I have a UICollectionViewCell subclass that's setup with a prototype cell and constraints (every view is connected both vertically and horizontally).

I have two labels that can vary in size, they can be either one or two lines. To that end I have set two height constraints on each label, one with a greater than or equal (16 or 20 depending on the label) and a less than or equal (32 or 40 depending on the label).

The number of lines on the labels are set to 0. (Though I have tried a variety of settings).

Since I've used auto layout and constraints to setup the view I've specified a width on the content view in the cell's awakeFromNib()

override func awakeFromNib() {
        NSLayoutConstraint.activate([contentView.widthAnchor.constraint(equalToConstant: 341)])
        super.awakeFromNib()
        configureBorder()
}

On the collectionView's layout I've specified the automaticDimension constant for estimateItemSize & itemSize

if let flowLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
    flowLayout.estimatedItemSize = UICollectionViewFlowLayoutAutomaticSize
    flowLayout.itemSize = UICollectionViewFlowLayoutAutomaticSize
}

With the idea of using auto layout I have not implemented a delegate on the collection view.

I am experiencing very inconsistent layout, some instances the cell's will appear as I'd like them to, in others the labels are truncated and in others the labels are extremely narrow and display text over three lines.

I have tried many things, including calling .sizeToFit() on each label after it's text property is set, as well as calling .setNeedsDisplay() before the cell returns from cellForItemAt

I'm wondering what is the right way to do this with storyboard constraints. I've worked with some of the popular answers to similar questions here on SO, though none to any real success.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
flowLayout.estimatedItemSize = UICollectionViewFlowLayoutAutomaticSize
flowLayout.itemSize = UICollectionViewFlowLayoutAutomaticSize

Of course I am familiar with Apple's repeated claims that a UICollectionViewCell in a UICollectionViewFlowLayout can be self-sizing based on internal constraints. But I have never seen working code from Apple that demonstrated this feature, and I have never once myself succeeded in confirming those claims to be true. I do not believe there is really such a thing as a self-sizing cell. For years, trying to get a cell to be self-sizing resulted in crashes. In iOS 10, the crashing mostly stopped, but now the flow layout was not laying out the cells correctly (which sounds like what you're seeing).

Naturally, I have filed bugs on all this, year after year.

Meanwhile, what I do is to give the collection view a delegate and implement collectionView(_:layout:sizeForItemAt:), and I suggest that you should do the same.


EDIT New in iOS 13 you can use a composable layout and abandon UICollectionViewFlowLayout altogether. Self-sizing cells work fine in a composable layout.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...