Using background decoration views with Compositional Layout

These can help you add a bit of visual flair or maybe imitate the inset table view style.

In another post about Compositional Layout for collection views, we will take a look at lighter topic today. And that is background decoration views. These are views can be added to layout sections.

You can provide visual separation for example between sections or imitate the inset table view style that became quite popular in iOS 14 (for example Notes app).

You can use any view as background decoration as long at it subclasses the UICollectionReusableView. This itself does not have any extra requirements. Because these views are really a decoration views, there are no configuration options. So you need to do all the setup in the init method or use .xib file to create your design.

Once you have suitable view, you can register it with compositional layout. In my example I am going to use RoundedBackgroundView which is simple view that has secondary system fill color and rounded corners.

When creating an instance of NSCollectionLayoutSection to provide section for our layout, we can use the decorationItem property to define the NSCollectionLayoutDecorationItem item with specific kind:

section.decorationItems = [
            NSCollectionLayoutDecorationItem.background(elementKind: RoundedBackgroundView.reuseIdentifier)
]

I am using extension on UICollectionReusableView which automatically provides reuseIdentifier for all these views:

extension UICollectionReusableView {
    static var reuseIdentifier: String {
        return String(describing: Self.self)
    }
}

With that done, we just need to set the actual view type on the layout.

let layout = UICollectionViewCompositionalLayout(section: section)
layout.register(RoundedBackgroundView.self, forDecorationViewOfKind: RoundedBackgroundView.reuseIdentifier)

The register method can alternatively accept an instance of UINib for decoration views created in the designer as .xib files.

And thats is! Now your section will have this specified background view.

The working example is available in my Modern Collection Views project on GitHub.

Below is the source for RoundedBackgroundView, if you just want to quickly try it:

class RoundedBackgroundView: UICollectionReusableView {

    private var insetView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.backgroundColor = .secondarySystemFill
        view.layer.cornerRadius = 15
        view.clipsToBounds = true
        return view
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)
        backgroundColor = .clear
        addSubview(insetView)

        NSLayoutConstraint.activate([
            insetView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 15),
            trailingAnchor.constraint(equalTo: insetView.trailingAnchor, constant: 15),
            insetView.topAnchor.constraint(equalTo: topAnchor),
            insetView.bottomAnchor.constraint(equalTo: bottomAnchor)
        ])
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

And here is screenshot from the example project:

Background decoration example

Uses: Xcode 12 & Swift 5.3


Follow me on Twitter for latest updates and news