我有一个按钮,我想在单击它时链接到另一个视图。有人告诉我将其放在 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)
}
}
如有任何帮助/建议,我们将不胜感激!
您不应该使用
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)
我个人认为前者更有意义。