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

如何通过代码复制UIView并保留accessibilityIdentifier?

如何在UIView复制时保留accessibilityIdentifier?

这个问题我之前也碰到过!用NSKeyedArchiver/NSKeyedUnarchiver复制UIView时,accessibilityIdentifier丢失的原因很简单:UIKit默认的归档逻辑不会把这个属性纳入归档范围——系统只会归档UIView内部标记为需要持久化的核心属性,而辅助功能相关的很多属性不在这个列表里。

最简单的修复方案:手动复制属性

直接修改你的copyView扩展,在复制完成后把原视图的accessibilityIdentifier手动赋值给新视图就行,代码如下:

extension UIView {
    func copyView<T: UIView>() -> T {
        guard let copiedView = NSKeyedUnarchiver.unarchiveObject(with: NSKeyedArchiver.archivedData(withRootObject: self)) as? T else {
            fatalError("Failed to copy view as type \(T.self)")
        }
        // 手动复制accessibilityIdentifier
        copiedView.accessibilityIdentifier = self.accessibilityIdentifier
        return copiedView
    }
}

这段代码做了两个优化:

  • 用guard let做安全解包,比强制解包更稳妥,避免类型不匹配时崩溃;
  • 新增了accessibilityIdentifier的手动赋值逻辑,确保复制后的视图保留原标识。

如果之后你还需要保留其他辅助功能属性(比如accessibilityLabel、accessibilityHint、accessibilityTraits),只需要在这个地方继续添加赋值语句即可:

copiedView.accessibilityLabel = self.accessibilityLabel
copiedView.accessibilityHint = self.accessibilityHint
copiedView.accessibilityTraits = self.accessibilityTraits

进阶方案:自定义归档逻辑(可选)

如果你想让归档流程自动处理accessibilityIdentifier,可以创建UIView的子类,重写归档和解档方法,把属性加入归档列表:

class AccessibleView: UIView {
    override func encode(with coder: NSCoder) {
        super.encode(with: coder)
        // 归档accessibilityIdentifier
        coder.encode(accessibilityIdentifier, forKey: "accessibilityIdentifier")
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        // 解档accessibilityIdentifier
        accessibilityIdentifier = coder.decodeObject(forKey: "accessibilityIdentifier") as? String
    }
}

不过这种方法比较重,而且只有子类实例会生效,所以更推荐第一种手动赋值的方式——灵活、轻量,完全能解决你的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:03:51