Clinton Lam Clinton Lam - 6 months ago 30
iOS Question

Basic swift layout having centred view with labels and text within by program

Why does this code gives out nothing when run? I want 2 labels, 2 textfield and a button to sit in view (container) which centred within the main view. Now when run the screen is plain white nothing there.

override func viewDidLoad() {

// User ID label
let userIDLabel:UILabel = UILabel()
userIDLabel.text = "User ID"

// Password label
let passwordLabel:UILabel = UILabel()
passwordLabel.text = "Password"

// User ID text
let userIDText:UITextField = UITextField()

// Password text
let passwordText:UITextField = UITextField()

// Login button
let loginBtn:UIButton = UIButton()
loginBtn.setTitle("Login", for: .normal)

// Container view
let container:UIView = UIView()
container.translatesAutoresizingMaskIntoConstraints = false

container.addSubview(userIDLabel)
container.addSubview(userIDText)
container.addSubview(passwordLabel)
container.addSubview(passwordText)
container.addSubview(loginBtn)

view.addSubview(container)


// Add constraints
let heightConstraint = NSLayoutConstraint(item: container, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 300)
let widthConstraint = NSLayoutConstraint(item: container, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 200)
let centerXConstraint = NSLayoutConstraint(item: container, attribute: .centerX, relatedBy: .equal, toItem: view, attribute: .centerX, multiplier: 1, constant: 0)
let centerYConstraint = NSLayoutConstraint(item: container, attribute: .centerY, relatedBy: .equal, toItem: view, attribute: .centerY, multiplier: 1, constant: 0)

container.addConstraint(heightConstraint)
container.addConstraint(widthConstraint)
view.addConstraint(centerXConstraint)
view.addConstraint(centerYConstraint)

}


EDIT: Thanks everyone. Now there the objects are showing after adding frames

// User ID label
let userIDLabel:UILabel = UILabel(frame: CGRect(x: 0.0, y: 0.0, width: 200.0, height: 50.0))
userIDLabel.text = "User ID"
// Password label
let passwordLabel:UILabel = UILabel(frame: CGRect(x: 0.0, y: 30.0, width: 200.0, height: 30.0))
passwordLabel.text = "Password"
// User ID text
let userIDText:UITextField = UITextField(frame: CGRect(x: 0.0, y: 60.0, width: 200.0, height: 30.0))
// Password text
let passwordText:UITextField = UITextField(frame: CGRect(x: 0.0, y: 90.0, width: 200.0, height: 30.0))
// Login button
let loginBtn:UIButton = UIButton(frame: CGRect(x: 0.0, y: 120.0, width: 100.0, height: 30.0))
loginBtn.setTitle("Login", for: .normal)


But the container is not vertically align to relative to the view as I would like to. The height/width of the view is fixed for now. Is there a way to make it dynamic, so that it knows the height it needed to hold all the labels and texts? I don not want to hardcode height/width.

Can height of view(grey backgroud) dynamic?


Answer Source

I would recommend using anchors. They always work perfect for me.

let someView = UIView()
someView.backgroundColor = .red
someView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(someView)
someView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
someView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
someView.heightAnchor.constraint(equalToConstant: 50).isActive = true
someView.widthAnchor.constraint(equalToConstant: 50).isActive = true

Important: note that translatesAutoresizingMaskIntoConstraints should be set fale for the view that your are trying to center

EDIT: You also need to set size and constraints to your labels and fields. Currently you don't have any frames for them. You can also instantiate the labels or fields with frames:

UILabel(frame: CGRect(x: 5.0, y: 5.0, width: 10.0, height: 10.0))
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download