【问题标题】:How to remove all gesture recognizers from a UIView in Swift如何从 Swift 中的 UIView 中删除所有手势识别器
【发布时间】:2014-11-30 03:15:13
【问题描述】:

我编写了 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]??,并且我认为双重包装的返回值让我感到困惑。谁能帮帮我?

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

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

【问题讨论】:

    标签: ios uiview swift uigesturerecognizer optional


    【解决方案1】:

    iOS 11 更新

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

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

    更新

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

    此外,通过使用零合并运算符??,您可以避免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,如果返回,您将收到运行时错误,然后您强制解包。

    【讨论】:

    • 谢谢!我现在在你的帮助下编译它!我必须对您的代码进行 2 处更改才能使其编译:1) for 循环需要 recognizers 强制解包和 2) recognizer 参数必须强制转换为 UIGestureRecognizer,因为 UIView 的 gestureRecognizers 方法返回一个数组任何对象。我将编辑我的问题以包含最终代码。
    • 你还需要投射它:subview.removeGestureRecognizer(gesture as UIGestureRecognizer)
    • 演员表在 iOS 9.0 中已过时。
    【解决方案2】:

    最简单的解决方案

    yourView.gestureRecognizers?.removeAll()
    

    【讨论】:

    • view.gestureRecognizers = []
    • 这是最好的解决方案。删除单个手势(例如: cell?.removeGestureRecognizer(swipeLeft) )对我不起作用。
    • 这是错误的,从视图中删除手势识别器不仅仅是释放它(就像您在代码中所做的那样)。您还必须从视图中分离识别器:developer.apple.com/documentation/uikit/uiview/…
    【解决方案3】:

    更简单的方法是

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

    【讨论】:

    • 您也可以拨打gestureRecognizers?.removeAll()
    猜你喜欢
    • 2012-06-12
    • 1970-01-01
    • 2013-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多