Make a UIButton programmatically in Swift

322,361

Solution 1

You're just missing the colon at the end of the selector name. Since pressed takes a parameter the colon must be there. Also your pressed function shouldn't be nested inside viewDidLoad.

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    let myFirstLabel = UILabel()
    let myFirstButton = UIButton()
    myFirstLabel.text = "I made a label on the screen #toogood4you"
    myFirstLabel.font = UIFont(name: "MarkerFelt-Thin", size: 45)
    myFirstLabel.textColor = .red
    myFirstLabel.textAlignment = .center
    myFirstLabel.numberOfLines = 5
    myFirstLabel.frame = CGRect(x: 15, y: 54, width: 300, height: 500)
    myFirstButton.setTitle("✸", for: .normal)
    myFirstButton.setTitleColor(.blue, for: .normal)
    myFirstButton.frame = CGRect(x: 15, y: -50, width: 300, height: 500)
    myFirstButton.addTarget(self, action: #selector(pressed), for: .touchUpInside)
}

@objc func pressed() {
    var alertView = UIAlertView()
    alertView.addButtonWithTitle("Ok")
    alertView.title = "title"
    alertView.message = "message"
    alertView.show()
}

EDIT: Updated to reflect best practices in Swift 2.2. #selector() should be used rather than a literal string which is deprecated.

Solution 2

Swift 2.2 Xcode 7.3

Since Objective-C String Literals are deprecated now for button callback methods

