SwiftUI 滑动/拖动 NavigationLink

4

我希望能够通过在具有多个导航链接的NavigationView上向左/向右滑动来更新视图。这些NavigationLinks链接到不同的演示视图。

当我在最外面的视图上开始拖动手势时,如果该手势始于NavigationLink上,则该链接会更改颜色,就好像已经按下一样。继续拖动手势,主视图会按预期更新,并且NavigationLink会返回其正常状态(颜色)。

我需要的是一种方法,使得当进行拖动手势时,NavigationLink不会更改颜色。也许有一种方法可以使NavigationLink对“长按”之类的触摸作出反应。

以下是演示我所见情况的一些代码。这不是我的实际项目,而是一个非常简化的例子。

欢迎任何建议或解决方案!

import SwiftUI

struct ContentView: View {
    
    @State var outputText: String = ""
    var body: some View {
        VStack(alignment: .center, spacing: 20) {
            NavigationView {
                VStack {
                    Text("Navigation View")
                    NavigationLink(destination: Text("Showwing Widget")) {
                        HStack {
                            Text("Navigation Link")
                        }
                        .frame(width: 300, height: 200)
                        .border(Color.blue)
                    }
                    .border(Color.red)
                    Spacer()
                }
                .border(Color.yellow)
            }

            Text(outputText)
                .font(.title)
                .fontWeight(.bold)

            Text("My Green Oval")
                .foregroundColor(.white)
                .fontWeight(.bold)
                .font(.title)
                .frame(width: 300, height: 200)
                .background(
                    Ellipse()
                        .fill(Color.green)
                )
            Button(action: {
                outputText = "Button tapped"
            }) {
                Text("Button to Tap")
            }
            
            Text("Just some words...")
            Spacer()
        }
        .highPriorityGesture(DragGesture(minimumDistance: 25, coordinateSpace: .local)
            .onEnded { value in
                if abs(value.translation.height) < abs(value.translation.width) {
                    if abs(value.translation.width) > 50.0 {
                        if value.translation.width < 0 {
                            self.swipeRightToLeft()
                        } else if value.translation.width > 0 {
                            self.swipeLeftToRight()
                        }
                    }
                }
            }
        )
    }
    
    func swipeRightToLeft() {
        outputText = "Swiped Right to Left <--"
    }
    
    func swipeLeftToRight() {
        outputText = "Swiped Left to Right -->"
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

1个回答

3

经过长时间的尝试,我找到了一个解决方案!虽然有点取巧,但只需很少的努力即可实现。通过在视图上设置条件偏移量,可以根据抽屉行是否打开进行配置,并创建一个状态变量来跟踪用户是否正在拖动。您可以使用UIScreen.main.bounds.width获取屏幕宽度。

.offset(x: self.isOpen ? -screenWidth/12 : 0, y: 0)
                .simultaneousGesture(DragGesture()
                            .onChanged{ gesture in
                                self.isDragging = true
                                self.offset = gesture.translation.width
                            }
                            .onEnded { _ in
                                self.isDragging = false
                                if self.offset > 0 {
                                    withAnimation {
                                        self.isOpen = false
                                        self.offset = 0
                                    }
                                } else if self.offset < 0 {
                                    withAnimation {
                                        self.isOpen = true
                                        self.offset = 0
                                    }
                                }
                            })

然后在你的NavigationLink上添加这个disable修饰符

.disabled(self.isDragging || self.isOpen)

祝你好运!希望如果你还没有找到解决方案,这个方法也可以对你有用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接