如何在具有组合布局的新集合视图中将 CAGradientLayer 添加到 UIBackgroundConfiguration?

How do you add a CAGradientLayer to a UIBackgroundConfiguration in the new collection views with compositional layouts?

我想在具有组合布局的新集合视图的上下文中为集合视图单元格的背景添加渐变。下面是如何根据 Apple 示例代码 Implementing Modern Collection ViewsEmojiExplorerViewController 的第 180 行配置单元格背景的示例:

func configuredGridCell() -> UICollectionView.CellRegistration<UICollectionViewCell, Emoji> {
    return UICollectionView.CellRegistration<UICollectionViewCell, Emoji> { (cell, indexPath, emoji) in
        var content = UIListContentConfiguration.cell()
        content.text = emoji.text
        content.textProperties.font = .boldSystemFont(ofSize: 38)
        content.textProperties.alignment = .center
        content.directionalLayoutMargins = .zero
        cell.contentConfiguration = content
        var background = UIBackgroundConfiguration.listPlainCell()
        background.cornerRadius = 8
        background.strokeColor = .systemGray3
        background.strokeWidth = 1.0 / cell.traitCollection.displayScale
        cell.backgroundConfiguration = background
    }
}

由于新的 UIBackgroundConfiguration 是一个结构而不是层支持的 UIView 子类,我不能只添加一个 CAGradientLayer 实例作为子层。

向单元格背景配置添加渐变的好方法是什么?

Since the new UIBackgroundConfiguration is a structure rather than a layer-backed UIView subclass, I can't just add a CAGradientLayer instance as a sublayer.

是的,你可以。 UIBackgroundConfiguration 是一个结构这一事实无关紧要。它有一个 customView 属性 视图,它将用作单元格中的背景视图(在内容视图后面)。因此,将该视图设置为某些内容(默认情况下为 nil),一切就绪。

举个例子。这是用于测试目的的玩具 table 视图,但测试完全是关于配置对象的,因此很容易适应 table 来演示该技术。无论您使用的是 table 视图、集合视图还是两者都不使用都没有关系,只要您使用的是具有 UIBackgroundConfiguration 属性 的东西即可。如您所见,我制作了一个从黑色到红色的垂直渐变作为单元格的背景。

这是相关代码。首先,我定义了一个 gradient-carrier 视图类型:

class MyGradientView : UIView {
    override static var layerClass: AnyClass { CAGradientLayer.self }
}

然后,我在配置单元格时使用该视图作为背景视图:

var back = UIBackgroundConfiguration.listPlainCell()
let v = MyGradientView()
(v.layer as! CAGradientLayer).colors = 
    [UIColor.black.cgColor, UIColor.red.cgColor]
back.customView = v
cell.backgroundConfiguration = back

您想要实现的任何其他功能都只是上述的变体。例如,您可以使用图像视图或纯色背景视图并将它们与渐变视图组合。关键是,customView 背景视图,你设置成什么视图都会显示在单元格的背景中。

我还应该指出还有另一种方法可以做到这一点,即使用单元子类并实现 updateConfigurationUsingState:。这种方法的优点是,一旦你给后台配置一个customView,你就可以在每次调用方法时修改那个customView。您可以使用此技术来响应选择,例如,正如我在此处的其他答案中所展示的那样(例如 )。