【问题标题】:Rotate UIView around its center keeping its size围绕其中心旋转 UIView 保持其大小
【发布时间】:2014-02-17 16:38:41
【问题描述】:

我正在尝试将 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;

谢谢!

【问题讨论】:

  • 您忘记调用宏了吗?例如。 CGAffineTransform 变换 = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(45));
  • @Marco 抱歉,我正在编辑问题。我没有使用宏,但仍无法按预期工作。
  • 你需要这样做,因为 CGAffineTransformMakeRotation 的参数是弧度。
  • @Marco 你是对的,我的错。现在它似乎并没有将其中心作为问题,但是在旋转后它仍在调整大小。我已经根据问题相应地更新了代码。

标签: ios objective-c uiview rotation


【解决方案1】:

除非必要,否则我会避免使用宏。这很好用

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

【讨论】:

    【解决方案2】:

    Swift + 扩展是你的朋友!

    // MARK: - UIView Extension -
    
    extension UIView {
    
        /**
         Rotate a view by specified degrees
    
         - parameter angle: angle in degrees
         */
        func rotate(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)
    

    【讨论】:

    • 我会将其重命名为setRotation,因为rotate 听起来您将其旋转了某个角度。 IE。调用rotate 两次会将其旋转两次,但它不会这样做。
    【解决方案3】:

    您可能在使用自动布局时遇到了问题。您可能对旋转视图有约束,将其固定到超级视图的边缘。应用转换时,自动布局正在更新视图的大小以仍然适合超级视图。

    您可以尝试不同的约束条件(例如,将视图的中心固定到另一个视图的中心,并将宽度和高度固定为恒定值)或为旋转的视图关闭自动布局,或者,如果这些没有工作或不适合您的需要,请使用在 Autolayout 下布置的容器视图,并将您的旋转视图添加到其中,而不使用 Autolayout。

    这只能在代码中完成 - 您可以通过将 translatesAutoresizingMasksIntoConstraints 设置为 NO(自动布局开启)或 YES(自动布局关闭)来使单个视图受制于自动布局或不受制于自动布局。如果您将视图从一个切换到另一个,则需要设置适当的自动调整大小掩码。

    【讨论】:

    • 谢谢!。这正是我一直在寻找的。添加这一行解决了我的问题: [self.arrowView setTranslatesAutoresizingMaskIntoConstraints:YES];没有任何方法可以将这一点可视化或从 IB 改变吗?
    • 使用 IB,全部是自动布局或没有自动布局。很高兴它起作用了,这有点猜测,但几天前我遇到了完全相同的问题。
    • translatesAutoresizingMaskIntoConstraints 不是translatesAutoresizingMasksIntoConstraints
    【解决方案4】:

    用 Swift 4 更新 Luca Davanzo 的答案:

    /**
     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
    }
    

    【讨论】:

      【解决方案5】:

      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);
      

      编辑 :如果可以,请分享您想要实现的转换类型(动画/无生命,单一/迭代)。我相信可能有更好的优化方式来做到这一点。

      【讨论】:

        【解决方案6】:

        斯威夫特 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
            }
        }
        

        【讨论】:

          【解决方案7】:

          试试这个代码:

          #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);
          

          【讨论】:

          • 我得到了完全相同的结果。
          【解决方案8】:

          在 Swift 3 上:

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

          我正在使用-90,因为您必须将有关rotationAngle 的文档的这个特定部分传递给CGAffineTransform:

          这个矩阵旋转坐标的角度,以弧度为单位 系统轴。在 iOS 中,正值指定逆时针方向 旋转,负值指定顺时针旋转。

          【讨论】:

            【解决方案9】:

            Swift5

            翻转 UIView

            let degrees:CGFloat = -180 //angle to convert upside down
            rotatingUI.transform = CGAffineTransform(rotationAngle: degrees * CGFloat(Double.pi)/180);
                
            

            【讨论】:

            • CGFloat 有一个pi 属性:CGFloat.pi 所以你不必从Double.pi 转换
            【解决方案10】:

            在我看来,您需要计算三角形的中心并围绕该点旋转。现在您围绕正方形的中心旋转箭头。

            见:One step affine transform for rotation around a point?

            希望对你有帮助。

            【讨论】:

            • 感谢您链接到该答案,我已尝试实施该解决方案,但是旋转后箭头仍在调整大小。
            猜你喜欢
            • 2010-10-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-04-19
            相关资源
            最近更新 更多