ios - 如何围绕其中心旋转 CGRect?

标签 ios swift cgaffinetransform cgrect

背景:

我想显示一个顺时针旋转 90 度的标签。旋转的标签应该在我指定的某个框架中。比方说 (10, 100, 50, 100)。

我知道我可以使用 CGAffineTransform 旋转 View 。我还知道,根据 docs,我不应该在转换完成后设置 frame 属性。 .

When the value of this property is anything other than the identity transform, the value in the frame property is undefined and should be ignored.

我尝试在转换后设置框架,虽然它有效,但我不想做文档告诉我不要做的事情。

label2.transform = CGAffineTransform(rotationAngle: -.pi / 2)
label2.frame =  CGRect(x: 10, y: 100, width: 50, height: 100)

然后我想,我可以这样做:

  1. 创建一个我想要的框架的CGRect
  2. 逆时针旋转90度
  3. 将其设置为标签的框架
  4. 将标签顺时针旋转90度

然后标签将位于所需的框架中。

所以我尝试了这样的事情:

    let desiredFrame = CGRect(x: 10, y: 100, width: 50, height: 100) // step 1
    // I am using UIViews here because I am just looking at their frames
    // whether it is a UIView or UILabel does not matter
    // label1 is a view that is in the desired frame but not rotated
    // If label2 has the correct frame, it should completely cover label1
    let label1 = UIView(frame: desiredFrame)
    let label2Frame = rotateRect(label1.frame) // step 2
    let label2 = UIView(frame: label2Frame) // step 3
    view.addSubview(label1)
    view.addSubview(label2)
    label1.backgroundColor = .red
    label2.backgroundColor = .blue
    label2.transform = CGAffineTransform(rotationAngle: -.pi / 2) // step 4

rotateRect 声明如下:

func rotateRect(_ rect: CGRect) -> CGRect {
    return rect.applying(CGAffineTransform(rotationAngle: .pi / 2))
}

这没有用。 label2 根本不与 label1 重叠。我什至在屏幕上根本看不到 label2

我怀疑这是因为 CGRect 中的 applying 方法围绕原点而不是中心旋转矩形。所以我试着先将矩形变换到原点,旋转它,然后再变换回来,就像这个 post在 math.SE 上说:

func rotateRect(_ rect: CGRect) -> CGRect {
    let x = rect.x
    let y = rect.y
    let transform = CGAffineTransform(translationX: -x, y: -y)
                        .rotated(by: .pi / 2)
                        .translatedBy(x: x, y: y)
    return rect.applying(transform)
}

但是,我仍然无法在屏幕上看到 label2

最佳答案

我认为您的转换顺序不正确。如果你这样做,那,

Translate(x, y) * Rotate(θ) * Translate(-x, -y)

将它与您的 rotateRect 一起使用似乎可以正常工作。因为,您将 View 旋转 90 度,蓝色 View 完全阻挡红色 View 。换个角度试试,效果会更明显。

func rotateRect(_ rect: CGRect) -> CGRect {
    let x = rect.midX
    let y = rect.midY
    let transform = CGAffineTransform(translationX: x, y: y)
                                    .rotated(by: .pi / 2)
                                    .translatedBy(x: -x, y: -y)
    return rect.applying(transform)
}

关于ios - 如何围绕其中心旋转 CGRect?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54956827/

相关文章:

ios - CGAffineTransformMakeRotation 再次不起作用

ios - 沿弧定位 CATextLayers

ios - 为什么我的服务器证书被拒绝?

ios - 我可以隐藏试飞按钮吗

ios - 如何处理 iOS 中的未读推送通知?

iphone - NSString 如何去除常规\转义字符?

ios - 从另一个应用程序打开时,在 applicationWillTerminate 之后以首选状态打开应用程序?

ios - 在 UIView 上应用渐变不起作用

iphone - MKMapview 变换仅旋转 map 内容

swift - 你需要在 Swift 中声明变量的数据类型吗?