iOS - 以编程方式使用自动布局将 UIView 定位在超级视图的中心
Posted
技术标签:
【中文标题】iOS - 以编程方式使用自动布局将 UIView 定位在超级视图的中心【英文标题】:iOS - Position UIView in center of superview using Auto Layout programmatically 【发布时间】:2012-12-23 13:36:59 【问题描述】:如何使用 Auto Layout 以编程方式将 UIView 设置为位于其父视图的中心?
UIButton* viewObj = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[viewObj setTranslatesAutoresizingMaskIntoConstraints:NO];
[viewObj setBackgroundColor:[UIColor greenColor]];
[self.view addSubview:viewObj];
NSLayoutConstraint* cn = [NSLayoutConstraint constraintWithItem:viewObj
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0];
[self.view addConstraint:cn];
cn = [NSLayoutConstraint constraintWithItem:viewObj
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterY
multiplier:1.0
constant:0];
[self.view addConstraint:cn];
上面的代码适用于 UIButton,但我无法用适用于 UIView 的内容替换第一行。
我试过了
UIView* viewObj = [UIView alloc] initWithFrame:CGRectZero];
但视图没有显示在模拟器中。
有什么建议吗?
谢谢!
【问题讨论】:
总是尝试格式化您的问题,以便人们易于阅读(即没有水平滚动).. 它只是让 SO 更方便 【参考方案1】:由于您在使用 Auto Layout 的上下文中提出了这个问题,因此这里的问题是 UIButton 具有一个固有大小(通过 intrinsicContentSize 方法进行通信),它为 Auto Layout 提供有关宽度和高度的信息,但 UIView 通常会这样做不是。所以你需要添加更多与宽度和高度相关的约束。
如果你希望你的 UIView 是一个固定的尺寸(比如,200x200),你可以添加这些行:
cn = [NSLayoutConstraint constraintWithItem:viewObj
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1
constant:200];
[viewObj addConstraint:cn];
cn = [NSLayoutConstraint constraintWithItem:viewObj
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1
constant:200];
[viewObj addConstraint: cn];
请注意toItem:
参数是nil
,第二个属性是NSLayoutAttributeNotAnAttribute
,因为您没有指定相对于其他任何内容的宽度和高度。如果您希望子视图的高度和宽度相对于父视图(例如 0.5),您可以这样做:
cn = [NSLayoutConstraint constraintWithItem:viewObj
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeHeight
multiplier:0.5
constant:0];
[self.view addConstraint:cn];
cn = [NSLayoutConstraint constraintWithItem:viewObj
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeWidth
multiplier:0.5
constant:0];
[self.view addConstraint: cn];
【讨论】:
如果你想将它居中到某个位置,比如“x”中的 200 和“y”中的 350 怎么办? 我不认为自动布局是为了处理像素完美而设计的,它是为了适应而设计的。如果你愿意,你应该把它关掉,anth。 重新像素完美:它处理得很好......你只需要重新思考你想要什么。将父视图定位在您想要的位置,然后在其中居中可以解决一些问题。【参考方案2】:UIButton
、UIImageView
、UIlabel
和 UITextField
可以根据其内容属性自动设置其大小。 UIImageView
的宽度和高度由它可能包含的 UIImage
设置。 UILabel
的大小将取决于其文本。 UIButton
的宽度和高度由标题和它拥有的图像定义(您可以通过 Intrinsic Content Size 了解更多信息)。
因此,当您想使用自动布局将UIButton
、UILabel
、UITextField
或UIImageView
居中时,几乎在所有情况下都不必创建约束因为它们的宽度和高度。您只需为它们设置水平和垂直约束。
但是,对于自动布局,没有子视图的UIView
不能依赖任何东西来设置其大小,除非您为其提供任意宽度和高度约束。根据您的需要,您可以通过 3 种不同的方式解决此问题。
纯自动布局风格
这里,我们直接将UIView
的宽度和高度设置为自动布局约束:
override func viewDidLoad()
super.viewDidLoad()
let newView = UIView()
newView.backgroundColor = .redColor()
newView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(newView)
// Auto layout code using anchors (ios9+)
let horizontalConstraint = newView.centerXAnchor.constraintEqualToAnchor(view.centerXAnchor)
let verticalConstraint = newView.centerYAnchor.constraintEqualToAnchor(view.centerYAnchor)
let widthConstraint = newView.widthAnchor.constraintEqualToAnchor(nil, constant: 100)
let heightConstraint = newView.heightAnchor.constraintEqualToAnchor(nil, constant: 100)
NSLayoutConstraint.activateConstraints([horizontalConstraint, verticalConstraint, widthConstraint, heightConstraint])
自动调整大小的蒙版样式
在这里,我们用它的宽度和高度初始化我们的UIView
,使其中心和它的父视图的中心相等,并创建一些自动调整大小的蒙版。然后,我们要求 UIKit 将这些自动调整大小的掩码转换为自动布局约束:
override func viewDidLoad()
super.viewDidLoad()
let newView = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 100.0, height: 100.0))
newView.backgroundColor = .redColor()
newView.center = CGPointMake(view.bounds.midX, view.bounds.midY)
newView.autoresizingMask = [.FlexibleLeftMargin, .FlexibleRightMargin, .FlexibleTopMargin, .FlexibleBottomMargin]
newView.translatesAutoresizingMaskIntoConstraints = true // default is true
view.addSubview(newView)
子类风格
在这里,我们创建UIView
的子类并覆盖其intrinsicContentSize()
方法(declaration),使其返回所需的大小:
import UIKit
class CustomView: UIView
override func intrinsicContentSize() -> CGSize
return CGSize(width: 100, height: 100)
class ViewController: UIViewController
override func viewDidLoad()
super.viewDidLoad()
let newView = CustomView()
newView.backgroundColor = .redColor()
newView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(newView)
let horizontalConstraint = NSLayoutConstraint(item: newView,
attribute: .CenterX,
relatedBy: .Equal,
toItem: view,
attribute: .CenterX,
multiplier: 1,
constant: 0)
view.addConstraint(horizontalConstraint)
let verticalConstraint = NSLayoutConstraint(item: newView,
attribute: .CenterY,
relatedBy: .Equal,
toItem: view,
attribute: .CenterY,
multiplier: 1,
constant: 0)
view.addConstraint(verticalConstraint)
【讨论】:
以上是关于iOS - 以编程方式使用自动布局将 UIView 定位在超级视图的中心的主要内容,如果未能解决你的问题,请参考以下文章