如何通过在 SwiftUI 中插入不可见且拦截的视图来专门阻止触摸?

问题描述 投票:0回答:1

在 SwiftUI 中,我想通过在层次结构中插入透明视图并拦截它们来有条件地阻止触摸。

我不想以更抽象的方式来做,因为我发现这更简单。

这里是起点:

struct ContentView: View {
    
    @State var blockTouches:Bool = false
    
    var body: some View {
        
        VStack{
            Text("toggle touch blocking")
                .padding()
                .padding()
                .onTapGesture {
                    blockTouches.toggle()
                }
            ZStack{
                VStack{
                    Color.red.opacity(0.5).onTapGesture {
                        print("TOUCHED RED")
                    }
                    Color.blue.opacity(0.5).onTapGesture {
                        print("TOUCHED BLUE")
                    }
                }
                if blockTouches {
                    // The view is not rendered and touches are not blocked here.
                    Color.clear.onTapGesture {
                        print("TOUCH BLOCKED!")
                    }
                }
            }
        }
    }
}

但是,由于我们使用了 Color.clear,框架决定根本不需要渲染该视图,因此触摸不会被阻止。

我尝试用各种方式来欺骗它:

Rectangle()
    .fill(Color.clear)
    .onTapGesture {
        print("TOUCH BLOCKED!")
        }
    .background(Color.clear)

但只发现这个有效(即轻微的不透明度):

Color.white.opacity(0.0001).onTapGesture {
    print("TOUCH BLOCKED!")
}

没有更好/正常的方法吗?

ios swiftui touch-event swiftui-gesture
1个回答
0
投票

您可以尝试这种简单的方法,使用

allowsHitTesting(...)

struct ContentView: View {
    @State var blockTouches = false
    
    var body: some View {
        VStack {
            Button("Touch blocking \(blockTouches ? "ON" : "OFF")") {
                blockTouches.toggle()
            }.buttonStyle(.bordered)
            
            ZStack {
                VStack {
                    Color.red.opacity(0.5)
                        .onTapGesture {
                            print("TOUCHED RED")
                        }
                    Color.blue.opacity(0.5)
                        .onTapGesture {
                            print("TOUCHED BLUE")
                        }
                }.allowsHitTesting(!blockTouches) // <--- here
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.