如何从 Swift 中的 UIView 中删除所有手势识别器 [英] How to remove all gesture recognizers from a UIView in Swift

查看:42
本文介绍了如何从 Swift 中的 UIView 中删除所有手势识别器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have written Swift code that attempts to remove all gesture recognizers from all subviews of a given custom UIView type.

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

但是 forreceiver 行产生编译器错误:

But the for recognizer line produces the compiler error:

'[AnyObject]?' does not have a member named 'Generator'

我尝试将 for 识别器 循环更改为 for 在 enumerate(subview.gestureRecognizers) 中的识别器,但这会产生编译器错误:

I have tried changing the for recognizer loop to for recognizer in enumerate(subview.gestureRecognizers), but that produces the compiler error:

Type '[AnyObject]?!' Does not conform to protocol 'SequenceType'

我看到 UIView 的 gestureRecognizers 方法返回 [AnyObject]??,并且我认为双重包装的返回值让我感到困惑.有人可以帮我吗?

I see that UIView's gestureRecognizers method returns [AnyObject]??, and I think that the doubly wrapped return values are tripping me up. Can anyone help me?

更新:修改后,编译代码为:

UPDATE: Revised, compiling code is:

if let recognizers = subview.gestureRecognizers {
   for recognizer in recognizers! {
      subview.removeGestureRecognizer(recognizer as UIGestureRecognizer)
   }
}

推荐答案

针对 iOS 11 的更新

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

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.

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

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.

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

You no longer need to cast to UIGestureRecognizer, because UIView.gestureRecognizers was changed to type [UIGestureRecognizer]? in iOS 9.0.

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

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)

我们也可以像这样在 for 循环中过滤子视图:

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) }

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

The use of .lazy should prevent it from creating unnecessary temporary arrays.

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

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)
    }
}

您可以强制解开它(用于 subview.gestureRecognizers 中的识别器!),但我不确定 gestureRecognizers 是否可以返回 nil 如果确实如此,您将收到运行时错误,并且您将其强制解包.

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.

这篇关于如何从 Swift 中的 UIView 中删除所有手势识别器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