CALayer во время анимации использует значение свойства по умолчанию вместо того, что должно быть значением свойства текущего экземпляра - PullRequest
0 голосов
/ 14 июня 2019

Я воссоздаю свою проблему на игровой площадке xCode, где приводятся примеры ошибок, с которыми я сталкиваюсь (показывается лучше при объяснении): https://gist.github.com/Wowserman/c1910523ad85cf34d3e08150b65c7074

Моя проблема в том, что мой класс CALayer прекрасно отображает его, в этом .gif вы можете увидеть, что это, когда он впервые отображается (зеленый с тенью внизу) и чтобы было ясно, что он отображает так, как должен, но как только я начинаю анимировать высоту тени, вот в чем проблема.

Я анимировал shadowHeight с 12,0 до 0,0 и перевернул эту анимацию, и анимация работает хорошо, за исключением , свойство color может измениться на значение по умолчанию (Желтый) без моего намерения!

Вы можете видеть в этом gif, слой сначала визуализируется внутри, зеленый с тенью (что предназначено), затем, когда к виду обращаются, и слой анимирует сокращение тени (предназначено), но color изменяет значение по умолчанию (желтый) во время анимации и после его завершения возвращается к собственному значению color экземпляра. Анимация должна всегда иметь значение color на протяжении всей анимации.

enter image description here

Я проверил, что свойство color никогда не изменяется, у меня есть didSet наблюдатель, печатающий каждый раз, когда он изменяется, и он изменяется только во время инициализации, как и должно быть.

Затем я проверил draw(in ctx:) метод CALayer , и там я увидел, что свойство color отличается.

Еще одна возможная проблема, о которой я думал, может состоять в том, что слой drawsAsynchronously верен, но после его переключения я определил, что это не проблема.

Моя проблема подведена :

Свойство color слоя незаметно изменяется во время анимации на значение свойства по умолчанию вместо значения, установленного при инициализации, что вызывает нежелательный рендеринг.

Ответы [ 2 ]

2 голосов
/ 14 июня 2019

Я нашел решение для всех, кто в этом нуждается.Когда CALayer анимирован, CALayer не видоизменяется, скорее он дублируется с помощью CALayer init(layer:).

Я читал документацию по этому инициализатору ( введите описание ссылки здесь )и обнаружил, что внутри переопределения вы должны скопировать пользовательские свойства layer в новый подкласс CALayer.

public override init(layer: Any) {
    super.init(layer: layer)

    self.common()

    guard let overlay = layer as? OverlayLayer else {
        return
    }

    self.color = overlay.color
}

Вот обновление Gist с исправлением, если вам интересно

https://gist.github.com/Wowserman/ca23d9596f2979effd9cc8fa9e73c893

1 голос
/ 14 июня 2019

В вашем didSet наблюдателе на color - не звоните display()

Вы не должны звонить display напрямую.Как указано в документе:

Не вызывайте этот метод напрямую.Слой вызывает этот метод в подходящее время для обновления содержимого слоя.

Вместо этого используйте:

self.setNeedsDisplay()

Редактировать: То же самое относится и к вашей функции common().

...