collectionViewContentSize() vs contentSize

2019-03-31 14:05发布

What is the difference between

collectionViewController.collectionViewLayout.collectionViewContentSize() and collectionViewController.collectionView.contentSize ?

What do you prefer to use?

2条回答
The star\"
2楼-- · 2019-03-31 14:45

contentSize is a property of UIScrollView, whereas collectionViewContentSize() is a method of UICollectionViewLayout.

Reading Programming iOS 7, 4th Edition, whilst summarising UICollectionViewLayout, the author states:

The layout workhorse class for a collection view. A collection view cannot exist without a layout instance! As I’ve already said, the layout knows how much room all the subviews occupy, and supplies the collectionViewContentSize that sets the contentSize of the collection view, qua scroll view.

From personal experience I encountered difficulties using layout.collectionViewContentSize(). Either the console showed the warning below, or the layouts appeared initially incorrect.

the behavior of the UICollectionViewFlowLayout is not defined because: the item height must be less than the height of the UICollectionView minus the section insets top and bottom values.

My guess is that collectionViewContentSize() does more than just return the content size. I think that invoking this actually initiates the layout calculations. If - during those calculations - anomalies are detected, then the warning shown is output.

For me testing on iPad and initiating the collection view via a Xib, the Xib's frames were iPhone sized. Initial passes triggered from viewDidLayoutSubviews were dealing with the small view. Checking the collection view's frame, it was too small. Subsequent layout engine passes eventually delivered the correct sizes, but by then the warnings had already been displayed.

Next, I tried making the Xib frame much larger. This obviated the error, but caused a worse problem; layouts were initially wrong. In scrolling, you would see the items jump around as the layout was recalculated to the correct dimensions.

Possibly the answer is to call invalidateLayout(), but I'm not sure where. I tried after instantiating the collection view and that didn't work.

So, the answer? I used contentSize. Initial passes in viewDidLayoutSubviews still show incorrect sizes but eventually come good. It doesn't generate any console warnings and better still, doesn't trigger any erroneous layout based upon the old frame size. Even better, rotation is handled automatically as viewDidLayoutSubviews will be called automatically by which point the content size will have been updated.

查看更多
在下西门庆
3楼-- · 2019-03-31 15:09

collectionViewContentSize() is a method you can override (in the layout) to generate the size dynamically.

contentSize is a property of collectionView that is going to be used if there is no such override.

It is similar to a UITableView's rowHeight vs. the UITableViewDelegate's heightForRowAtIndexPath().

Please also note (as mentioned in the comments) that "contentSize is a UIScrollView-inherited property, while itemSize is the property on UICollectionViewLayout that allows you to specify a blanket size for each cell".

查看更多
登录 后发表回答