Поворот CALayer на 90 градусов?

Как повернуть CALayer на 90 градусов? Мне нужно повернуть все, включая подслои и систему координат.


person Kristina Brooks    schedule 29.07.2010    source источник
comment
Не забудьте установить точку привязки слоя, если это необходимо. Он не будет переворачиваться так же, если вы поместите его в середину, а не в верхнюю часть слоя.   -  person guillaume    schedule 27.05.2013


Ответы (5)


Если я анимирую его, я использую что-то вроде этого в своих приложениях:

- (NSObject *) defineZRotation {
    // Define rotation on z axis
    float degreesVariance = 90;
    // object will always take shortest path, so that
    // a rotation of less than 180 deg will move clockwise, and more than will move counterclockwise
    float radiansToRotate = DegreesToRadians( degreesVariance );
    CATransform3D zRotation;
    zRotation = CATransform3DMakeRotation(radiansToRotate, 0, 0, 1.0);  
    // create an animation to hold "zRotation" transform
    CABasicAnimation *animateZRotation;
    animateZRotation = [CABasicAnimation animationWithKeyPath:@"transform"];
    // Assign "zRotation" to animation
    animateZRotation.toValue = [NSValue valueWithCATransform3D:zRotation];
    // Duration, repeat count, etc
    animateZRotation.duration = 1.5;//change this depending on your animation needs
    // Here set cumulative, repeatCount, kCAFillMode, and others found in
    // the CABasicAnimation Class Reference.
    return animateZRotation;
}

Конечно, вы можете использовать его где угодно, не обязательно возвращать его из метода, если он вам не подходит.

person Rab    schedule 29.07.2010
comment
Нет необходимости создавать объект CAAnimation для вращения представления. Для этого отлично работает animateWithDuration:animations. Смотрите мой ответ для более подробной информации. - person Duncan C; 17.05.2012
comment
@Duncan Я считаю, что этот метод применим только к UIView, а не к CALayer. Смотрите мой ответ на ваш ответ. - person Rab; 18.05.2012

Объект-C:

theLayer.transform = CATransform3DMakeRotation(90.0 / 180.0 * M_PI, 0.0, 0.0, 1.0);

Быстрый:

theLayer.transform = CATransform3DMakeRotation(90.0 / 180.0 * .pi, 0.0, 0.0, 1.0)

То есть преобразовать слой так, чтобы он повернулся на 90 градусов (π / 2 радиана), при этом 100% этого поворота происходили вокруг оси z.

person Jonathan Grynspan    schedule 29.07.2010
comment
M_PI имеет значение Double, а CATransform3DMakeRotation требует, чтобы угол был равен CGFloat, поэтому вместо него следует использовать CGFloat(M_PI) - person Mina Kolta; 04.08.2015
comment
В C преобразование из double в CGFloat является неявным (и приведения типов в C и Objective-C принимают форму (T)expression, а не T(expression). думаете о Swift или C++?) Кроме того, M_PI умножается на double в приведенном выше утверждении, поэтому оно расширяется, нарушая цель приведения. - person Jonathan Grynspan; 05.08.2015
comment
как заставить его вращаться, используя центр в качестве точки привязки? Его вращение весь слой - person apinho; 18.07.2016
comment
M_PI вызывает проблемы приведения в Swift и устарел в пользу Type.pi или просто .pi, которые будут использовать правильный тип (в данном случае CGFloat.pi). - person Abhi Beckert; 10.02.2018
comment
@apinho установил .anchor в центр кадра - person Fattie; 07.08.2019

В основном что-то вроде этого:

CGAffineTransform rotateTransform = CGAffineTransformMakeRotation(M_PI / 2.0); [myCALayer setAffineTransform:rotateTransform];

EDIT: он будет вращаться по часовой стрелке или против часовой стрелки в зависимости от платформы (iOS или Mac OS).

person SteamTrout    schedule 29.07.2010

Чтобы повернуться на 90' вправо:

myView.transform = CGAffineTransformMakeRotation(M_PI_2);
person Chris    schedule 13.11.2011

Раб показал, как это сделать с CAAnimation объектом. На самом деле все проще:

[myView animateWithDuration: 0.25 
  animations:
  ^{
     myView.transform = CGAffineTransformMakeRotation(M_PI/2);
   }
];

(подняв строку преобразования из ответа Криса - слишком ленив, чтобы переписать ее, так как он уже предоставил идеальный код.)

Код Криса вращал вид без анимации. Мой код выше будет делать то же самое с анимацией.

По умолчанию в анимациях используется ускорение, облегчение времени. Вы можете изменить это с помощью немного более сложной версии вызова animateWithDuration (вместо этого используйте animateWithDuration:delay:options:animations:completion: и передайте желаемое время в параметре options.)

person Duncan C    schedule 17.05.2012
comment
animateWithDuration:animations: блочный метод для UIView. Вопрос здесь в том, как анимировать CALayer — у CALayer нет этого метода, или, по крайней мере, он не задокументирован. Также в 2010 году метод animateWithDuration:animations: еще не существовал (и, я думаю, не делал ничего блочного в Obj-C)... так что это было бы скорее обновлением для 2012 года, если бы оно применялось. - person Rab; 18.05.2012
comment
также код Криса будет анимирован. со стандартной продолжительностью анимации CALayer. - person vikingosegundo; 13.01.2013
comment
Справедливо отметить, что блочной анимации, вероятно, не существовало в 2010 году, и что этот вопрос был конкретно задан о CALayer, а не о просмотре анимации. Анимации UIView в конечном итоге генерируют CAAnimations под обложками, но вы можете использовать анимацию UIView только в том случае, если слой, который вы хотите анимировать, является вспомогательным слоем представления. - person Duncan C; 02.06.2019
comment
@vikingosegundo, как и мой, код Криса изменяет преобразование вида, а не слоя. Я почти уверен, что изменение свойств вида не создает неявную анимацию, как это делает изменение свойств анимируемого слоя. (Это СТАРАЯ ветка, но кто-то только что проголосовал за мой ответ, что побудило меня вернуться к нему.) - person Duncan C; 02.06.2019