列表项内的 NavigationLink 内的按钮无法正常工作

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

我有一个按钮,我想在单击它时链接到另一个视图。有人告诉我将其放在 NavigationLink 中,使用 .borderless 按钮样式,但它会在整个列表行的区域之外激活。我尝试使用导航视图或在其他建议中禁用导航链接,但它不能解决问题或只是弄乱了我的视图,所以我一定做错了什么。

这是列表项视图

struct NodeListItem: View {
 var body: some View {
   LazyVStack(alignment: .leading) {
    //has more information up here I don't think is relevant
     HStack {
        NavigationLink(destination: UserMessageList(user: node.user!)) {
            Button("DM") {
              //don't actually need it to do anything besides changing views
             }
           //.borderless does nothing I want it to have a border
            .buttonStyle(.borderedProminent) 
            }
        }
     }
  }

这是我的列表视图

struct NodeList: View {
 var body: some View {
   NavigationStack {
     List(nodes, id: \.self) { node in
        NodeListItem(node: node)
            .contextMenu {
                 Button {
                    node.user!.mute = !node.user!.mute
                    } label: {
                        Label(node.user!.mute ? "Show DM Alerts" : "Hide DM Alerts", systemImage: node.user!.mute ? "bell" : "bell.slash")
                    }
                    
                    if bleManager.connectedPeripheral != nil {
                        Button (role: .destructive) {
                            deleteNodeId = node.num
                            isPresentingDeleteNodeAlert = true
                        } label: {
                            Label("Delete Node", systemImage: "trash")
                        }
                    }
              }
        }
       .listStyle(.plain)
   }
}

如有任何帮助/建议,我们将不胜感激!

swift list swiftui swiftui-navigationlink swiftui-navigationstack
1个回答
0
投票

您不应该使用

NavigationLink
。您应该在按钮的操作闭包中以编程方式进行导航。

假设

nodes
的类型是
[Node]
,你可以添加一个代表导航路径的
@State
,如下所示:

@State private var path: [Node] = []
let nodes = [...]

var body: some View {
    NavigationStack(path: $path) {
        List(nodes, id: \.self) { node in
            NodeListItem(node: node) {
                // programmatic navigation
                path.append(node)
            }
            .contextMenu { ... }
        }
        .navigationDestination(for: Node.self) { node in
            UserMessageList(user: node.user!)
        }
    }
}

请注意,

UserMessageList
的导航目的地是在
List
上声明的,而不是每个单独的
NodeListItem

NodeListItem
应更改为关闭其按钮操作:

struct NodeListItem: View {
    let node: Node
    let buttonAction: () -> Void
    
    var body: some View {
        LazyVStack(alignment: .leading) {
            // ...
            HStack {
                // ...
                Button("DM") {
                    buttonAction()
                }
                .buttonStyle(.borderedProminent)
            }
        }
    }
}

当然,你也可以传一个导航路径的

@Binding
,在
path.append
中做
NodeListItem

struct NodeListItem: View {
    let node: Node
    @Binding var path: [Node]
    
    var body: some View {
        LazyVStack(alignment: .leading) {
            // ...
            HStack {
                // ...
                Button("DM") {
                    path.append(node)
                }
                .buttonStyle(.borderedProminent)
            }
        }
    }
}

// ...

NodeListItem(node: node, path: $path)

我个人认为前者更有意义。

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