我编写了Swift代码,试图从给定的自定义UIView类型的所有子视图中删除所有手势识别器。
let mySubviews = self.subviews.filter() { $0.isKindOfClass(CustomSubview) } for subview in mySubviews { for recognizer in subview.gestureRecognizers { subview.removeGestureRecognizer(recognizer) } }
但是该for recognizer行会产生编译器错误:
for recognizer
'[AnyObject]?' does not have a member named 'Generator'
我尝试将for recognizer循环更改为for recognizer in enumerate(subview.gestureRecognizers),但这会产生编译器错误:
for recognizer in enumerate(subview.gestureRecognizers)
Type '[AnyObject]?!' Does not conform to protocol 'SequenceType'
我看到UIView的gestureRecognizers方法[AnyObject]??return,并且我认为双重包装的返回值使我感到震惊。谁能帮我?
gestureRecognizers
[AnyObject]??
更新:修改后的编译代码为:
if let recognizers = subview.gestureRecognizers { for recognizer in recognizers! { subview.removeGestureRecognizer(recognizer as UIGestureRecognizer) } }
通常,通过循环遍历视图数组来删除视图中的 所有 手势识别是(而且一直是)一个坏主意gestureRecognizers。您应该只删除手势识别是 您 添加到视图,通过跟踪那些识别器在自己的实例变量。
这对于iOS 11中涉及拖放的视图具有新的重要性,因为UIKit向这些视图添加了自己的手势识别器以识别拖放。
您不再需要强制转换为UIGestureRecognizer,因为UIView.gestureRecognizers已更改为[UIGestureRecognizer]?在iOS 9.0中键入。
UIGestureRecognizer
UIView.gestureRecognizers
[UIGestureRecognizer]?
另外,通过使用nil-coalescing运算符??,您可以避免使用该if语句。
??
if
for recognizer in subview.gestureRecognizers ?? [] { subview.removeGestureRecognizer(recognizer) }
但是,最简单的方法是:
subview.gestureRecognizers?.forEach(subview.removeGestureRecognizer)
我们还可以for像这样在循环中对子视图进行过滤:
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可以防止它创建不必要的临时数组。
.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,如果返回,则会出现运行时错误,然后您将其强制拆开。
for recognizer in subview.gestureRecognizers!
nil