creating simple action if NSButton is pressed in swift

iznogoud picture iznogoud · Jun 10, 2016 · Viewed 10.7k times · Source

I am in the process of learning swift. I would like to know how to call a function programmatically if a button is pressed. I tried this, but the function is executed directly when the program launches, not when I press the button. Can you please help me to fix this.

Here is what i have tried,

//
//  ViewController.swift
//  hjkhjkjh
//
//  Created by iznogoud on 14/05/16.
//  Copyright © 2016 iznogoud. All rights reserved.
//

import Cocoa


class ViewController: NSViewController {

    func printSomething() {
       print("Hello")
    }

    override func viewDidLoad() {
       super.viewDidLoad()

       let myButtonRect = CGRect(x: 10, y: 10, width: 100, height: 10)
       let myButton =  NSButton(frame: myButtonRect)
       view.addSubview(myButton)
       myButton.target = self
       myButton.action = Selector(printSomething())


       // Do any additional setup after loading the view.
    }

    override var representedObject: AnyObject? {
       didSet {
          // Update the view, if already loaded.
       }
    }
}

Answer

pbodsk picture pbodsk · Jun 10, 2016

The problem lies in the way you add your selector

myButton.action = Selector(printSomething())

The syntax for adding selectors is a bit quirky, you give it a string with the name of the function, so in your case you should write:

myButton.action = Selector("printSomething")

Which should reward you with Hello in your console.

And probably because the syntax is causing people problems it was changed in Swift 2.2, so now you write:

myButton.action = #selector(ViewController.printSomething)

instead. This means that the compiler can help you catch these errors early, which is a great step forward I think. You can read more about it in the release notes for Swift 2.2 here

So...here is your entire example:

import Cocoa

class ViewController: NSViewController {

    @objc
    func printSomething() {
        print("Hello")
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        let myButtonRect = CGRect(x: 10, y: 10, width: 100, height: 10)
        let myButton =  NSButton(frame: myButtonRect)
        view.addSubview(myButton)

        myButton.target = self
        myButton.action = #selector(ViewController.printSomething)
    }

    override var representedObject: AnyObject? {
        didSet {
        // Update the view, if already loaded.
        }
    }
}

Hope that helps you.