Вторичное обновление свойств не прилипает после анимации

Репозиторий REPRO здесь: https://github.com/kaolin/38492498/tree/master


У меня есть @property int percentScanned.

Я установил needsDisplayForKey:

+ (BOOL)needsDisplayForKey:(NSString *)key {
    if ([@"percentScanned" isEqualToString:key]) {
        return YES;
    }
    return [super needsDisplayForKey:key];
}

Мой метод отображения:

- (void)display {
    _percentTextLayer.string = [NSString stringWithFormat:@"%02d%%",[[self presentationLayer] percentScanned]];
}

Моя анимация:

    [CATransaction begin];
    self.percentScanned = 99;
    [email protected]"99%";
    [CATransaction setCompletionBlock:^{
        [email protected]"99%";
        self.percentScanned = 99;
    }];
    {
        CABasicAnimation *a = [CABasicAnimation animationWithKeyPath:@"percentScanned"];
        [a setFromValue:@0];
        [a setToValue:@99];
        [a setDuration:4.];
        [self addAnimation:a forKey:@"percentage"];
    }
    [CATransaction commit];

Все работает отлично, за исключением того, что в конце анимации строка моего модельного слоя возвращается к "00%". Как вы можете видеть, я бросил то, что чувствует, как кухонная раковина, заставляя его оставаться на уровне "99%" (за пределами "взлома" animation.removedOnCompletion = NO; и animation.fillMode = kCAFillModeForwards; - и на самом деле, добавив, что это не помогает!).

У меня есть еще одна анимация на том же слое примерно на 3/30 секунды позже, угасая непрозрачность. Но выталкивание этого или удаление его, похоже, не имеет значения.

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


ИЗМЕНИТЬ ДОБАВИТЬ:

Где-то по пути добавление animation.removedOnCompletion = NO; и animation.fillMode = kCAFillModeForwards; действительно запустило "работу", но я не хочу утечки анимаций....

Если я добавлю setter для percentScanned, он не вызывается с 0 в конце, но в конце вызывается отображение с 0. Трудно проследить связь между вызываемым и вызываемым вызовом setPercentScanned...

Я могу взломать display следующим образом:

- (void)display {
    if ([[self presentationLayer] percentScanned] != 0) {
        _percentTextLayer.string = [NSString stringWithFormat:@"%02d%%",[[self presentationLayer] percentScanned]];
    }
}

Затем он работает для моего конкретного варианта использования, но это еще меньше, чем идеальный....

И положить точку останова в методе отображения довольно бесполезно (конечно, это происходит только внутри display_if_needed).:/

Ответ 1

percentScanned необходимо установить в качестве переменной @dynamic, чтобы Core Animation реализовала для вас аксессоров, за fooobar.com/questions/172686/...

Ответ 2

В принципе, установите конечное значение непосредственно на слой и анимируйте только fromValue. Таким образом, значение, которое имеет слой, уже правильно в конце анимации.