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

Posted

技术标签:

【中文标题】UICollectionViewListCell 的自定义子类中的自我调整大小在 iOS 14 中不起作用【英文标题】:Self sizing in Custom subclass of UICollectionViewListCell not working in iOS 14 【发布时间】:2020-07-15 08:02:39 【问题描述】:

背景:

ios14 引入了一种新的方法来注册和配置 collectionViewCell 和 In Lists In CollectionView WWDC 视频 苹果开发者说 self sizing 默认为 UICollectionViewListCell 并且我们不必明确指定单元格的高度。如果我在各种配置中使用系统列表单元格,但当我将它与 UICollectionViewListCell 的自定义子类一起使用时,自动调整大小会失败。

我尝试了什么?

iOS 14 引入了一种配置单元的新方法,我们不直接访问单元组件来设置各种 UI 属性评估器,我们使用 content configurationbackground 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
    

SkillListViewBackgroundConfiguration

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
    

SkillListViewContentConfiguration

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
    

终于子视图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)
        ])
    

我使用它来配置它

    let skillsCellConfigurator = UICollectionView.CellRegistration<CustomSkillListCollectionViewCell, Employee>  (cell, indexPath, employee) in
        cell.skillLavel = employee.individualSkil
        cell.accessories = [.disclosureIndicator()]
    

问题:

除了身高,其他都很好

【问题讨论】:

【参考方案1】:

首先,您需要至少 1 个以上的约束来保证满意,因为顶部、底部和前导需要一个尾随或 centerX 来配合它们。但更重要的是,它可能限制在边缘而不是超级视图。只要 UICollectionView 本身尊重它们,单元格应该自动尊重安全区域等边距,我认为这是默认行为。单元格的 layoutmarginguide 被显着地推到了顶部,如果您检查的话,可以从 interfacebuilder 中的一个虚拟示例中看到。

【讨论】:

以上是关于UICollectionViewListCell 的自定义子类中的自我调整大小在 iOS 14 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

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

iOS 14 UICollectionViewCell 相关

iOS 14 UICollectionViewCell 相关

iOS 14 UICollectionViewCell 相关