Повернуть UIView вокруг правой стороны экрана

Я хочу повернуть вид вокруг правого края экрана, например, при открытии двери. Это то, что у меня есть до сих пор:

CATransform3D transform = CATransform3DIdentity;
transform.m34 = -1.0f/500;
view.layer.transform = CATransform3DRotate(transform, kDegreesToRadians(90), 0, 1, 0);
[UIView animateWithDuration:2.0f animations:^{
     view.layer.transform = transform;
} completion:nil];

Я еще не совсем уверен в CATranforms или матрицах, если на то пошло, поэтому, если кто-то может подтолкнуть меня в правильном направлении, это будет очень признательно!


person barndog    schedule 12.12.2013    source источник
comment
Пробовали ли вы изменить точку привязки? stackoverflow.com/questions/7438385/   -  person atxe    schedule 13.12.2013


Ответы (2)


Анимации UIView предназначены для анимации свойств представления, а не для анимации слоев. Насколько мне известно, вы не можете анимировать слой представления, используя вызов UIView animateWithDuration:.

Вам нужно будет создать CABasicAnimation и добавить его в слой вашего представления самостоятельно.

Прошло некоторое время с тех пор, как я сделал CAAnimations, но давайте посмотрим, что я могу накопать:

Как говорит atxe, вы должны переместить точку привязки слоя на 1,.5, прежде чем делать эту анимацию, чтобы она вращалась вокруг правого края.

Вот код из нашего мультяшного приложения «Кевин и Келл», который анимирует дверь, распахивающуюся на петлях:

//Open the door.
rotateAnimation = [CABasicAnimation animation];
rotateAnimation.keyPath = @"transform";
rotateAnimation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];

//Pivot on the right edge (y axis rotation)
theTransform = CATransform3DIdentity;
  theTransform.m34 = -1/100.0;
  theTransform = CATransform3DRotate(theTransform, degreesToRadians(70), 0, 1, 0);


rotateAnimation.toValue = [NSValue valueWithCATransform3D:theTransform];

rotateAnimation.duration = 0.5;

// leaves presentation layer in final state; preventing snap-back to original state
rotateAnimation.removedOnCompletion = NO;
rotateAnimation.fillMode = kCAFillModeBoth; 

rotateAnimation.repeatCount = 0;
rotateAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
rotateAnimation.delegate = self;
[treeDoorImageView.layer addAnimation:rotateAnimation forKey:@"transform"];

Логика преобразования почти идентична вашей (я использую значение m34 -1/100 для более преувеличенного 3D-эффекта. Ваше значение -1/500 более нормальное).

Обратите внимание, что вместо того, чтобы пытаться сделать анимацию из блока анимации UIView, я создаю CABasicAnimation и устанавливаю его свойства fromValue и toValue в начальное и конечное значения преобразования.

Вы сможете использовать этот код в качестве отправной точки для анимации.

person Duncan C    schedule 12.12.2013
comment
Такой фантастический ответ. Спасибо! - person barndog; 13.12.2013

Вам нужно использовать CAAnimation, а не блочную анимацию UIView.

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform"];
animation.duration = 2;
animation.fromValue = [NSValue valueWithCATransform3D:view.layer.transform]; // From the existing transform.
animation.toValue = [NSValue valueWithCATransform3D:transform]; // To the new one.

view.layer.transform = transform; // Set the new transform.
[view.layer addAnimation:animation forKey:@"door"]; // Animate visual change.

Кроме того, как указал axte, вам нужно будет установить anchorPoint слоя на (1, 0.5), чтобы применить вращение вокруг правого края слоя.

person Tricertops    schedule 12.12.2013