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
iOS Autolayout with Uiscrollview: Why Does Content View of Scroll View Not Fill the Scroll View
How to Display a Uipopoverview as a Annotation to the Map View? (iPad)
iOS 5 JSON Parsing Results in Cocoa Error 3840
Programmatically Scroll a Uiscrollview
Nsxmlparser: Unexpected Result with Non-Ascii Characters
Uitableview Dynamic Cell Heights Only Correct After Some Scrolling
Xcode Simulator: How to Remove Older Unneeded Devices
How to Attach Debugger to iOS App After Launch
Adding Blur Effect to Background in Swift
Pod Install Is Staying on "Setting Up Cocoapods Master Repo"
How to Disable/Enable the Sleep Mode Programmatically in iOS
Add a Uiview Above All, Even the Navigation Bar
Raw Value for Enum Case Must Be a Literal
Dynamic Link Object Has No Url
Getting Client Certificate to Work for Mutual Authentication Using Swift 3 and Alamofire 4