Изменить свойства CALayer: EXC_BAD_INSTRUCTION - PullRequest
0 голосов
/ 18 января 2019

Я пытаюсь реализовать выбор подслоя, щелкая по нему и визуализируя, что он был выбран, например, путем изменения цвета фона подслоя. Тем не менее, я получаю следующую ошибку и пытаюсь изменить любое свойство:

Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)

Она - моя функция, которая вызывается из моей функции NSView подкласса * mouseUp.

func SelectObject( atPoint: NSPoint)
{
    let thePoint = atPoint as CGPoint
    if let hitLayer = itsCourseLayer.hitTest( thePoint) {
        if (hitLayer != itsCourseLayer) {
            // Gives following error:
            // Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
            hitLayer.backgroundColor = NSColor.red.cgColor 
        }
    }
}

Я также пытался hitLayer.setValue (NSColor.red.cgColor, forKeyPath: "backgroundColor") и я пытался окружить его CATransaction.begin () и CATransaction.commit () , или изменить любое другое свойство подслоя. Но безуспешно.

Есть идеи, что не так с моим кодом?

1 Ответ

0 голосов
/ 19 января 2019

Сообщение об ошибке как бы подсказывает вам одно решение: внедрить init(layer:) в CPCoursePointLayer.

Когда вы устанавливаете свойство для слоя, и этот слой находится в дереве слоев не скрытого окнаCore Animation ищет CAAction для этого свойства, отправляя сообщение actionForKey: на слой.Если этот поиск возвращает nil, Core Animation создает неявную анимацию для свойства, используя некоторые параметры по умолчанию.

Любой слой с прикрепленной анимацией имеет соответствующий уровень представления.(Прочитайте Деревья слоев отражают различные аспекты состояния анимации для получения дополнительной информации.) Поэтому Core Animation необходимо создать соответствующий слой представления для вашего hitLayer.Это делается с использованием инициализатора init(layer:) в вашем классе CPCoursePointLayer.

В Swift класс не наследует автоматически все конструкторы своего суперкласса, поэтому ваш класс CPCoursePointLayer не имеет этого инициализатора,Таким образом, ваше приложение падает.

Одним из решений является добавление инициализатора init(layer:) к вашему CPCoursePointLayer классу:

init(layer: CALayer) {
    let layer = layer as! CPCoursePointLayer
    // copy any custom properties from layer to self here
    super.init(layer: layer)
}

Если вы определите init(layer:), тогда вы можете анимировать свойстваваш слой и разрешить им неявную анимацию.

Если вы никогда не планируете явно или неявно анимировать свойства вашего слоя, вы можете вместо этого отключить неявную анимацию, возвращая NSNull, когда Core Animation ищет действиеНапример, добавив этот метод в класс CPCoursePointLayer:

override class func defaultAction(forKey key: String) -> CAAction? {
    return unsafeBitCast(NSNull(), to: CAAction?.self)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...