iOS14で動作しません
iOS14で動作しなくなっていたので、対応を下記ブログにまとめました。
https://kentaro.app/posts/fix-swiftui-allows-hit-testing-sample
概要
allowsHitTesting()
を利用すると、「○○な時はGestureで何かしたいけど、xxなときはGesture効かないようにしたい」みたいなことが実現可能です。
簡単なサンプルを作ったので、それをもとに説明します。
サンプル
-
allowsHitTesting
をON / OFFするToggle
-
Toggle
がONのときはViewをダブルタップすると背景色が切り替わる -
Toggle
がOFFの場合はViewをダブルタップしても何も起きない
こんな感じ
ソースコード
import SwiftUI
struct ContentView: View {
@State private var allowsHitTesting = true
@State private var isDark = false
var body: some View {
VStack {
Toggle(
"allowsHitTestingのON / OFF",
isOn: $allowsHitTesting
)
Divider()
Text("allowsHitTestingがONのときは、ダブルタップで背景色が変化します。")
.frame(
maxWidth: .infinity,
maxHeight: .infinity
)
}
.contentShape(Rectangle())
.padding()
.foregroundColor(
Color(isDark ? .systemBackground : .label)
)
.allowsHitTesting(allowsHitTesting)
.gesture(
TapGesture(count: 2)
.onEnded {
self.isDark.toggle()
}
)
.background(
Color(isDark ? .label : .systemBackground)
.edgesIgnoringSafeArea(.all)
)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
解説
allowsHitTesting(_:)
このビューがヒットテスト操作に参加するかどうかを設定します。
このメソッドに Bool
を渡すとヒットテスト操作に参加する / しない が設定できます。
-
true
-
Gesture
等の操作を受け付ける
-
-
false
-
Gesture
等の操作を受け付けない
-
サンプルコードでは Toggle
の値を allowsHitTesting()
に渡して、 Toggle
がONのときはViewのタップ操作を受け付け、OFFのときは何もしない、という動作を実現しています。
disabled(_:) ではダメなのか?
+.disabled(!allowsHitTesting)
-.allowsHitTesting(allowsHitTesting)
↑でよさそうな感じもするが、 disabled(_:)
だと Toggle
も効かなくなってしまいます。
disabled(_:)
で問題ないView構造の場合はdisabledを利用するのでOKかと思います (そのようなケースのほうが多そう)
サンプルコードのリポジトリ
いじってみたい方はこちらからどうぞ。
Previewでも普通に動作確認できました。
環境
- Xcode 11.4