Selector in Swift3

Selector in swift3

Selector("tap:") should now be written as #selector(tap(gestureReconizer:))

Also, you should declare tap as func tap(_ gestureRecognizer: UITapGestureRecognizer) as per the new Swift API Guidelines in which case your selector would then become #selector(tap(_:)).

Using Selector in Swift 3

A simple workaround:

@objc protocol SomeMethodType {
func someMethod()
}
extension UIViewController {
func myMethod() {
if self.responds(to: #selector(SomeMethodType.someMethod)) {
//...
self.perform(#selector(SomeMethodType.someMethod))
// or
(self as AnyObject).someMethod?()
//...
}
}
}

A little more Swifty way:

protocol SomeMethodType {
func someMethod()
}
//For all classes implementing `someMethod()`.
extension MyViewController: SomeMethodType {}
//...
extension UIViewController {
func myMethod() {
if let someMethodSelf = self as? SomeMethodType {
//...
someMethodSelf.someMethod()
//...
}
}
}

How to use the Swift 3 selectors?

As noted in comments, this code is a vestigial remnant of attempts to support old iOS versions that not only are no longer relevant, but can't even be targeted when developing in Swift.

Just call UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.mainScreen().scale) directly — the scale property exists on all iOS versions that you can target with Swift, so there's no need to check for it.

In fact, in general it's not a good idea to test for API availability using selector checks. A selector may exist on a version below the one you're targeting, but be private API with different behavior — so your check will succeed, but your code will not behave correctly. This is why the @available and #available system was introduced in Swift 2.

(Another upside of version-based availability checking: when an OS version gets old enough for you to drop support, it's much easier to find all the sites in your code that you can clean up. You don't have to remember which version which method/property became universal in.)


If for some other reason you need to form a Selector for UIScreen.scale... you can't use the #selector expression to do that in Swift 2.2, because scale is a property, not a method. In Swift 2.2, #selector takes a function/reference, and there's no way to get a reference to the underlying getter or setter method of a property. You'd still need to construct that selector from a string. To get around the warning, stash the string literal in a temporary:

let scale = "scale"
let selector = Selector(scale)

Or do some other dance that passes a string, but doesn't directly pass a string literal, to the Selector initializer:

let selector = Selector({"scale"}())

In Swift 3 there'll be a special form of #selector for property getters/setters, but it hasn't landed yet.

Selector In Swift 3.0

You can declare selector in Swift 3 like this.

var itemSelected: Selector?

Or

var itemSelected = #selector(tapGesture) 

Later you can use above itemSelected selector with action like this.

For eg:

let tap = UITapGestureRecognizer(target: self, action: itemSelected)

And tapGesture is declared like

func tapGesture(_ sender: UITapGestureRecognizer) { }

Edit: You have added collectionView inside your TableViewCell, so to get the selected IndexPath of CollectionViewCell, declare one protocol and use it with your tableViewCell.

protocol SelectedCellDelegate {
func getIndexPathOfSelectedCell(tableIndexPath: IndexPath, collectionViewCell indexPath: IndexPath)
}

Now create one instance of SelectedCellDelegate and instance of IndexPath within your CustomTableViewCell.

class CustomTableCell: UITableViewCell, UICollectionViewDelegate, UICollectionViewDataSource {
//All outlet

var delegate: SelectedCellDelegate?
var tableCellIndexPath = IndexPath()

//CollectionViewDataSource method

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
self.delegate?.getIndexPathOfSelectedCell(tableIndexPath: tableCellIndexPath, indexPath: indexPath)
}

}

Now inside your ViewController where you have added TableView implement the protocol SelectedCellDelegate and set the delegate and tableCellIndexPath in cellForRowAt indexPath method.

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, SelectedCellDelegate {
//your methods

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell // Initialize the cell with your custom TableCell
cell.delegate = self
cell.tableCellIndexPath = indexPath
return cell
}

Now add the delegate method in your ViewController.

func getIndexPathOfSelectedCell(tableIndexPath: IndexPath, collectionViewCell indexPath: IndexPath)  {
print("TableView cell indexPath - \(tableIndexPath)")
print("CollectionView cell indexPath - \(indexPath)")
}

What's the diffrents between #selector() and Selector() ios Swift

Both are same things, the purpose of #selector() syntax is to save you from the possible error in having to write a selector as a literal string, which is error-prone.

Perform Selector With Object in swift 3

It started working well as, I modified the selector being called

from

func imageSelected(aImage : UIImage)

to this

func imageSelected(_ aImage : UIImage)

how to define a selector in swift3 for an override method

I'm afraid this may be a flaw in the current #selector notation and you should send a bug report to Apple or swift.org. (Or I may be just missing something...)

To work this around, define a class conforming to the protocol, and define the method that you want to make a selector for.

class TheClass: NSObject, CBPeripheralDelegate {
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
//No need to actually implement the method
}
}

And use that class name in your #selector():

#selector(TheClass.peripheral(_:didUpdateValueFor:error:))

You may already have a class implementing the method, then you can use the class name of it.

Objective-C selectors does not keep a class name information, so, the selector can be used for any classes which may be implementing the method.

If you want to make a selector from inside a class which conforms the protocol and has a definition for the method, you can write it as:

#selector(peripheral(_:didUpdateValueFor:error:))


Related Topics



Leave a reply



Submit