如何从Swift中的UIView中删除所有手势识别器

Bri*_*rty 50 optional uiview uigesturerecognizer ios swift

我编写了Swift代码,试图从给定自定义UIView类型的所有子视图中删除所有手势识别器.

let mySubviews = self.subviews.filter() {
   $0.isKindOfClass(CustomSubview)
}
for subview in mySubviews {
   for recognizer in subview.gestureRecognizers {
      subview.removeGestureRecognizer(recognizer)
   }
}
Run Code Online (Sandbox Code Playgroud)

但该for recognizer行会产生编译错误:

'[AnyObject]?' does not have a member named 'Generator'
Run Code Online (Sandbox Code Playgroud)

我已经尝试将for recognizer循环更改为for recognizer in enumerate(subview.gestureRecognizers),但这会产生编译器错误:

Type '[AnyObject]?!' Does not conform to protocol 'SequenceType'
Run Code Online (Sandbox Code Playgroud)

我看到UIView的gestureRecognizers方法返回了[AnyObject]??,我认为双重包裹的返回值正在绊倒我.谁能帮我?

更新:修改,编译代码是:

if let recognizers = subview.gestureRecognizers {
   for recognizer in recognizers! {
      subview.removeGestureRecognizer(recognizer as UIGestureRecognizer)
   }
}
Run Code Online (Sandbox Code Playgroud)

rob*_*off 100

适用于iOS 11的更新

通常,通过循环遍历其数组从视图中删除所有手势识别是(并且一直是)一个坏主意gestureRecognizers.您应该只删除手势识别添加到视图,通过跟踪那些识别器在自己的实例变量.

这在iOS 11中对于拖放涉及的视图具有新的重要性,因为UIKit将自己的手势识别器添加到这些视图以识别拖放.

UPDATE

您不再需要强制转换UIGestureRecognizer,因为UIView.gestureRecognizers已更改为[UIGestureRecognizer]?在iOS 9.0中键入.

此外,通过使用nil-coalescing运算符??,您可以避免使用该if语句.

for recognizer in subview.gestureRecognizers ?? [] {
    subview.removeGestureRecognizer(recognizer)
}
Run Code Online (Sandbox Code Playgroud)

但是,最简单的方法是:

subview.gestureRecognizers?.forEach(subview.removeGestureRecognizer)
Run Code Online (Sandbox Code Playgroud)

我们也可以在for循环中过滤子视图,如下所示:

for subview in subviews where subview is CustomSubview {
    for recognizer in subview.gestureRecognizers ?? [] {
        subview.removeGestureRecognizer(recognizer)
    }
}
Run Code Online (Sandbox Code Playgroud)

或者我们可以将它们全部包装成一个表达式(为清晰起见而包装):

subviews.lazy.filter { $0 is CustomSubview }
    .flatMap { $0.gestureRecognizers ?? [] }
    .forEach { $0.view?.removeGestureRecognizer($0) }
Run Code Online (Sandbox Code Playgroud)

使用.lazy应该防止它创建不必要的临时数组.

原版的

这是关于Swift的令人讨厌的事情之一.你的for循环只能在Objective-C中工作,但在Swift中你必须显式展开可选数组:

if let recognizers = subview.gestureRecognizers {
    for recognizer in recognizers {
        subview.removeGestureRecognizer(recognizer as! UIGestureRecognizer)
    }
}
Run Code Online (Sandbox Code Playgroud)

你可以强制解包它(for recognizer in subview.gestureRecognizers!),但是我不确定是否gestureRecognizers可以返回nil,如果确实如此,你将得到一个运行时错误,你强制解包它.


use*_*836 28

最简单的解决方案

yourView.gestureRecognizers?.removeAll()
Run Code Online (Sandbox Code Playgroud)

  • 这是错误的,从视图中删除手势识别器不仅仅是释放它(就像您在代码中所做的那样)。您还必须从视图中分离识别器:https://developer.apple.com/documentation/uikit/uiview/1622413-removegesturerecognizer (2认同)

Ah *_*oon 10

更简单的方法是

for subview in self.subviews as [UIView] {
    if subview.isKindOfClass(CustomSubview) {
        subview.gestureRecognizers?.removeAll(keepCapacity: false)
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 你也可以调用`gestureRecognizers?.removeAll()` (11认同)