Длительность анимации настройки CATransaction не работает

Я изучаю Core Animation и пробую образцы примеров.

Когда я использую следующий код, продолжительность анимации работает

@implementation ViewController

- (void)viewDidLoad
{
[super viewDidLoad];

//Modifying base layer
self.view.layer.backgroundColor = [UIColor orangeColor].CGColor;
self.view.layer.cornerRadius = 20.0;
self.view.layer.frame = CGRectInset(self.view.layer.frame, 20, 20);

//Adding layer
mylayer=[CALayer layer]; //mylayer declared in .h file
mylayer.bounds=CGRectMake(0, 0, 100, 100);
mylayer.position=CGPointMake(100, 100); //In parent coordinate
mylayer.backgroundColor=[UIColor redColor].CGColor;
mylayer.contents=(id) [UIImage imageNamed:@"glasses"].CGImage;

[self.view.layer addSublayer:mylayer];
}


- (IBAction)Animate //Simple UIButton
{
[CATransaction begin];

// change the animation duration to 2 seconds
[CATransaction setValue:[NSNumber numberWithFloat:2.0f] forKey:kCATransactionAnimationDuration];

mylayer.position=CGPointMake(200.0,200.0);
mylayer.zPosition=50.0;
mylayer.opacity=0.5;

[CATransaction commit];
}
@end

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

Есть предположения?

Спасибо КМБ


person Khaled Barazi    schedule 18.10.2012    source источник


Ответы (1)


Вот что вам не хватает: в вашем приложении есть две иерархии уровней. Существует иерархия уровней model, с которой вы обычно работаете. Затем идет иерархия слоев презентации, которая отражает то, что происходит на экране. Взгляните на «Дерево слоев отражает различные аспекты состояния анимации» в Руководстве по программированию базовой анимации для получения дополнительной информации или (настоятельно рекомендуется) посмотреть Видео Core Animation Essentials с WWDC 2011.

Весь код, который вы написали, работает на уровне модели (как и должно быть).

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

Только слои модели, которые находятся в иерархии представлений UIWindow, получают слои представления. Система отправляет вам viewDidLoad до того, как она добавила self.view в окно, поэтому пока нет слоев представления для self.view или вашего пользовательского слоя, когда viewDidLoad работает.

Поэтому вам нужно изменить свойство позже, после того как вид и слой будут добавлены в окно и система создаст слои представления. viewDidAppear: уже достаточно поздно.

- (void)viewDidLoad {
    [super viewDidLoad];

    //Modifying base layer
    self.view.layer.backgroundColor = [UIColor orangeColor].CGColor;
    self.view.layer.cornerRadius = 20.0;
    self.view.layer.frame = CGRectInset(self.view.layer.frame, 20, 20);

    // Adding layer
    mylayer = [CALayer layer]; //mylayer declared in .h file
    mylayer.bounds = CGRectMake(0, 0, 100, 100);
    mylayer.position = CGPointMake(100, 100); //In parent coordinate
    mylayer.backgroundColor = [UIColor redColor].CGColor;
    mylayer.contents = (id)[UIImage imageNamed:@"glasses"].CGImage;    
    [self.view.layer addSublayer:mylayer];
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    [CATransaction begin]; {
        [CATransaction setAnimationDuration:2];
        mylayer.position=CGPointMake(200.0,200.0);
        mylayer.zPosition=50.0;
        mylayer.opacity=0.5;
    } [CATransaction commit];
}
person rob mayoff    schedule 18.10.2012
comment
Спасибо, Роб. Это сработало. Я предполагаю, что эти скобки вокруг начала фиксации являются необязательными. - person Khaled Barazi; 18.10.2012
comment
Брекеты необязательны. Мне нравится делать отступ в коде между begin и commit, а фигурные скобки заставляют Xcode делать отступ автоматически. - person rob mayoff; 18.10.2012
comment
Я решительно поддерживаю упомянутое видео WWDC — это отличное введение во многие подводные камни CoreAnimation. - person MaxGabriel; 18.10.2012
comment
Или вместо того, чтобы разделять его, оберните его двумя разными CATransactions (на случай, если вам нужно сделать это вне инициализации). - person DuneCat; 27.05.2013