NSView CALayer Непрозрачность Безумие

Кажется, что свойства слоя моего NSView иногда не редактируются/неправильные. В приведенном ниже коде анимация работает отлично, и все выглядит нормально. Вывод из NSlogs всегда:

anim over opacity = 1.00000
first opacity = 0.50000
current opacity = 0.00000
updated opacity = 0.00000

Первые два лога выглядят правильно, поэтому даже при остановке анимации слой работает нормально. Однако некоторое время спустя, когда я проверяю непрозрачность, она волшебным образом становится равной 0. Еще более неправильно, когда я устанавливаю непрозрачность слоя на 1 и сразу же проверяю ее, она по-прежнему равна 0. Как это возможно?

Я дурачился с setneedsdisplay в слое и setneedsdisplay:YES в nsview, и это не помогло. Любые предложения приветствуются.

- (void) someSetupAnimationMethod {
        aLayer = [CALayer layer];
        [theView setWantsLayer:YES];
        [theView setLayer:aLayer];

        [aLayer setOpacity:0.0];
        CABasicAnimation *opacity = [CABasicAnimation animationWithKeyPath:@"opacity"];
        opacity.byValue = [NSNumber numberWithFloat:1.0];
        opacity.duration = 0.3;
        opacity.delegate = self;
        opacity.fillMode = kCAFillModeForwards;
        opacity.removedOnCompletion = NO;
        [opacity setValue:@"opacity done" forKey:@"animation"];
        [aLayer addAnimation:opacity forKey:nil];
    }

    - (void) animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
        if([[anim valueForKey:@"animation"] isEqualToString:@"opacity done"]) {
           NSLog(@"anim over opacity = %f", aLayer.opacity);
           aLayer.opacity = 0.5;
           [aLyaer removeAllAnimations];
           NSLog(@"first opacity = %f", aLayer.opacity);
        }
    }

    - (void) someLaterMethod {
        NSLog(@"current opacity = %f", aLayer.opacity);
        aLayer.opacity = 1.0;
        NSLog(@"updated opacity = %f", aLayer.opacity);
    }

person Ryan    schedule 24.07.2011    source источник
comment
В качестве альтернативы, как правильно настроить слой в nsview?   -  person Ryan    schedule 24.07.2011


Ответы (1)


Вы нарушаете фундаментальное правило CALayer/NSView, создавая представление на основе слоев, а затем пытаясь управлять слоем напрямую.

aLayer = [CALayer layer];
[theView setWantsLayer:YES];
[theView setLayer:aLayer];

Когда вы сообщаете представлению использовать слой перед вызовом setLayer:, представление становится «поддерживаемым слоями» — оно просто использует слой в качестве буфера, и все рисование, которое вы хотите сделать, должно выполняться с помощью обычного drawRect: и связанных с ним методов. . Вам не разрешается прикасаться к слою напрямую. Если вы измените порядок этих вызовов:

[theView setLayer:aLayer];
[theView setWantsLayer:YES];

Теперь у вас есть представление «уровень-хостинг», что означает, что представление просто предоставляет пространство на экране для слоя, в котором он будет отображаться. В этом случае вы делаете свой рисунок прямо в слое. Поскольку содержимое слоя становится содержимым вида, вы не можете добавлять подвиды или использовать механизмы рисования вида.

Это упоминается в -[NSView setWantsLayer:] документация; Я также нашел старую тему разработки какао. это объясняет это довольно хорошо.

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

person jscs    schedule 24.07.2011
comment
Спасибо за информацию. Попробую настроить таким образом, посмотрю, работает ли. - person Ryan; 25.07.2011