Поверните 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;
Спасибо!
8 ответов
Вы, вероятно, столкнулись с проблемой с Autolayout. Вероятно, у вас есть ограничения на повернутый вид, прикрепляющий его к краям суперпредставления. Когда преобразование применено, Autolayout обновляет размер представления, чтобы все еще соответствовать в суперпредставлении.
Вы можете поэкспериментировать с другими ограничениями (например, закрепить центр вида в центре другого вида и закрепить ширину и высоту в постоянных значениях) или отключить автоматическое расположение для повернутого вида, или, если они не работают или не работают в соответствии с вашими потребностями, используйте вид контейнера, который выложен под Autolayout, и добавьте в него свой вращающийся вид, не используя Autolayout.
Это может быть сделано только в коде - вы можете сделать отдельные представления подлежащими автоматической разметке или нет, установив translatesAutoresizingMasksIntoConstraints
в NO
(Autolayout on) или YES
(Автопрокат выключен). Вам нужно будет установить соответствующие маски автоматического изменения размера, если вы переключаете представление с одного на другое.
Я избегаю использования макросов без необходимости. Это отлично работает
float degrees = 20; //the value in degrees
view.transform = CGAffineTransformMakeRotation(degrees * M_PI/180);
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.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)
Обновите ответ Луки Давандзо со Swift 4:
/**
Rotate a view by specified degrees
- parameter angle: angle in degrees
*/
func rotate(angle: CGFloat) {
let radians = angle / 180.0 * CGFloat.pi
let rotation = self.transform.rotated(by: radians)
self.transform = rotation
}
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:
extension UIView {
func setTransformRotation(toDegrees angleInDegrees: CGFloat) {
let angleInRadians = angleInDegrees / 180.0 * CGFloat.pi
let rotation = self.transform.rotated(by: angleInRadians)
self.transform = rotation
}
}
Попробуйте с этим кодом:
#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);
Swift5
Повернуть UIView вверх ногами
let degrees:CGFloat = -180 //angle to convert upside down
rotatingUI.transform = CGAffineTransform(rotationAngle: degrees * CGFloat(Double.pi)/180);
На Свифте 3:
let degrees: CGFloat = -90
let radians = CGFloat(__sinpi(degrees.native/180.0))
view.transform = CGAffineTransform(rotationAngle: radians)
я использую -90
из-за этой конкретной части документации о rotationAngle
Вы должны перейти к CGAffineTransform
:
Угол в радианах, на который эта матрица поворачивает оси системы координат. В iOS положительное значение указывает вращение против часовой стрелки, а отрицательное значение указывает вращение по часовой стрелке.
На мой взгляд, вам нужно рассчитать центр вашего треугольника и вращаться вокруг этой точки. Теперь вы вращаете стрелку вокруг центра вашего квадрата.
Смотрите: Один шаг аффинного преобразования для вращения вокруг точки?
Надеюсь, это поможет вам.