Возвращение NSNull из actionForLayer: forKey - PullRequest
1 голос
/ 18 мая 2010

Если я реализую метод делегата CALayer actionForLayer:forKey, я могу вернуть [NSNull null], чтобы заставить CALayer не анимировать какие-либо изменения. К сожалению, [NSNull null] не реализует делегат CAAction, и XCode выдает следующее предупреждение:

предупреждение: класс NSNull не реализует протокол CAAction

Вот код метода:

- (id<CAAction>)actionForLayer:(CALayer *)theLayer
                        forKey:(NSString *)theKey {
 //This disables the animations when moving things around
 //Also, don't animate the selection box. It was doing weird things
 if(undoGroupStarted || theLayer == self.selectionBox) {
  return [NSNull null];
 } else {
  return nil;
 }
}

Я что-то не так делаю? Возвращает [NSNull null] плохое поведение? Если да, то как еще можно сделать то, что я пытаюсь сделать здесь? Если нет, то как мне порадовать компилятор?

Ответы [ 2 ]

2 голосов
/ 22 мая 2010

Раздел «Руководство по программированию CoreAnimation» Определенный шаблон поиска для ключей действий решает эту проблему. Они CALayer делегат могут вернуть nil, чтобы указать, что он не обрабатывает действие, но что поиск должен продолжаться. Он также может вернуть [NSNull null], чтобы указать, что действие не должно обрабатываться (то есть поиск должен быть остановлен).

В заголовке CALayer вы увидите немного больше информации о том, как это обрабатывается:

Если любой из этих шагов приводит к объекту, отличному от нуля, следующие шаги игнорируются. Если окончательный результат является экземпляром NSNull, он преобразуется в `nil '.

Чтобы заставить компилятор принять это, вы можете просто привести:

return (id <CAAction>)[NSNull null]; // Prevent the action from animating
0 голосов
/ 21 мая 2010

Судя по документации Apple CAAction, единственным встроенным классом, который реализует протокол CAAction, является CAAnimation (и его подклассы, конечно). Компилятор ожидает возвращаемое значение, которое реализует CAAction, поэтому да, возвращение [NSNull null] не будет работать. Вам действительно нужно использовать этот метод делегата, в отличие от удаления анимации со слоя, используя [layer removeAllAnimations] или [layer removeAnimationForKey:]?

Это кажется расточительным, но если вам абсолютно необходимо использовать метод делегата, возможно, вы могли бы вернуть «пустой» объект анимации:

return [CAAnimation animation];

Кроме того, вам нужно отключить эту анимацию навсегда или только в определенных обстоятельствах? Если вам не нужно постоянно переопределять анимацию, вы можете использовать CATransaction, чтобы отключить анимацию для отдельных вызовов методов, как описано здесь в Core Animation Programming Guide .

...