如何将 DragGesture 添加到 TabView 的子视图,同时仍确保 TabView 内的子视图可滚动?

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

我已向每个图像添加了一个 DragGesture,它按预期工作并打印“子视图拖动已工作”。但现在,滑动 TabView 的视图之间不再起作用。

struct ContentView: View {
    var body: some View {
        SliderView()
    }
}

struct SliderView: View {
    let images = ["image1", "image2", "image3", "image4", "image5"]
    @State private var selectedTab = 2

    var body: some View {
        VStack {
            TabView(selection: $selectedTab) {
                ForEach(images.indices, id: \.self) {
                    Image("\(images[$0])")
                        .resizable()
                        .ignoresSafeArea()
                        .scaledToFill()
                        .tag($0)
                        .gesture(
                            DragGesture(minimumDistance: 3.0, coordinateSpace: .local)
                                .onEnded { value in
                                    if value.translation.height > 50 {
                                        print("sub-view drag worked.")
                                    }
                                }
                        )
                }
            }
            .tabViewStyle(.page(indexDisplayMode: .always))
        }
        .ignoresSafeArea()
    }
}
swiftui
1个回答
0
投票

拖动手势拦截了滑动手势,滑动手势本身实际上也只是一个拖动手势。您没有描述您期望两者如何能够一起工作,而且很难看出他们如何能够一起工作。

但是,一种可能性是将拖动手势限制在屏幕的特定区域,也许是中心区域:

  • 如果拖动手势从中心区域开始,则由您的手势处理程序解释
  • 否则,如果手势从屏幕的侧面或顶部开始,则由
    TabView
    解释。

这是示例的更新版本,以这种方式工作。

  • 在图像上应用几乎透明的覆盖层,所有边都有 50pt 的填充。
  • 由于图像是缩放至填充的,因此需要使用
    GeometryReader
    来测量屏幕尺寸,以便将图像裁剪到帧大小。
GeometryReader { proxy in
    TabView(selection: $selectedTab) {
        ForEach(images.indices, id: \.self) {
            Image("\(images[$0])")
                .resizable()
                .scaledToFill()
                .frame(width: proxy.size.width, height: proxy.size.height)
                .clipped()
                .overlay {
                    Color.black
                        .opacity(0.001)
                        .gesture(
                            DragGesture(minimumDistance: 3.0, coordinateSpace: .local)
                                .onEnded { value in
                                    if value.translation.height > 50 {
                                        print("sub-view drag worked.")
                                    }
                                }
                        )
                        .padding(50)
                }
                .ignoresSafeArea()
                .tag($0)
        }
    }
    .tabViewStyle(.page(indexDisplayMode: .always))
}
.ignoresSafeArea()

如果您想查看叠加层覆盖的区域,请将不透明度从 0.001 更改为 0.1。我已经为下面的屏幕录制做到了这一点:

Animation

© www.soinside.com 2019 - 2024. All rights reserved.