let button:UIButton = UIButton(frame: CGRectMake(100, 400, 100, 50))
button.backgroundColor = UIColor.blackColor()
button.setTitle("Button", forState: UIControlState.Normal)
button.addTarget(self, action:#selector(self.buttonClicked), forControlEvents: .TouchUpInside)
self.view.addSubview(button)

func buttonClicked() {
     print("Button Clicked")
}

Swift 3 Xcode 8

let button:UIButton = UIButton(frame: CGRect(x: 100, y: 400, width: 100, height: 50))
button.backgroundColor = .black
button.setTitle("Button", for: .normal)
button.addTarget(self, action:#selector(self.buttonClicked), for: .touchUpInside)
self.view.addSubview(button)

func buttonClicked() {
    print("Button Clicked")
}

Swift 4 Xcode 9

let button:UIButton = UIButton(frame: CGRect(x: 100, y: 400, width: 100, height: 50))
button.backgroundColor = .black
button.setTitle("Button", for: .normal)
button.addTarget(self, action:#selector(self.buttonClicked), for: .touchUpInside)
self.view.addSubview(button)

@objc func buttonClicked() {
    print("Button Clicked")
}

Solution 3

Swift 4/5

let button = UIButton(frame: CGRect(x: 20, y: 20, width: 200, height: 60))
 button.setTitle("Email", for: .normal)
 button.backgroundColor = .white
 button.setTitleColor(UIColor.black, for: .normal)
 button.addTarget(self, action: #selector(self.buttonTapped), for: .touchUpInside)
 myView.addSubview(button)



@objc func buttonTapped(sender : UIButton) {
                //Write button action here
            }

Solution 4

Swift 4

private func createButton {
    let sayButtonT = UIButton(type: .custom)
    sayButtonT.addTarget(self, action: #selector(sayAction(_:)), for: .touchUpInside)
}

@objc private func sayAction(_ sender: UIButton?) {

}

Solution 5

You should be able to create a customize UI button programmatically by accessing the titleLabel property of UIButton.

Per Class Reference in Swift: Regarding the titleLabel property, it says that "although this property is read-only, its own properties are read/write. Use these properties primarily to configure the text of the button."

In Swift, you can directly modify the properties of titleLabel like such:

let myFirstButton = UIButton()
myFirstButton.titleLabel!.text = "I made a label on the screen #toogood4you"
myFirstButton.titleLabel!.font = UIFont(name: "MarkerFelt-Thin", size: 45)
myFirstButton.titleLabel!.textColor = UIColor.red
myFirstButton.titleLabel!.textAlignment = .center
myFirstButton.titleLabel!.numberOfLines = 5
myFirstButton.titleLabel!.frame = CGRect(x: 15, y: 54, width: 300, height: 500)

Edit

Swift 3.1 Syntax

Share:
322,361
Benr783
Author by

Benr783

Updated on December 23, 2021

Comments

  • Benr783
    Benr783 over 2 years

    I am trying to build UIs programmatically with Swift.

    How can I get this action working?

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        let myFirstLabel = UILabel()
        let myFirstButton = UIButton()
        myFirstLabel.text = "I made a label on the screen #toogood4you"
        myFirstLabel.font = UIFont(name: "MarkerFelt-Thin", size: 45)
        myFirstLabel.textColor = UIColor.redColor()
        myFirstLabel.textAlignment = .Center
        myFirstLabel.numberOfLines = 5
        myFirstLabel.frame = CGRectMake(15, 54, 300, 500)
        myFirstButton.setTitle("✸", forState: .Normal)
        myFirstButton.setTitleColor(UIColor.blueColor(), forState: .Normal)
        myFirstButton.frame = CGRectMake(15, -50, 300, 500)
        myFirstButton.addTarget(self, action: "pressed", forControlEvents: .TouchUpInside)
        self.view.addSubview(myFirstLabel)
        self.view.addSubview(myFirstButton)
    }
    
    func pressed(sender: UIButton!) {
        var alertView = UIAlertView();
        alertView.addButtonWithTitle("Ok");
        alertView.title = "title";
        alertView.message = "message";
        alertView.show();
    }
    
  • Benr783
    Benr783 almost 10 years
    The app still crashes when I press the button.
  • Dash
    Dash almost 10 years
    Sorry fixed. The function shouldn't be nested.
  • user2202911
    user2202911 over 9 years
    i tried running this code and it is not working for me. Non of the chidlren of titleLabel seem to exist
  • juniorgarcia
    juniorgarcia about 9 years
    Hey, can you tell me the logic behind the colon we need to add after the string that represents the action?
  • HughHughTeotl
    HughHughTeotl almost 9 years
    @chorajunior The colon is needed because the pressed function takes an argument.
  • Dave G
    Dave G over 8 years
    Inversely, anyone reading this may also want to know that if your button action references a function that takes no parameter, the colon is not needed and may even cause an error if not removed.
  • Felipe
    Felipe over 8 years
    Thanks, m8! Starting up with Swift today so everything is kind of strange (:
  • arbel03
    arbel03 over 8 years
    Colon only in functions that take only 1 parameter.
  • evanflash
    evanflash over 8 years
    It's worth noting that the pressed function needs to be public, at least that has been my experience.
  • evanflash
    evanflash over 8 years
    whoops, too late to edit my comment, but here's some more clarification about access control using addTarget stackoverflow.com/questions/25056278/…
  • corykon
    corykon over 8 years
    After following everything described above I kept getting the unrecognized selector crash. Found the answerI needed here: stackoverflow.com/a/29409052/2311702
  • nyxee
    nyxee almost 7 years
    how does getCurrentLocation help us to get the location please?
  • 7stud
    7stud almost 7 years
    @nyxee, The question here was about how to programmatically make a button. Getting the location of a user has nothing to do with making a button. To get a user's location see here; developer.apple.com/reference/corelocation/cllocationmanager‌​. If you can’t figure it out, ask your own question please.
  • ArgaPK
    ArgaPK over 6 years
    @n.by.n how to pass argument on this method buttonClicked()?
  • Pradumna Patil
    Pradumna Patil over 4 years
    Without @objc for selector function it is not accepting.
  • Milo Chen
    Milo Chen over 3 years
    '''@objc func buttonAction() { //some Action }'''. <-- Should add @objc
  • ShadeToD
    ShadeToD over 3 years
    Remember that you can't use addTarget with action inside a closure.