苹果文件说:
In iOS 8.0 and later, the transform property does not affect Auto Layout. Auto layout calculates a view’s alignment rectangle based on its untransformed frame.
所以,如果我有一个名为 View1
的 View ,它通过使用 transform 属性进行缩放,并且 View2
想要与 View1
的边缘对齐。如何使用 AutoLayout
做到这一点?
好问题。正如您所引用的,约束适用于 View 的原始未转换边界。
为了能够使您的其他 View 尊重转换后的边界,一种方法是在应用转换后计算约束常量的偏移量。下面是与您的情况类似的示例,但有一个顶部约束,而不是 leading/trailing/align。但基本上你也可以对其他情况应用相同的程序。
这暂时有效,请随时改进此答案。
Storyboard设置:
应用(scaleX:3, scaleY:2.5)的变换后的输出
.
我们在下面的代码中做的是:
IBOutlet
。注意:根据 Apple 文档,它说:
Warning
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.
但转换后的框架似乎在应用比例后立即可用。所以我们将它保存到一个变量中以备将来使用。如果您尝试访问其他地方的框架,您将无法获得正确的框架。因此,我们在应用转换后立即执行此步骤。
updateViewConstraints
方法,您有机会更新约束。现在我们只需将两帧底部位置的差值应用到 IBOutlet
的约束常量上。import UIKit
class ViewController: UIViewController {
@IBOutlet weak var view1: UIView! //Dark gray view
@IBOutlet weak var view2: UIView! //Light gray view
@IBOutlet weak var topConstraint: NSLayoutConstraint!
let transformScaleX:CGFloat = 3
let transformScaleY:CGFloat = 2.5
var rectBeforeTransform:CGRect = .zero
var rectAfterTransform:CGRect = .zero
var originalTopConstraintConstant:CGFloat = 0
override func viewDidLoad() {
super.viewDidLoad()
//Store original constraint value
self.originalTopConstraintConstant = self.topConstraint.constant
//Store unaltered frame of the view
self.rectBeforeTransform = view1.frame
//Apply transform
self.view1.transform = .init(scaleX: transformScaleX, y: transformScaleY)
//Frame after transform.
//NOTE: When a non-identity transform is applied to a view, its frame is undefined, so we would not get proper frame info. of the view anywhere other than after applying the tranform.
self.rectAfterTransform = view1.frame
}
override func updateViewConstraints() {
DispatchQueue.main.async {
let constraintOffset = abs(self.rectAfterTransform.bottomY - self.rectBeforeTransform.bottomY)
self.topConstraint.constant = self.originalTopConstraintConstant + constraintOffset
}
super.updateViewConstraints()
}
}
extension CGRect {
var bottomY:CGFloat {
get {
return self.height + self.origin.y
}
}
}
PS:当前答案仅适用于顶部约束,我将尝试更新所有 leading/trailing/top/bottom 约束的答案,可能还有一个更优雅的解决方案。至于动画,不幸的是我无法提供一种方法。如果我找到一些会更新。谢谢。
关于ios - 如何使用带有变换的 AutoLayout,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53111763/
欢迎光临 OGeek|极客世界-中国程序员成长平台 (http://jike.in/) | Powered by Discuz! X3.4 |