UICollectionViewListCell 的自定义子类中的自调整大小在 iOS 14 中不起作用

San*_*ari 5 ios swift

背景:

iOS14 引入了一种新的方式来注册和配置 collectionViewCell 和在CollectionView 中的列表中WWDC 视频苹果开发人员表示默认情况下会自动调整大小UICollectionViewListCell,我们不必明确指定单元格的高度。如果我在各种配置中使用系统列表单元格,这很有效,但是当我将它与UICollectionViewListCell

我尝试了什么?

iOS 14 引入了一种配置单元格的新方法,我们不直接访问单元格组件来设置我们使用的各种 UI 属性评估器content configuration以及background configuration更新/配置单元格。当我们使用自定义单元格时,这变得有点棘手。

CustomSkillListCollectionViewCell

class CustomSkillListCollectionViewCell: UICollectionViewListCell {
    var skillLavel: String? {
        didSet {
            setNeedsUpdateConfiguration()
        }
    }
    
    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func updateConfiguration(using state: UICellConfigurationState) {
        backgroundConfiguration = SkillListViewBackgroundConfiguration.getBackgroundConfiguration(for: state)
        var content = SkillListViewContentConfiguration().updated(for: state)
        content.label = skillLavel
        contentConfiguration = content
    }
}
Run Code Online (Sandbox Code Playgroud)

技能列表视图背景配置

struct SkillListViewBackgroundConfiguration {
    @available(iOS 14.0, *)
    static func getBackgroundConfiguration(for state: UICellConfigurationState) -> UIBackgroundConfiguration {
        var background = UIBackgroundConfiguration.clear()
        if state.isHighlighted || state.isSelected {
            background.backgroundColor = UIColor.green.withAlphaComponent(0.4)
        }
        else if state.isExpanded {
            background.backgroundColor = UIColor.red.withAlphaComponent(0.5)
        }
        else {
            background.backgroundColor = UIColor.red.withAlphaComponent(0.9)
        }
        return background
    }
}
Run Code Online (Sandbox Code Playgroud)

技能列表视图内容配置

struct SkillListViewContentConfiguration: UIContentConfiguration {
    var label: String? = nil
    
    @available(iOS 14.0, *)
    func makeContentView() -> UIView & UIContentView {
        return SkillListView(contentConfiguration: self)
    }
    
    @available(iOS 14.0, *)
    func updated(for state: UIConfigurationState) -> Self {
        guard let state = state as? UICellConfigurationState else {
            return self
        }
        let updatedConfig = self
        return updatedConfig
    }
}
Run Code Online (Sandbox Code Playgroud)

最后子视图SkillListView

class SkillListView: UIView, UIContentView {
    var configuration: UIContentConfiguration {
        get {
            return self.appliedConfiguration
        }
        set {
            guard let newConfig = newValue as? SkillListViewContentConfiguration else { return }
            self.appliedConfiguration = newConfig
            apply()
        }
    }
    
    private var appliedConfiguration: SkillListViewContentConfiguration!
    var skillNameLabel: UILabel!
    
    @available(iOS 14.0, *)
    init(contentConfiguration: UIContentConfiguration) {
        super.init(frame: .zero)
        self.setUpUI()
        self.configuration = contentConfiguration
        self.apply()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func apply() {
        self.skillNameLabel.text = self.appliedConfiguration.label
    }
    
    private func setUpUI() {
        self.skillNameLabel = UILabel(frame: .zero)
        skillNameLabel.setContentCompressionResistancePriority(.defaultHigh, for: .vertical)
        skillNameLabel.setContentHuggingPriority(.defaultHigh, for: .vertical)
        self.skillNameLabel.translatesAutoresizingMaskIntoConstraints = false
        self.addSubview(skillNameLabel)
        NSLayoutConstraint.activate([
            self.skillNameLabel.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor, constant: 20),
            self.skillNameLabel.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor, constant: 20),
            self.skillNameLabel.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor, constant: 20)
        ])
    }
}
Run Code Online (Sandbox Code Playgroud)

我配置它使用

    let skillsCellConfigurator = UICollectionView.CellRegistration<CustomSkillListCollectionViewCell, Employee> { (cell, indexPath, employee) in
        cell.skillLavel = employee.individualSkil
        cell.accessories = [.disclosureIndicator()]
    }
Run Code Online (Sandbox Code Playgroud)

问题:

除了身高,其他一切都很好

在此处输入图片说明

use*_*275 0

首先,您至少还需要 1 个约束来保证满足,因为顶部、底部和前导需要尾随或 centerX 来配合它们。但更重要的是,它可能限制了边缘而不是超级视图。只要 UICollectionView 本身尊重它们,单元格就应该像安全区域一样自动尊重边距,我认为这是默认行为。单元格的布局边距指南在顶部显着向下推,如果您检查的话,可以从界面生成器中的虚拟示例中看到这一点。