Как правильно скопировать CAShapeLayer в swift? - PullRequest
1 голос
/ 11 января 2020

Я пытаюсь создать копии CAShapeLayer в быстром темпе, но получаю cra * sh

Завершение приложения из-за необработанного исключения '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 Ответ

1 голос
/ 11 января 2020

CALayer не соответствует NSCopying из API, но соответствует 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() для любого слоя (теоретически) без исключения.

...