2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[SwiftUI] allowsHitTestingを利用してGestureの活性・非活性をコントロールする

Last updated at Posted at 2020-07-21

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をダブルタップしても何も起きない

こんな感じ

sample

ソースコード

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かと思います :ok_woman: (そのようなケースのほうが多そう)

サンプルコードのリポジトリ

いじってみたい方はこちらからどうぞ。
Previewでも普通に動作確認できました。

環境

  • Xcode 11.4
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?