How About a Cleaner Swift Selector Syntax

Posted 08/17/2016 6:45 PM by Corey Klass

Newer versions of Swift introduced the Selector convention #selector(ClassName.FunctionName()) to replace the old-style Objective C style Selector conventions.

    func makeButton() {
        let button = UIButton(type: .System)
        button.setTitle("Test Button", forState: .Normal)
        button.addTarget(self, action: #selector(MyViewController.didTapButton(_:)), forControlEvents: .TouchUpInside)
    }

    func makeOtherButton() {
        let button = UIButton(type: .System)
        button.setTitle("Test Other Button", forState: .Normal)
        button.addTarget(self, action: #selector(MyViewController.didTapOtherButton(_:)), forControlEvents: .TouchUpInside)
    }

This is kind of ugly though, having your Selectors scattered all throughout your code.

Instead, you can create a private Extension of the Selector class, with a single static variable for each Selector. This way, you can keep all of your Selectors local in one place, neatly organized. Your code reads much cleaner, and since Xcode knows that the UIButton.addTarget() function takes a Selector as its second argument, you can leave off the Selector class name.

    func makeButton() {
        let button = UIButton(type: .System)
        button.setTitle("Test Button", forState: .Normal)
        button.addTarget(self, action: .DidTapButton, forControlEvents: .TouchUpInside)
    }

    func makeOtherButton() {
        let button = UIButton(type: .System)
        button.setTitle("Test Other Button", forState: .Normal)
        button.addTarget(self, action: .DidTapOtherButton, forControlEvents: .TouchUpInside)
    }

    private extension Selector {
        static let DidTapButton = #selector(MyViewController.didTapButton(_:))
        static let DidTapOtherButton = #selector(MyViewController.didTapOtherButton(_:))
    }