如何正确快速复制CAShapeLayer?

时间:2020-01-11 13:44:50

标签: swift cashapelayer

我试图快速创建CAShapeLayer的副本,但崩溃了

由于未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因:'-[CAShapeLayer copyWithZone:]:无法识别的选择器发送到实例0x282e87e60'

我应该采取哪些额外的步骤来允许CALayer .copy()工作而不会使应用程序崩溃? 即使我不转换.copy()的结果,它仍然在该copy()行上完全失败...

private var drawLines: [CAShapeLayer]
func getCopiedLayers() -> [CAShapeLayer] {
    return drawLines.compactMap { layer -> CAShapeLayer? in
        return layer.copy() as? CAShapeLayer
    }
}

我在这里做错了什么? 预先感谢您的回答

1 个答案:

答案 0 :(得分:1)

CALayer不符合API中的NSCopying,但符合NSSecureCoding,因此可以如下添加复制功能

使用Xcode 11.2 / iOS 13.2(通过CAShapeLayer和 CAGradientLayer)

extension CALayer : NSCopying {
    public func copy(with zone: NSZone? = nil) -> Any {
        if let data = try? NSKeyedArchiver.archivedData(withRootObject: self, requiringSecureCoding: false) {
            if let newInstance = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) {
                return newInstance
            }
        }
        fatalError() // << should never got here
    }
}

现在,可以无条件地(理论上)调用layer.copy()到任何层了。