使用约束旋转视图 - Swift

时间:2017-02-21 19:27:44

标签: ios uiview cgaffinetransform

我尝试使用约束在另一个视图的顶部旋转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))
}

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

From View A

To View B

我得到的是

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

1 个答案:

答案 0 :(得分:1)

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

或者,您可以连接变换并将中心移动到要旋转的点,执行旋转,然后反转您的平移(这实际上是使用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