You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为UICollectionViewListCell的accessory设置accessibilityIdentifier?

问题

在自动化测试中需要通过UIView的accessibilityIdentifier字段触发单元格的展开/折叠操作,但使用UICellAccessory.OutlineDisclosure时,对应的OutlineDisclosureOptions没有提供配置accessibilityIdentifier的选项。当前设置单元格accessory的代码如下:

func headerCellRegistration() -> UICollectionView.CellRegistration<MyCollectionViewListCell, MyStruct> {
    UICollectionView.CellRegistration<MyCollectionViewListCell, MyStruct>(
        cellNib: MyCollectionViewListCell.nib(MyCollectionViewListCell.self)
    ) { cell, indexPath, headerItem in
        let headerDisclosureOption = UICellAccessory.OutlineDisclosureOptions(
            style: .header,
            tintColor: .systemGray)
            
        cell.accessories = [
            .outlineDisclosure(displayed: .whenNotEditing, options: headerDisclosureOption),
        ]
    }
}

其中MyCollectionViewListCell是UICollectionViewListCell的子类,请问这种情况下有哪些解决办法?


可行的解决办法

1. 遍历单元格子视图为Disclosure按钮设置标识

系统的OutlineDisclosure本质是一个可交互的按钮视图,我们可以在单元格配置完成后,遍历其视图层级找到该按钮并设置accessibilityIdentifier。建议在配置闭包中延迟执行(确保accessory已添加到视图):

// 在单元格配置闭包内添加
DispatchQueue.main.async {
    // 递归遍历子视图查找Disclosure按钮
    func findDisclosureButton(in view: UIView) -> UIView? {
        // 可根据实际accessibilityLabel或控件类型匹配,不同iOS版本可能有差异
        if view.accessibilityLabel == "Disclosure Indicator" || view is UIControl {
            return view
        }
        for subview in view.subviews {
            if let button = findDisclosureButton(in: subview) {
                return button
            }
        }
        return nil
    }
    
    if let disclosureButton = findDisclosureButton(in: cell) {
        disclosureButton.accessibilityIdentifier = "header_disclosure_\(indexPath.section)"
    }
}

2. 自定义UICellAccessory替换系统控件

创建一个自定义的UICellAccessory,内部包含带accessibilityIdentifier的按钮,模拟系统OutlineDisclosure的样式和行为:

class CustomOutlineDisclosureAccessory: UICellAccessory {
    private let button = UIButton(type: .system)
    var tapHandler: (() -> Void)?
    
    var accessibilityID: String? {
        didSet {
            button.accessibilityIdentifier = accessibilityID
        }
    }
    
    override init() {
        super.init()
        setupButton()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setupButton()
    }
    
    private func setupButton() {
        // 模拟系统Disclosure图标
        let image = UIImage(systemName: "chevron.right")
        button.setImage(image, for: .normal)
        button.tintColor = .systemGray
        button.addTarget(self, action: #selector(onButtonTap), for: .touchUpInside)
    }
    
    @objc private func onButtonTap() {
        tapHandler?()
    }
    
    override func makeContentView() -> UIView {
        return button
    }
}

在单元格配置中使用自定义accessory:

func headerCellRegistration() -> UICollectionView.CellRegistration<MyCollectionViewListCell, MyStruct> {
    UICollectionView.CellRegistration<MyCollectionViewListCell, MyStruct>(
        cellNib: MyCollectionViewListCell.nib(MyCollectionViewListCell.self)
    ) { cell, indexPath, headerItem in
        let customDisclosure = CustomOutlineDisclosureAccessory()
        customDisclosure.accessibilityID = "header_disclosure_\(indexPath.section)"
        customDisclosure.tapHandler = {
            // 绑定展开/折叠逻辑,比如更新Diffable数据源
            guard let collectionView = cell.superview as? UICollectionView,
                  let dataSource = collectionView.dataSource as? UICollectionViewDiffableDataSource<Section, Item> else {
                return
            }
            var snapshot = dataSource.snapshot()
            snapshot.toggleExpansion(of: headerItem)
            dataSource.apply(snapshot, animatingDifferences: true)
        }
        
        cell.accessories = [customDisclosure]
    }
}

3. 为整个单元格设置标识,通过点击单元格触发操作

如果点击单元格本身会触发展开/折叠(部分列表配置下默认支持),可以直接为单元格设置accessibilityIdentifier,在自动化测试中点击整个单元格即可:

// 在单元格配置闭包内添加
cell.accessibilityIdentifier = "header_cell_\(indexPath.section)"

这种方式需要确认单元格的点击事件已绑定展开/折叠逻辑,等同于点击Disclosure按钮的效果。


内容的提问来源于stack exchange,提问作者Silis Alin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 17:13:09