如何通过代码复制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
相关产品推荐
相关产品推荐

