UPDATE FOR iOS 11
In general it is (and has always been) a bad idea to remove all gesture recognizes from a view by looping through its gestureRecognizers
array. You should only remove gesture recognizers that you add to the view, by keeping track of those recognizers in your own instance variable.
This takes on new importance in iOS 11 for views that are involved in drag and drop, because UIKit adds its own gesture recognizers to those views to recognize drags and drops.
UPDATE
You no longer need to cast to UIGestureRecognizer
, because UIView.gestureRecognizers
was changed to type [UIGestureRecognizer]?
in iOS 9.0.
Also, by using the nil-coalescing operator ??
, you can avoid the if
statement.
for recognizer in subview.gestureRecognizers ?? [] {
subview.removeGestureRecognizer(recognizer)
}
However, the shortest way to do it is this:
subview.gestureRecognizers?.forEach(subview.removeGestureRecognizer)
We can also do the filtering of the subviews in a for
loop like this:
for subview in subviews where subview is CustomSubview {
for recognizer in subview.gestureRecognizers ?? [] {
subview.removeGestureRecognizer(recognizer)
}
}
Or we can wrap it all up into one expression (wrapped for clarity):
subviews.lazy.filter { $0 is CustomSubview }
.flatMap { $0.gestureRecognizers ?? [] }
.forEach { $0.view?.removeGestureRecognizer($0) }
The use of .lazy
should prevent it from creating unnecessary temporary arrays.
ORIGINAL
This is one of those annoying things about Swift. Your for loop would just work in Objective-C, but in Swift you have to explicitly unwrap the optional array:
if let recognizers = subview.gestureRecognizers {
for recognizer in recognizers {
subview.removeGestureRecognizer(recognizer as! UIGestureRecognizer)
}
}
You could force-unwrap it (for recognizer in subview.gestureRecognizers!
), but I'm not sure whether gestureRecognizers
can return nil
and you'll get a runtime error if it does and you force-unwrap it.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…