-1

I am trying to create a button using programmed constraints. I am trying to not use the storyboard. I am having trouble unwrapping the button. How do I do this?

import UIKit

var aa: [NSLayoutConstraint] = []

class ViewController: UIViewController {

    var btn: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()

        self.view.addSubview(btn)
        let leadingc2 = btn.widthAnchor.constraint(equalToConstant: 80)
        let trailingC2 = btn.heightAnchor.constraint(equalToConstant: 50)
        let topc2 = btn.centerXAnchor.constraint(equalTo: self.view.centerXAnchor, constant: -50)
        let bottomc2 = btn.centerYAnchor.constraint(equalTo: self.view.centerYAnchor, constant: -250)

        aa = [leadingc2,trailingC2,topc2,bottomc2]

        NSLayoutConstraint.activate(aa)
    }
}
Lukas Würzburger
  • 6,543
  • 7
  • 41
  • 75

2 Answers2

2

You do not need to unwrap it. You need to instantiate it before using it.

override func viewDidLoad() {
    super.viewDidLoad()

    btn = UITextField() // Create the button like this before using it.
    self.view.addSubview(btn)

    btn.translatesAutoresizingMaskIntoConstraints = false
    let leadingc2 = btn.widthAnchor.constraint(equalToConstant: 80)
    let trailingC2 = btn.heightAnchor.constraint(equalToConstant: 50)
    let topc2 = btn.centerXAnchor.constraint(equalTo: self.view.centerXAnchor, constant: -50)
    let bottomc2 = btn.centerYAnchor.constraint(equalTo: self.view.centerYAnchor, constant: -250)

    aa = [leadingc2,trailingC2,topc2,bottomc2]

    NSLayoutConstraint.activate(aa)

}

Any variable declared with ! will be force unwrapped, meaning that if you forget to create an instance and use the variable, it will throw an error and crash your app.

Alex Kolovatov
  • 859
  • 7
  • 12
Rakesha Shastri
  • 11,053
  • 3
  • 37
  • 50
  • @AlexKolovatov and which constraint is giving you the error? – Rakesha Shastri Aug 27 '18 at 04:23
  • you just forgot to add this line. btn.translatesAutoresizingMaskIntoConstraints = false – Alex Kolovatov Aug 27 '18 at 06:01
  • @AlexKolovatov Yes, but the answer is not for constraints. It is for button crashing because it doesn't have an instance. I just added rest of OP's code so he would understand better where to do it. But thank you for pointing that out. You may edit the answer with that line if you want. – Rakesha Shastri Aug 27 '18 at 06:35
  • Of course you're right. But I remember when I was a beginner every error was a big headache for me :) – Alex Kolovatov Aug 27 '18 at 06:42
0

Use this code:

import UIKit

class ViewController: UIViewController {

  override func viewDidLoad() {
    super.viewDidLoad()

    view.addSubview(button)
    setupConstraints()
  }

  lazy var button: UIButton = {
    let button = UIButton(type: .system)
    button.setTitle("Button", for: .normal)
    button.backgroundColor = .blue
    //your action here
    button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
    return button
  }()

  private func setupConstraints() {
    button.translatesAutoresizingMaskIntoConstraints = false
    let top = NSLayoutConstraint(item: button, attribute: .top, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1, constant: 100)
    let left = NSLayoutConstraint(item: button, attribute: .left, relatedBy: .equal, toItem: view, attribute: .left, multiplier: 1, constant: 50)
    let right = NSLayoutConstraint(item: button, attribute: .right, relatedBy: .equal, toItem: view, attribute: .right, multiplier: 1, constant: -50)
    let height = NSLayoutConstraint(item: button, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 50)
    view.addConstraints([top, left, right, height])
  }

  @objc func buttonAction() {
    print("Button has pressed")
  }

}
Alex Kolovatov
  • 859
  • 7
  • 12
  • I am getting this error when using button function Cannot convert value of type '() -> _' to specified type 'UIButton' –  Aug 26 '18 at 17:58