UIButton等の同時タップをまとめて禁止する方法を調べた結果、exclusiveTouchの値を一括して変更する方法が複数存在しました。
- Method Swizzlingを利用する
- ビューの階層をたどって一つずつ変更する
- exclusiveTouchをオーバーライドして常にtrueを返す
Method Swizzlingを利用したくないしビューをたどるのも不格好、オーバーライドして値を決め打ちにするのはよろしくないので、Swiftで以下の方法を考えました。
var exclusiveTouchKey: UInt32 = 0
extension UIControl {
public override var exclusiveTouch: Bool {
get {
let value = objc_getAssociatedObject(self, &exclusiveTouchKey) as? Bool
return value ?? true
}
set {
objc_setAssociatedObject(self, &exclusiveTouchKey, newValue, .OBJC_ASSOCIATION_RETAIN)
}
}
}
これを定義しておくだけでUIControlのexclusiveTouchがデフォルトでtrueになります。また、値を変更することも可能です。
exclusiveTouchをオーバーライドするのですが、associated objectがnilの場合(初期値)はtrueに設定して、exclusiveTouchをセットするとassociated objectに値が設定されfalseに変更することもできるようになっています。副作用が無いかは検証しきれていませんが、簡単な動作検証では正常に動作しました。