Modern Collection Views and Readable Content Guide

Is there a way to opt into readable content guide for modern collection views on iOS 14 with the new list and cell configurations? I can inject the correct values in via the content directionalLayoutMargin but the accessory view still floats out at the edge of the superview.

Accepted Reply

If you want to inset your cells to the readable content width, you can use the contentInsetsReference API on UICollectionViewCompositionalLayoutConfiguration (to set a default value for the entire layout) or NSCollectionLayoutSection (to control the value per-section) to do this.

For list layouts (using UICollectionLayoutListConfiguration), you need to set both the contentInsetsReference and contentInsets on NSCollectionLayoutSection, because list sections do not use a default contentInsetsReference value of .automatic (meaning they won't inherit the value from the UICollectionViewCompositionalLayoutConfiguration) and they also may have nonzero default leading & trailing contentInsets which you probably want to remove.

Here is an example of how to do this using the NSCollectionLayoutSection API:

let layout = UICollectionViewCompositionalLayout { sectionIndex, layoutEnvironment in
    // Create the layout section using a list configuration.
    let listConfig = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
    var section = NSCollectionLayoutSection.list(using: listConfig, layoutEnvironment: layoutEnvironment)
    
    // Change the section's content insets reference to the readable content.
    // This changes the way that the insets in the section's contentInsets property are interpreted.
    section.contentInsetsReference = .readableContent
    
    // Zero out the default leading/trailing contentInsets, but preserve the default top/bottom values.
    // This ensures each section will be inset horizontally exactly to the readable content width.
    var contentInsets = section.contentInsets
    contentInsets.leading = 0
    contentInsets.trailing = 0
    section.contentInsets = contentInsets
    
    return section
}
  • This is awesome - thank you!

  • When the list is embedded in a UINavigationController, the navigationBar seems to adjust itself to the set appearance, regarding the margins it uses. This is especially visible when using .sidebar or .sidebarPlain. When adjusting the contentInset of the list, is there anything we can do to also adjust the margins of the navigationBar?

Add a Comment

Replies

If you want to inset your cells to the readable content width, you can use the contentInsetsReference API on UICollectionViewCompositionalLayoutConfiguration (to set a default value for the entire layout) or NSCollectionLayoutSection (to control the value per-section) to do this.

For list layouts (using UICollectionLayoutListConfiguration), you need to set both the contentInsetsReference and contentInsets on NSCollectionLayoutSection, because list sections do not use a default contentInsetsReference value of .automatic (meaning they won't inherit the value from the UICollectionViewCompositionalLayoutConfiguration) and they also may have nonzero default leading & trailing contentInsets which you probably want to remove.

Here is an example of how to do this using the NSCollectionLayoutSection API:

let layout = UICollectionViewCompositionalLayout { sectionIndex, layoutEnvironment in
    // Create the layout section using a list configuration.
    let listConfig = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
    var section = NSCollectionLayoutSection.list(using: listConfig, layoutEnvironment: layoutEnvironment)
    
    // Change the section's content insets reference to the readable content.
    // This changes the way that the insets in the section's contentInsets property are interpreted.
    section.contentInsetsReference = .readableContent
    
    // Zero out the default leading/trailing contentInsets, but preserve the default top/bottom values.
    // This ensures each section will be inset horizontally exactly to the readable content width.
    var contentInsets = section.contentInsets
    contentInsets.leading = 0
    contentInsets.trailing = 0
    section.contentInsets = contentInsets
    
    return section
}
  • This is awesome - thank you!

  • When the list is embedded in a UINavigationController, the navigationBar seems to adjust itself to the set appearance, regarding the margins it uses. This is especially visible when using .sidebar or .sidebarPlain. When adjusting the contentInset of the list, is there anything we can do to also adjust the margins of the navigationBar?

Add a Comment

In your content view. Set AutoLayout to readable layout guide and make sure call:

preservesSuperviewLayoutMargins = true