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

репозиторий 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;
    _percentTextLayer.string=@"99%";
    [CATransaction setCompletionBlock:^{
        _percentTextLayer.string=@"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; - и на самом деле, добавление этих не помогает!).

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

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


ОТРЕДАКТИРОВАНО, ЧТОБЫ ДОБАВИТЬ:

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

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

я могу взломать мой display читать как следует:

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

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

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

2 ответов


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


percentScanned необходимо установить как переменную @dynamic, чтобы Core Animation реализовала для вас аксессоры, per https://stackoverflow.com/a/2396461/856925