Default Swift Option and Selector Syntax

I have a function that accepts a default parameter:

func myFunc(foo: Bool = true) { } 

I am trying to figure out the correct Selector syntax as I add it as a target for UIRefreshControl

  self.refreshControl.addTarget(self, action: Selector("myFunc"), forControlEvents: UIControlEvents.ValueChanged) 

I tried both Selector("myFunc") and Selector("myFunc:") - both fail with an invalid selector error.

If there was some kind of network, but there were no solutions. Can anyone help? Thanks

+5
source share
2 answers

You crash because it expects a different parameter. 'addTarget' expects to receive a function, the only parameter (if any) is AnyObject (or, possibly, UIView), not Bool

+2
source

We are trying to add an action to a user interface element. Consider the options that Xcode offers us if we try to connect a control from our interface builder file to our view controller class:

enter image description here

Like the method you use, Interface Builder asks us a few things.

  • The interface designer knows which control is the sender (where we initiated the drag and drop Ctrl + ... this matches your self.refreshControl , which we call addTarget ).
  • The interface designer knows which class is the target (we Ctrl + drag it).
  • The interface designer asks for the name of the method we are going to create. In your case, you chose this when you wrote a method.
  • The interface designer asks how to pass the sender. It gives us, in the case of a button, the option AnyObject (default) or UIButton . In the case of UIRefreshControl parameters will be AnyObject or UIRefreshControl . This is passed as the sender object.
  • The interface designer asks us for what events this method should be called (as the addTarget method addTarget ).

And finally, the Interface builder asks us which arguments should be passed:

enter image description here

Here we have three options.

We cannot pass any arguments, in which case we will have a method that looks like this:

 func myFunc() { } 

Or we can pass the "sender", in which case the method will look like this:

 func myFunc(sender: AnyObject) { } 

But the type of sender will change depending on what we are actually trying to send.

Or we could pass the sender and the type of event (useful if multiple events are bound to the same method):

 func myFunc(sender: AnyObject, forEvent event: UIEvent) { } 

If you do this through the constructor interface, we will also have @IBAction at the beginning, but this is not what we do in your example.

Now, if it was Objective-C, our method would look something like this:

 - (void)myFunc:(id)sender { } 

And Objective-C does not support overloading, so it will not allow another function in the same class to look like this:

 - (void)myFunc:(BOOL)foo { } 

You cannot have two methods with the same name.

Swift, however, supports method overloading, and thus the same class can have both of the following methods:

 func myFunc(foo: AnyObject) { } func myFunc(foo: Bool) { } 

These are completely different methods in Swift's eyes and are wonderful.

However, your code only has the latter. A method called myFunc that takes a Bool argument.

When you try to add the addTarget: Swift method, it looks for a method with the name you gave it ( myFunc: , which can take the UIRefreshControl argument. He cannot find overload.

Effectively, the error you get is the same as this error:

enter image description here

The fact is that Swift cannot find a method called myFunc: which can take an argument of UIRefreshControl .

+5
source

Source: https://habr.com/ru/post/1214424/


All Articles