背景:
我想显示一个顺时针旋转90度的标签。旋转后的标签应位于我指定的特定框架中。假设是(10,100,50,100)。
我知道我可以使用CGAffineTransform
来旋转视图。根据{{3}},我也知道我不应该在完成转换后设置frame
属性。
如果此属性的值不是恒等变换,则frame属性中的值是未定义的,应忽略。
我尝试在转换后设置框架,尽管它可以工作,但是我不想做文档告诉我不要做的事情。
label2.transform = CGAffineTransform(rotationAngle: -.pi / 2)
label2.frame = CGRect(x: 10, y: 100, width: 50, height: 100)
然后我想,我可以这样做:
CGRect
然后标签将位于所需的帧中。
所以我尝试了这样的事情:
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
。
我怀疑这是因为applying
中的CGRect
方法使矩形绕原点旋转,而不是矩形的中心旋转。因此,我尝试首先将rect转换为原点,旋转它,然后再将其转换回,如math.SE上的docs所述:
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
。
答案 0 :(得分:1)
我认为您的转换顺序不正确。如果这样做的话,
平移(x,y)*旋转(θ)*平移(-x,-y)
并与您的rotateRect
一起使用似乎正常。因为您将视图旋转了90度,所以蓝色视图完全阻止了红色视图。以其他角度尝试一下,您会更加明显地看到效果。
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)
}
答案 1 :(得分:0)
由于我只想将视图旋转90度,因此初始框架的宽度和高度将与旋转框架的宽度和高度相反。
初始帧的中心和旋转的中心相同,因此我们可以在变换之前将标签的center
设置为所需帧的中心。
let desiredFrame = CGRect(x: 10, y: 100, width: 50, height: 100)
let label1 = UIView(frame: desiredFrame)
// get the centre of the desired frame
// this is also equal to label1.center
let center = CGPoint(x: desiredFrame.midX, y: desiredFrame.midY)
let label2Frame = CGRect(x: 0, y: 0, width: desiredFrame.height, height: desiredFrame.width)
let label2 = UIView(frame: label2Frame)
view.addSubview(label1)
view.addSubview(label2)
label1.backgroundColor = .red
label2.backgroundColor = .blue
label2.center = center // set the centre of label2 before the transform
label2.transform = CGAffineTransform(rotationAngle: -.pi / 2)