如何在Swift中从UIView删除所有手势识别器
我编写了Swift代码,试图从给定的自定义UIView类型的所有子视图中删除所有手势识别器。
let mySubviews = self.subviews.filter() { $0.isKindOfClass(CustomSubview)
}
for subview in mySubviews {
for recognizer in subview.gestureRecognizers {
subview.removeGestureRecognizer(recognizer)
}
}
但是该for recognizer
行会产生编译器错误:
'[AnyObject]?' does not have a member named 'Generator'
我尝试将for recognizer
循环更改为for recognizer in
enumerate(subview.gestureRecognizers),但这会产生编译器错误:
Type '[AnyObject]?!' Does not conform to protocol 'SequenceType'
我看到UIView的gestureRecognizers
方法[AnyObject]??
return,并且我认为双重包装的返回值使我感到震惊。谁能帮我?
更新:修改后的编译代码为:
if let recognizers = subview.gestureRecognizers { for recognizer in recognizers! {
subview.removeGestureRecognizer(recognizer as UIGestureRecognizer)
}
}
回答:
iOS 11更新
通常,通过循环遍历视图数组来删除视图中的 手势识别是(而且一直是)一个坏主意gestureRecognizers
。您应该只删除手势识别是
添加到视图,通过跟踪那些识别器在自己的实例变量。
这对于iOS 11中涉及拖放的视图具有新的重要性,因为UIKit向这些视图添加了自己的手势识别器以识别拖放。
更新
您不再需要强制转换为UIGestureRecognizer
,因为UIView.gestureRecognizers
已更改为[UIGestureRecognizer]?
在iOS
9.0中键入。
另外,通过使用nil-coalescing运算符??
,您可以避免使用该if
语句。
for recognizer in subview.gestureRecognizers ?? [] { subview.removeGestureRecognizer(recognizer)
}
但是,最简单的方法是:
subview.gestureRecognizers?.forEach(subview.removeGestureRecognizer)
我们还可以for
像这样在循环中对子视图进行过滤:
for subview in subviews where subview is CustomSubview { for recognizer in subview.gestureRecognizers ?? [] {
subview.removeGestureRecognizer(recognizer)
}
}
或者我们可以将它们全部包装成一个表达式(为清楚起见而包装):
subviews.lazy.filter { $0 is CustomSubview } .flatMap { $0.gestureRecognizers ?? [] }
.forEach { $0.view?.removeGestureRecognizer($0) }
使用.lazy
可以防止它创建不必要的临时数组。
原版的
这是Swift令人讨厌的事情之一。您的for循环仅在Objective-C中有效,但是在Swift中,您必须显式解开可选数组:
if let recognizers = subview.gestureRecognizers { for recognizer in recognizers {
subview.removeGestureRecognizer(recognizer as! UIGestureRecognizer)
}
}
您可以强制拆开它(for recognizer in
subview.gestureRecognizers!),但是我不确定是否gestureRecognizers
可以返回nil
,如果返回,则会出现运行时错误,然后您将其强制拆开。
以上是 如何在Swift中从UIView删除所有手势识别器 的全部内容, 来源链接: utcz.com/qa/415065.html