This line of code used to work with Swift 2, but now is incorrect in Swift 3.
if gestureRecognizer.isMember(of: UITapGestureRecognizer) { }
Swift 3:
if gestureRecognizer is UITapGestureRecognizer {
//It's a tap
}
You have to use .self to refer the class type now.
let a = UITapGestureRecognizer()
print (a.isMember(of: UIGestureRecognizer.self))
There is also:
print (a is UITapGestureRecognizer)
There are several ways to check the class of an object. Most of the time you will want to use either the is
or the as?
operators like so:
let gestureRecognizer: UIGestureRecognizer = UITapGestureRecognizer()
// Using the is operator
if gestureRecognizer is UITapGestureRecognizer {
// You know that the object is an instance of UITapGestureRecognizer,
// but the compiler will not let you use UITapGestureRecognizer specific
// methods or properties on gestureRecognizer because the type of the
// variable is still UIGestureRecognizer
print("Here")
}
// Using the as? operator and optional binding
if let tapGestureRecognizer = gestureRecognizer as? UITapGestureRecognizer {
// tapGestureRecognizer is the same object as gestureRecognizer and is
// of type UITapGestureRecognizer, you can use UITapGestureRecognizer
// specific methods or properties.
print("Here")
}
// Using the type(of:) global function
if type(of: gestureRecognizer) == UITapGestureRecognizer.self {
// gestureRecognizer is an instance of UITapGestureRecognizer, but not any
// of its subclasses (if gestureRecognizer was an instance of a subclass of
// UITapGestureRecognizer, the body of this if would not execute).
// This kind of check is rarely usefull, be sure this is really what you
// want to do before you use it.
print("Here")
}
// Using the isKind(of:) method
if gestureRecognizer.isKind(of: UITapGestureRecognizer.self) {
// Like for the is operator, you know that the object is an instance of
// UITapGestureRecognizer (or any subclass of UITapGestureRecognizer).
// This is the Objective-C version of the is operator and will only work
// on classes that inherit from NSObject, don't use it in Swift.
print("Here")
}
// Using the isMember(of:) method
if gestureRecognizer.isMember(of: UITapGestureRecognizer.self) {
// gestureRecognizer is an instance of UITapGestureRecognizer, but not
// any of its subclasses.
// This is the Objective-C version of type(of:) and will only work on
// classes that inherit from NSObject, don't use it in Swift.
print("Here")
}
Most likely, you'll want to not only check the type, but also cast to that type. In this case, use:
if let gestureRecognizer as? UITapGestureRecognizer { }
else { /* not a UITapGestureRecognizer */ }
These operators are only available in Swift, but still work when dealing with Objective C types.
The
as
operator performs a cast when it is known at compile time that the cast always succeeds, such as upcasting or bridging. Upcasting lets you use an expression as an instance of its type’s supertype, without using an intermediate variable.
The
as?
operator performs a conditional cast of the expression to the specified type. Theas?
operator returns an optional of the specified type. At runtime, if the cast succeeds, the value of expression is wrapped in an optional and returned; otherwise, the value returned isnil
. If casting to the specified type is guaranteed to fail or is guaranteed to succeed, a compile-time error is raised.
This is the second most preferable operator to use. Use it to safely handle the case in which a casting operator can't be performed.
The
as!
operator performs a forced cast of the expression to the specified type. Theas!
operator returns a value of the specified type, not an optional type. If the cast fails, a runtime error is raised. The behavior ofx as! T
is the same as the behavior of(x as? T)!
.
This is the least preferable operator to use. I strongly advise against abusing it. Attempting to cast an expression to an incompatible type crashes your program.
If you merely want to check the type of an expression, without casting to that type, then you can use these approaches. They are only available in Swift, but still work when dealing with Objective C types.
is
operator checks at runtime whether the expression can be cast to the specified type. It returns true
if the expression can be cast to the specified type; otherwise, it returns false
is
operator, this can be used to check the exact type, without consideration for subclasses.type(of: instance) == DesiredType.self
These are all methods on NSObjectProtocol. They can be used in Swift code, but they only apply work with classes that derive from NSObjectProtocol
(such as subclasses of NSObject
). I advise against using these, but I mention them here for completeness
is
operator instead.type(of: instance) == DesiredType.self
instead.is
operator instead.