使用约束旋转视图 - 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 变换的典型方法)。
更新:
这里是游乐场。请注意,您以希望应用转换的相反顺序连接矩阵。我在这里有一个动画,因此您可以分解变换并查看每个变换的作用:
- 将视图移动到原点 (0,0)(这是最后一个变换)
- 顺时针旋转视图 90 度
将视图向下移动其当前宽度的一半,使其位于父视图的底部。
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
我正在尝试使用约束在另一个视图之上旋转一个 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 变换的典型方法)。
更新: 这里是游乐场。请注意,您以希望应用转换的相反顺序连接矩阵。我在这里有一个动画,因此您可以分解变换并查看每个变换的作用:
- 将视图移动到原点 (0,0)(这是最后一个变换)
- 顺时针旋转视图 90 度
将视图向下移动其当前宽度的一半,使其位于父视图的底部。
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