使用约束旋转视图 - Swift

Rotating view using constraints - Swift

我正在尝试使用约束在另一个视图之上旋转一个 uiview。这是我实现的

mediaContainer.addSubview(overlayView)
keepBottomLeft()
overlayView.layoutIfNeeded()

func keepBottomLeft(overlayView: UIView) {
    NSLayoutConstraint(item: overlayView, attribute:.width, relatedBy:.equal,toItem: mediaContainer, attribute:.width, multiplier: 0.8, constant: 0).isActive = true
    NSLayoutConstraint(item: overlayView, attribute:.leading, relatedBy:.equal, toItem: mediaContainer, attribute:.leading, multiplier: 1, constant: 0).isActive = true
    NSLayoutConstraint(item: overlayView, attribute:.height, relatedBy:.equal,toItem: nil, attribute:.notAnAttribute, multiplier: 1.0, constant: 26).isActive = true
    NSLayoutConstraint(item: overlayView, attribute:.bottom, relatedBy:.equal, toItem: mediaContainer, attribute:.bottom, multiplier: 1, constant: 0).isActive = true
    overlayView.transform = CGAffineTransform(rotationAngle: CGFloat(-M_PI_2))
}

是否需要使用锚点?这就是我要实现的目标?

我得到的是

有人能指出我正确的方向吗?

您的锚点位于黄色视图的中心;默认值。要么你想用 layer.anchorPoint = CGPoint(x: 0, y:1) 将它移动到左下角 [注意锚点是单位坐标形式 0 到 1,而不是点]。您仍然需要额外翻译 x = height.

或者你可以连接你的变换并将你的中心移动到你想要旋转的点,执行旋转,然后反转你的平移(这实际上是 3d 变换的典型方法)。

更新: 这里是游乐场。请注意,您以希望应用转换的相反顺序连接矩阵。我在这里有一个动画,因此您可以分解变换并查看每个变换的作用:

  1. 将视图移动到原点 (0,0)(这是最后一个变换)
  2. 顺时针旋转视图 90 度
  3. 将视图向下移动其当前宽度的一半,使其位于父视图的底部。

    import PlaygroundSupport
    import UIKit
    class V: UIViewController {
       var overlayView = UIView()
        override func viewDidLoad() {
            super.viewDidLoad()
            overlayView.translatesAutoresizingMaskIntoConstraints = false
            view.addSubview(overlayView)
            overlayView.backgroundColor = .yellow
            overlayView.heightAnchor.constraint(equalToConstant: 26).isActive = true
            overlayView.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.8).isActive = true
            overlayView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
            overlayView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        }
        override func viewDidAppear(_ animated: Bool) {
            UIView.animate(withDuration: 1) {
                let center = self.overlayView.center
                let size = self.overlayView.bounds.size
                self.overlayView.transform =
                    CGAffineTransform(translationX: self.view.bounds.size.height - size.width / 2, y: -size.height/2)
                    .concatenating(CGAffineTransform(rotationAngle: CGFloat.pi/2)
                    .concatenating(CGAffineTransform(translationX: -center.x, y: -center.y)))
            }
        }
    }
    
    let v = V()
    v.view.frame = CGRect(x: 0, y: 0, width: 200, height: 200)
    PlaygroundPage.current.liveView = v