苹果文件说:
在iOS 8.0和更高版本中,transform属性不会影响“自动布局”。自动布局会根据视图的未变形帧来计算视图的对齐矩形。
因此,如果我有一个名为 View1
的视图,该视图通过使用transform属性和 View2
< / em> 要与 View1
的边缘对齐。我该如何使用 AutoLayout
?
答案 0 :(得分:3)
好问题。正如您所引用的,约束条件适用于视图的原始未变换范围。
为了能够使您的其他视图尊重变换后的边界,一种方法是在应用变换后计算约束常数的偏移量。下面是一个与您的情况类似的示例,但有一个最大的约束,而不是 leading / trailing / align 。但基本上,您也可以对其他情况应用相同的过程。
这暂时有效,请随时改进此答案。
故事板设置:
应用(scaleX:3, scaleY:2.5)
变换后的输出。
我们在下面的代码中所做的是:
IBOutlet
。注意::根据Apple文档,它说:
警告
当此属性的值不是 身份转换,未定义frame属性中的值,并且 应该被忽略。
但是在应用比例尺后,转换后的框架似乎可以使用。因此,我们将其保存到变量中以备将来使用。如果尝试访问其他位置的框架,则不会获得正确的框架。因此,我们在应用转换后立即执行此步骤。
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 限制条件(可能是更优雅的解决方案。至于动画,很遗憾,我无法提供解决方法。如果发现一些会更新。谢谢。