我想关闭自动布局一段时间,并使用bounds
,center
和transformation
来处理UIView的大小和位置。
我有一个非常简单的“单视图应用程序”示例。我的应用程序有一个托管主视图的视图控制器。在该视图中有两个按钮和另一个视图(背景设置为粉红色),后者又包含一个图像视图(设置为宽高比):
我已经将我的问题提炼成一个非常简单的UIViewController:
@IBOutlet weak var imageHolderView: UIView!
@IBOutlet weak var imageView: UIImageView!
@IBAction func loadImageButtonClicked(sender: AnyObject) {
let url = NSURL(string: "https://c2.staticflickr.com/4/3909/15110089915_21a12eba6a_k.jpg")
let data = NSData(contentsOfURL: url!)
self.imageView.image = UIImage(data: data!)
}
@IBAction func clearConstraintsButtonClicked(sender: AnyObject) {
let bounds:CGRect = self.imageHolderView.bounds
let center:CGPoint = self.imageHolderView.center
NSLayoutConstraint.deactivateConstraints(self.imageHolderView.constraints)
self.imageHolderView.bounds = bounds
self.imageHolderView.center = center
}
N.B。我试图在一个更复杂的项目中理解这一点,这里的例子只是为了证明这个问题。
当我运行项目时,图像没有来源,所以粉红色的UIView(imageHolderView
)占据了预期的大部分屏幕:
当我单击加载图像按钮时,控制器将图像从Web加载到UIImageView中。因为约束仍然存在,所以自动布局确保图片在UIImageView中被方面拟合约束到其超级视图imageHolderView
:
如果我现在清除约束,我希望看到没有区别,因为自动布局设置的约束会立即在代码中被相同的值替换。但那不是我所看到的:
如何抓取自动布局设置的UIView的边界和中心,关闭UIView的自动布局,然后从我自己的swift代码重新建立边界和居中?
在调试器中查看UIView imageHolderView
上的边界是正确的,并且UIImageView imageView
上的约束几乎(*)仍然存在(我希望将UIImageView限制为适合UIView),但UIImageView上的界限已经增长,以适应全尺寸图像。为什么呢?
(在更复杂的应用程序中,我继续调整大小,旋转和转换视图。Apple's documentation声明“如果transform属性包含非标识变换,则为frame属性的值未定义且不应修改。在这种情况下,您可以使用center属性重新定位视图,并使用bounds属性调整大小。“示例代码不使用转换,但正如我所说的我的真实代码所做的;我认为这使我无法设置框架。)
(*)我差点说,因为UIImageView有四个约束,但在调试器中,计数是两个。
答案 0 :(得分:3)
有几件事你忘记了。
首先,在:
NSLayoutConstraint.deactivateConstraints(self.imageHolderView.constraints)
确保您没有停用所需的约束。例如。如果您在imageHolderView
上有宽度或高度限制,则可以使用此调用停用它。
在:
let bounds:CGRect = self.imageHolderView.bounds
let center:CGPoint = self.imageHolderView.center
NSLayoutConstraint.deactivateConstraints(self.imageHolderView.constraints)
self.imageHolderView.bounds = bounds
self.imageHolderView.center = center
您正在获取bounds
的{{1}}和center
,然后您尝试将它们分配回imageHolderView
。这是错误的,因为您正在停用设置imageHolderView
位置的约束。您不必更改imageView
的位置,因为它的约束会保存在其超级视图中。另一方面,self.imageHolderView
可能已禁用所有约束,因此您应该设置其位置:
self.imageView
self.imageView.bounds = bounds
self.imageView.center = center
设置错误,因为在其超级视图的坐标系中指定了center
。您应该从imageHolderView.center
手动计算中心。
bounds
然而,最大的问题可能是这样的事实:默认情况下,在启用了autolayout的storyboard / xib中创建的任何视图中,self.imageView.center = CGPointMake(bounds.size.width / 2, bounds.size.height / 2)
和bounds
(或center
)都会被忽略
您必须手动将frame
设置为imageView.translatesAutoresizingMaskIntoConstraints
。否则布局管理器将忽略true
。
答案 1 :(得分:2)
不要设置边界,而是设置框架。试试这个:
@IBAction func clearConstraintsButtonClicked(sender: AnyObject) {
let frame = self.imageHolderView.frame
NSLayoutConstraint.deactivateConstraints(self.imageHolderView.constraints)
self.imageHolderView. frame = frame
}
答案 2 :(得分:2)
由于您正在清除视图的包含内容,因此它将删除其子视图的垂直和水平拥抱约束。你可以通过自定义你的持有人来解决这个问题,
class CustomHolderView: UIView {
@IBOutlet weak var imageView: UIImageView!
override func layoutSubviews() {
super.layoutSubviews()
self.imageView.frame = self.bounds
}
}
在holder holder视图layoutSubviews方法中,您应该为图像视图设置框架。
答案 3 :(得分:1)
UIImageView
会根据其大小调整掩码及其contentMode自动添加约束。尝试将其contentMode设置为AspectFit
或AspectFill
并操纵其frame
而不是bounds
。