2

I have a nested collectionView which I would like to get the readableContentGuide for after rotation in order to set the content inset correctly.

This is what it looks like:

enter image description here

I have already tried to subclass the collection view and get the value from layoutMarginsDidChange, traitCollectionDidChange, and layoutSubviews.

However the value I get there is always the previous value (i.e when I'm in portrait I get the landscape value and vice versa)

I have also tried to set the inset in the collectionView's collectionView(_:layout:insetForSectionAt:).

Currently, the only solution that seems to work is observing the bounds of the collection view, but that feels a bit hacky.

Any thoughts on how this can be done?

MrHaze
  • 3,406
  • 3
  • 24
  • 45

1 Answers1

2

If you are using Autolayout on storyboard you should activate "Follow Readable Width" option for the superview. First, make sure that the collection view is attached to the superview's margins. Then go to the superview and open Size Inspector, and select the option:
Follow Readable Width
Thanks matt for the answer.

For programmatic Autolayout you don't need margins, just attach the collection view to the readableContentGuide of the superview. Like this:

let cv = collectionView

// Guide of the superview
let readableGuide = view.readableContentGuide 

NSLayoutConstraint.activateConstraints([
    cv.topAnchor.constraintEqualToAnchor(readableGuide.topAnchor),
    cv.bottomAnchor.constraintEqualToAnchor(readableGuide.bottomAnchor),
    cv.rightAnchor.constraintEqualToAnchor(readableGuide.rightAnchor),
    cv.leftAnchor.constraintEqualToAnchor(readableGuide.leftAnchor)
])

If you prefer frame-based programmatic layout you don't need to use layoutMarginsDidChange, traitCollectionDidChange of the superview, neither observe bounds. The best place for layout code is viewWillLayoutSubviews() func of the controller. This will handle any bounds changes including interface rotations.

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()

    collectionView.frame = view.readableContentGuide.layoutFrame

    collectionView.collectionViewLayout.invalidateLayout()
}

Here I explain why we need to invalidateLayout().

kelin
  • 9,553
  • 6
  • 63
  • 92