特定のカスタムUIViewタイプのすべてのサブビューからすべてのジェスチャレコグナイザーを削除しようとするSwiftコードを記述しました。
_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)
}
}
_
一般的に、(allジェスチャーがビューからgestureRecognizers
配列をループすることで認識する)を削除するのは(そしてこれまでずっと)悪い考えです。 yoビューに追加するジェスチャレコグナイザーのみを削除する必要があります。これらのレコグナイザーを追跡するには、独自のインスタンス変数を使用します。
これは、UIKitが独自のジェスチャー認識機能をそれらのビューに追加してドラッグアンドドロップを認識するため、iOS 11でドラッグアンドドロップに関係するビューにとって新たな重要性を帯びます。
UIView.gestureRecognizers
はiOS 9.0で[UIGestureRecognizer]?
型に変更されたため、UIGestureRecognizer
にキャストする必要はなくなりました。
また、nil-coalescing演算子??
を使用することにより、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)
}
}
または、すべてを1つの式にまとめることができます(わかりやすくするためにラップしています)。
subviews.lazy.filter { $0 is CustomSubview }
.flatMap { $0.gestureRecognizers ?? [] }
.forEach { $0.view?.removeGestureRecognizer($0) }
.lazy
を使用すると、不要な一時配列が作成されなくなります。
これは、Swiftの面倒なことの1つです。 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
を返すことができるかどうかわかりません。ラップを解除します。
最も簡単なソリューション
yourView.gestureRecognizers?.removeAll()
それを行う簡単な方法は
for subview in self.subviews as [UIView] {
if subview.isKindOfClass(CustomSubview) {
subview.gestureRecognizers?.removeAll(keepCapacity: false)
}
}