Поверните UIView вокруг своего центра, сохраняя его размер

Я пытаюсь повернуть UIView несколько радианов, но после применения преобразования он не хочет сохранять свой размер. Каков правильный способ достижения этого?

Вот что я делаю и что получаю (синий ящик со стрелкой - это вид, который я пытаюсь повернуть - он должен сохранять тот же аспект, что и красный ящик):

#define DEGREES_TO_RADIANS(angle) ((angle) / 180.0 * M_PI)

double rads = DEGREES_TO_RADIANS(240);
CGAffineTransform transform = CGAffineTransformRotate(CGAffineTransformIdentity, rads);
self.arrowView.transform = transform;

enter image description here

Спасибо!

Ответ 1

Вероятно, вы столкнулись с проблемой с Autolayout. Вероятно, у вас есть ограничения на повернутое представление, прикрепляющее его к краям супервизора. Когда применяется преобразование, Autolayout обновляет размер представления, чтобы по-прежнему вписываться в супервизор.

Вы можете поэкспериментировать с различными ограничениями (например, привязать центр обзора к центру другого вида и привязать ширину и высоту к постоянным значениям) или отключить автоотключение для повернутого представления или, если это не так, работайте или не отвечайте вашим потребностям, используйте вид контейнера, который выложен в Autolayout, и добавьте к нему вращающийся вид, не используя Autolayout.

Это можно сделать только в коде - вы можете сделать отдельные просмотры объектами Autolayout или нет, установив translatesAutoresizingMasksIntoConstraints на NO (Автозапуск включен) или YES (Автоотключение выключено). Вам нужно будет установить соответствующие маски авторезистировки, если вы переключите представление из одного в другое.

Ответ 2

Я избегаю использования макросов, если это необходимо. Это прекрасно работает

float degrees = 20; //the value in degrees
view.transform = CGAffineTransformMakeRotation(degrees * M_PI/180);

Ответ 3

Swift + extension - ваши друзья!

// MARK: - UIView Extension -

extension UIView {

    /**
     Rotate a view by specified degrees

     - parameter angle: angle in degrees
     */
    func rotate(angle angle: CGFloat) {
        let radians = angle / 180.0 * CGFloat(M_PI)
        let rotation = CGAffineTransformRotate(self.transform, radians);
        self.transform = rotation
    }

}

Таким образом, в любом месте вашего кода:

let view = UIView(frame: CGRectMake(0, 0, 100, 100))
view.backgroundColor = UIcolor.redColor()
view.rotate(angle: 90)

Ответ 4

Преобразование CGAffineTransformRotate вращается от существующего аффинного преобразования. Возможно, проблема в том, что вы используете CGAffineTransformIdentity. Вы должны указать текущее преобразование вашего представления.

#define DEGREES_TO_RADIANS(angle) ((angle) / 180.0 * M_PI)
...
double rads = DEGREES_TO_RADIANS(240);
CGAffineTransform transform = CGAffineTransformRotate(self.arrowView.transform, rads);
self.arrowView.transform = transform;

Кроме того, вы можете рассмотреть:

self.arrowView.transform = CGAffineTransformMakeRotation(rads);

РЕДАКТИРОВАТЬ. Если вы можете, поделитесь тем, что вы вроде преобразуете (анимированный/неживой, одиночный/итеративный), который вы хотите достичь. Я считаю, что может быть лучший, оптимизированный способ сделать это.

Ответ 5

Попробуйте с помощью этого кода:

#define DEGREES_TO_RADIANS(angle) ((angle) / 180.0 * M_PI)

double rads = DEGREES_TO_RADIANS(240);
self.arrowView.layer.transform = CATransform3DMakeRotation(rads, 0, 0, 1);

Ответ 6

В Swift 3:

let degrees: CGFloat = -90
let radians = CGFloat(__sinpi(degrees.native/180.0))
view.transform = CGAffineTransform(rotationAngle: radians)

Я использую -90 из-за этой конкретной части документации о rotationAngle, которую вы должны передать на CGAffineTransform:

Угол в радианах, по которому эта матрица вращает координату системных осей. В iOS положительное значение указывает против часовой стрелки вращение и отрицательное значение указывает вращение по часовой стрелке.

Ответ 8

Обновление Лука Даванцо ответит с помощью Swift 4:

/**
 Rotate a view by specified degrees

 - parameter angle: angle in degrees
 */
func rotate(angle: CGFloat) {
    let radians = angle / 180.0 * CGFloat(Double.pi)
    let rotation = self.transform.rotated(by: radians)
    self.transform = rotation
}