首页 > 解决方案 > iOS 14 中的 UICollectionViewListCell 和自定义单元格附件

问题描述

我对新集合视图列表单元的问题是我无法将操作处理程序添加到自定义附件视图。

我一直在尝试执行以下操作:

protocol TappableStar: class {
    func onStarTapped(_ cell: UICollectionViewCell)
}

class TranslationListCell: UICollectionViewListCell {
    let starButton: UIButton = {
        let starButton = UIButton()
        let starImage = UIImage(systemName: "star")!.withRenderingMode(.alwaysTemplate)
        starButton.setImage(starImage, for: .normal)
        starButton.setContentHuggingPriority(.defaultHigh, for: .horizontal)
        starButton.addTarget(self, action: #selector(starButtonPressed(_:)), for: .touchUpInside)
        starButton.tintColor = .systemOrange
        return starButton
    }()
    
    var translation: TranslationModel?
    weak var link: TappableStar?
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        accessories = [.customView(configuration: .init(customView: starButton, placement: .trailing(displayed: .always)))]
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    @objc private func starButtonPressed(_ sender: UIButton) {
        link?.onStarTapped(self)
    }
    
    override func updateConfiguration(using state: UICellConfigurationState) {
        // Create new configuration object and update it base on state
        var newConfiguration = TranslationContentConfiguration().updated(for: state)
        // Update any configuration parameters related to data item
        newConfiguration.inputText = translation?.inputText
        newConfiguration.outputText = translation?.outputText

        contentConfiguration = newConfiguration
    }
}

继承 UICollectionViewListCell,创建一个带有目标操作处理程序的按钮并将其添加到附件数组中。我也有自己的单元配置实现。

现在,我创建了一个协议,将操作处理委托给我的视图控制器(我还实现了新的单元注册 API 和 set cell.link = self)。

我的问题是我的附件按钮没有调用,starButtonPressed尽管这个附件视图是响应式的(突出显示时它会改变颜色)。

我的想法是,我使用自定义附件实现动作处理的方式可能有问题,但关于这个新 api 的信息似乎很少甚至没有。

此外,在预定义附件之间进行选择时,其中一些具有actionHandlerUICellAccessory.ActionHandler 类型的闭包,但我似乎不明白如何正确实现它。

任何想法将不胜感激。

标签: iosswift

解决方案


iOS 14,使用 UIActions

从 iOS 14 开始,我们可以使用主要操作初始化 UIButton 和其他 UIControl。它变得类似于原生配件的处理程序。有了这个,我们可以使用我们想要的任何参数化方法。参数化很重要,因为通常我们想对特定的单元格做一些动作。#selector 无法参数化,因此我们无法将任何信息传递给有关要更新哪个单元格的方法。但此解决方案仅适用于 iOS 14+。

创建 UIAction:

let favoriteAction = UIAction(image: UIImage(systemName: "star"),
                                      handler: { [weak self] _ in
                                        guard let self = self else { return }
                                        self.handleFavoriteAction(for: your_Entity)
                                      })

创建 UIButton:

let favoriteButton = UIButton(primaryAction: favoriteAction)

创建附件:

let favoriteAccessory = UICellAccessory.CustomViewConfiguration(
    customView: favoriteButton, 
    placement: .leading(displayed: .whenEditing)
)

使用

cell.accessories = [.customView(configuration: favoriteAccessory)]

推荐阅读