Search code examples
swiftclosuresselector

Can I make #selector refer to a closure in Swift?


I want to make a selector argument of my method refer to a closure property, both of them exist in the same scope. For example,

func backgroundChange() {
    self.view.backgroundColor = UIColor.blackColor()
    self.view.alpha = 0.55

    let backToOriginalBackground = {
        self.view.backgroundColor = UIColor.whiteColor()
        self.view.alpha = 1.0
    }

    NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: #selector(backToOriginalBackground), userInfo: nil, repeats: false)
}

However, this shows an error: Argument of #selector cannot refer to a property.

Of course I can define a new, separate method and move the implementation of the closure to it, but I want to keep it frugal for such a small implementation.

Is it possible to set a closure to #selector argument?


Solution

  • As @gnasher729 notes, this is not possible because selectors are just names of methods, not methods themselves. In the general case, I'd use dispatch_after here, but in this particular case, the better tool IMO is UIView.animateWithDuration, because it's exactly what that function is for, and it's very easy to tweak the transition:

    UIView.animateWithDuration(0, delay: 0.5, options: [], animations: {
        self.view.backgroundColor = UIColor.whiteColor()
        self.view.alpha = 1.0
    }, completion: nil)