Suppose I want to add a UIBUtton
programmatically. Every UIView
constructor requires a CGFrame
, but in my case I want the size to be intrinsic and the location to be anchored to the super view's center.
UIBUtton
element without supplying a frame, I see it in the debug view hierarchy but not on the screen.x,y
values brake the constraint I later add.What is the proper way to add a button programmatically?
Thanks!
EDIT: There's no problem instantiating without a CGFrame
. I didn't see the button because I didn't add
button.translatesAutoresizingMaskIntoConstraints = false
which is done automatically by the interface builder.
If you're using auto layout, set translateAutoResizingMaskIntoConstraints
to false
and ignore the frame, but don't forget to add constraints manually.
Here is a simple example:
override func viewDidLoad() {
super.viewDidLoad()
// no auto layout
let v = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
v.backgroundColor = UIColor.blue
view.addSubview(v)
// with auto layout
let v2 = UIView()
v2.backgroundColor = UIColor.red
// use auto layout
v2.translatesAutoresizingMaskIntoConstraints = false
// add width / height constraints
v2.addConstraint(NSLayoutConstraint(item: v2, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 100))
v2.addConstraint(NSLayoutConstraint(item: v2, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 100))
// must add to hirarchy before adding the following constraints
view.addSubview(v2)
view.addConstraint(NSLayoutConstraint(item: v2, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1, constant: 100))
view.addConstraint(NSLayoutConstraint(item: v2, attribute: .top, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1, constant: 0))
// auto layout, visual format
let v3 = UIView()
v3.translatesAutoresizingMaskIntoConstraints = false
v3.backgroundColor = UIColor.green
let views = [ "v3" : v3 ]
// must add v3 as subview before adding constraints referencing the parent view
view.addSubview(v3)
view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-200-[v3(100)]", options: [], metrics: nil, views: views))
view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[v3(100)]", options: [], metrics: nil, views: views))
}
For many views, there's no need to specify size as some views provide the size they want with intrinsicContentSize
.
You can use that for buttons to make them take the size they 'need', or force another size using constraints.
For custom views - you may override this property to provide your own 'needed size' logic.