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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26206452/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 03:01:46  来源:igfitidea点击:

How to remove all gesture recognizers from a UIView in Swift

iosuiviewswiftuigesturerecognizeroptional

提问by Brian McCafferty

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

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

let mySubviews = self.subviews.filter() {
   
'[AnyObject]?' does not have a member named 'Generator'
.isKindOfClass(CustomSubview) } for subview in mySubviews { for recognizer in subview.gestureRecognizers { subview.removeGestureRecognizer(recognizer) } }

But the for recognizerline produces the compiler error:

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

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

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

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

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

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

我看到 UIView 的gestureRecognizers方法返回[AnyObject]??,我认为双重包装的返回值让我绊倒了。谁能帮我?

UPDATE: Revised, compiling code is:

更新:修改后的编译代码是:

for recognizer in subview.gestureRecognizers ?? [] {
    subview.removeGestureRecognizer(recognizer)
}

回答by rob mayoff

UPDATE FOR iOS 11

iOS 11 更新

In general it is (and has always been) a bad idea to remove allgesture recognizes from a view by looping through its gestureRecognizersarray. You should only remove gesture recognizers that youadd to the view, by keeping track of those recognizers in your own instance variable.

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

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.

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

UPDATE

更新

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

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

Also, by using the nil-coalescing operator ??, you can avoid the ifstatement.

此外,通过使用 nil-coalescing operator ??,您可以避免该if语句。

subview.gestureRecognizers?.forEach(subview.removeGestureRecognizer)

However, the shortest way to do it is this:

但是,最短的方法是这样的:

for subview in subviews where subview is CustomSubview {
    for recognizer in subview.gestureRecognizers ?? [] {
        subview.removeGestureRecognizer(recognizer)
    }
}

We can also do the filtering of the subviews in a forloop like this:

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

subviews.lazy.filter { 
if let recognizers = subview.gestureRecognizers {
    for recognizer in recognizers {
        subview.removeGestureRecognizer(recognizer as! UIGestureRecognizer)
    }
}
is CustomSubview } .flatMap {
yourView.gestureRecognizers?.removeAll()
.gestureRecognizers ?? [] } .forEach {
for subview in self.subviews as [UIView] {
    if subview.isKindOfClass(CustomSubview) {
        subview.gestureRecognizers?.removeAll(keepCapacity: false)
    }
}
.view?.removeGestureRecognizer(##代码##) }

Or we can wrap it all up into one expression (wrapped for clarity):

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

##代码##

The use of .lazyshould prevent it from creating unnecessary temporary arrays.

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

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:

这是关于 Swift 的那些烦人的事情之一。你的 for 循环只能在 Objective-C 中工作,但在 Swift 中你必须显式地解开可选数组:

##代码##

You could force-unwrap it (for recognizer in subview.gestureRecognizers!), but I'm not sure whether gestureRecognizerscan return niland you'll get a runtime error if it does and you force-unwrap it.

您可以强制解包它 ( for recognizer in subview.gestureRecognizers!),但我不确定是否gestureRecognizers可以返回nil,如果返回,您将收到运行时错误并且您强制解包它。

回答by user3144836

Simplest solution

最简单的解决方案

##代码##

回答by Ah Ryun Moon

Simpler way to do that is

更简单的方法是

##代码##