Monday, March 28, 2016

UIButton - Selector Warning (Update with Swift 3.1)

Update:
May 1, 2017:
Swift 3.1 with Xcode 8.3.2.

May 29, 2016:
The class name in the selector may be removed. Use #selector(buttonPressed) instead of #selector(ViewController.buttonPressed) for code simplicity.

On March 21, 2016, Apple released Xcode 7.3 with Swift 2.2. This new version of Swift is the first official release after the programming language became open source on December 3, 2015. The official Swift.org blog says that 212 non-Apple programmers have contributed to this release. Below is the first issue I face with Swift 2.2.

After I updated Xcode to Version 7.3, a warning appears with the UIButton code I normally use:

let button = UIButton()
.
.
button.addTarget(self, action: "buttonPressed", forControlEvents: UIControlEvents.TouchUpInside)

A warning is shown in front of the line number:


If I ignore the warning and continue to build the code, the UIButton still works perfectly.

By clicking the warning triangle, the warning description says that Use of string literal for Objective-C selectors is deprecated; use '#selector' instead.


Select the Fix-it Replace option.



Then the warning is disappeared as below:

button.addTarget(self, action: #selector(ViewController.buttonPressed), forControlEvents: UIControlEvents.TouchUpInside)


Update May 1, 2017 (Swift 3.1):

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let button = UIButton(frame: CGRect(x: 0, y: 0, width: 200, height: 40))
        button.center = view.center
        button.setTitle("Press", for: UIControlState.normal)
        button.setTitleColor(UIColor.blue, for: UIControlState.normal)
        button.setTitleColor(UIColor.cyan, for: UIControlState.highlighted)
        button.addTarget(self, action: #selector(buttonPressed), for: UIControlEvents.touchUpInside)
        view.addSubview(button)
    }
    
    func buttonPressed() {
        print("button pressed!!")
    }

}

Update May 29, 2016 (Swift 2.2):

Remove the class name in the selector: #selector(ViewController.buttonPressed)and the complete UIButton code now becomes:


override func viewDidLoad() {
    super.viewDidLoad()
        
    let button = UIButton(frame: CGRectMake(0, 0, 200, 200))
    button.center = view.center
    button.setTitle("Press", forState: UIControlState.Normal)
    button.setTitleColor(UIColor.blueColor(), forState: UIControlState.Normal)
    button.setTitleColor(UIColor.cyanColor(), forState: UIControlState.Highlighted)
    button.addTarget(self, action: #selector(buttonPressed), forControlEvents: UIControlEvents.TouchUpInside)
    view.addSubview(button)
}
    
func buttonPressed() {
    print("button pressed!!")
}

Here is more explanation about the modification of Objective-C selectors in Swift 2.2:

Referencing the Objective-C selector of a method

More Information about modifications in Swift 2.2:

Swift 2.2 Released!(Official Swift.org blog)

Reference:

UIButton - Update button label when pressed

2 comments:

  1. im calling the target in the superclass as:

    likeButton.addTarget(self.superview, action: Selector("likeBtnClicked:"), forControlEvents: UIControlEvents.TouchUpInside);

    And in superclass i've defined it as:
    func likeBtnClicked(sender:AAButton){
    ....
    }

    I get the same warning as "no method declared with selector likeBtnClicked"

    How to update this for Swift 2.2?

    ReplyDelete
    Replies
    1. Try #selector(YourClassName.likeBtnClicked(_:)) or #selector(SuperClassName.likeBtnClicked(_:))

      Delete