如何在SwiftUI中将NavigationLink显示为按钮
我在这里读了很多关于SwiftUI导航的文章,并尝试了一些方法,但都没有达到预期效果 基本上,我有一个包含训练列表的视图,您可以通过单击一行来显示单个训练。这与使用NavigationView和NavigationLink时的预期效果一样 现在,我想在“详细信息”视图上单击一个按钮开始训练。这将打开一个带有计时器的视图。该视图应显示与细节视图相同的动画,并在导航栏中用后退按钮显示训练名称 我可以通过详细信息页面上的NavigationLink视图来实现这一点,但该链接始终显示为一个全宽行,箭头位于右侧。我希望这是一个按钮,而不是,但导航链接似乎是抵制样式如何在SwiftUI中将NavigationLink显示为按钮,navigation,swiftui,Navigation,Swiftui,我在这里读了很多关于SwiftUI导航的文章,并尝试了一些方法,但都没有达到预期效果 基本上,我有一个包含训练列表的视图,您可以通过单击一行来显示单个训练。这与使用NavigationView和NavigationLink时的预期效果一样 现在,我想在“详细信息”视图上单击一个按钮开始训练。这将打开一个带有计时器的视图。该视图应显示与细节视图相同的动画,并在导航栏中用后退按钮显示训练名称 我可以通过详细信息页面上的NavigationLink视图来实现这一点,但该链接始终显示为一个全宽行,箭头位
struct WorkoutDetail: View {
var workout: Workout
var body: some View {
VStack {
NavigationLink(destination: TimerView()) {
Text("Starten")
}.navigationBarTitle(Text(workout.title))
}
}
}
struct WorkoutList: View {
var workoutCollection: WorkoutCollection
var body: some View {
NavigationView {
List(workoutCollection.workouts) { workout in
NavigationLink(destination: WorkoutDetail(workout: workout)) {
WorkoutRow(workout: workout)
}
}.navigationBarTitle(Text("Workouts"))
}
}
}
更新:这里有一个屏幕截图来说明我的意思:
我自己已经玩了几天了。我想这就是你要找的
struct WorkoutDetail: View {
var workout: Workout
var body: some View {
NavigationView {
VStack {
NavigationLink(destination: TimerView()) {
ButtonView()
}.navigationBarTitle(Text(workout.title))
}
}
}
并创建要在NavigationLink中显示的视图
struct ButtonView: View {
var body: some View {
Text("Starten")
.frame(width: 200, height: 100, alignment: .center)
.background(Color.yellow)
.foregroundColor(Color.red)
}
注意:导航视图上方的任何内容都会显示在导航中的所有页面上,从而使导航视图在链接中的大小变小。您不需要将视图包装在
导航链接中,以使其在按下时触发导航
我们可以用NavigationLink
绑定一个属性,无论执行什么操作,只要更改该属性,我们的导航就会触发。例如:
struct SwiftUI: View {
@State private var action: Int? = 0
var body: some View {
NavigationView {
VStack {
NavigationLink(destination: Text("Destination_1"), tag: 1, selection: $action) {
EmptyView()
}
NavigationLink(destination: Text("Destination_2"), tag: 2, selection: $action) {
EmptyView()
}
Text("Your Custom View 1")
.onTapGesture {
//perform some tasks if needed before opening Destination view
self.action = 1
}
Text("Your Custom View 2")
.onTapGesture {
//perform some tasks if needed before opening Destination view
self.action = 2
}
}
}
}
}
无论何时更改可绑定属性的值(即操作)导航链接
都会将其标记的预定义值与绑定属性操作
进行比较,前提是两者相等
因此,您可以以任何方式创建视图,也可以从任何视图触发导航,而不必考虑任何操作,只需使用NavigationLink
绑定的属性即可
谢谢,希望有帮助。使用按钮标签内的导航链接
Button(action: {
print("Floating Button Click")
}, label: {
NavigationLink(destination: AddItemView()) {
Text("Open View")
}
})
例如,我认为准确的方法是使用按钮样式
NavigationLink(destination: WorkoutDetail(workout: workout)) {
WorkoutRow(workout: workout)
}
.buttonStyle(ButtonStyle3D(background: Color.yellow))
您可以将NavigationLink as按钮与ZStack一起使用:
@State var tag:Int? = nil
ZStack {
NavigationLink(destination: MyModal(), tag: 1, selection: $tag) {
EmptyView()
}
Button(action: {
self.tag = 1
}, label: {
Text("show view tag 1")
})
}
希望能有所帮助。与的解决方案非常相似,但删除了ZStack:
struct ContentView: View {
@State var selectedTag: String?
var body: some View {
Button(action: {
self.selectedTag = "xx"
}, label: {
Image(systemName: "plus")
})
.background(
NavigationLink(
destination: Text("XX"),
tag: "xx",
selection: $selectedTag,
label: { EmptyView() }
)
)
}
}
等待没有状态的更简洁的解决方案。您呢?您可以将导航链接直接添加到按钮,如下所示:
@State var tag:Int? = nil
...
NavigationLink(destination: Text("Full List"), tag: 1, selection: $tag) {
MyButton(buttonText: "Full list") {
self.tag = 1
}
}
我不知道为什么所有这些答案都让事情变得如此复杂。在Swiftui2.0中,您只需在导航链接中添加按钮
NavigationLink(destination: TimerView()) {
Text("Starten")
}
您可以对文本
对象应用SwiftUI样式,就像对任何其他元素应用样式一样。如何填充训练
?每件事背后都有模型(通常是某种形式的@ObjectBinding
)吗?换句话说,你是如何获得应用程序的训练状态的?我已经更新了帖子以显示列表视图以显示训练是如何填充的。workoutCollection已加载并移交给SceneDelegate类中的列表视图。谢谢,但不幸的是,这并不是我的问题。我用截图更新了我的问题。问题是,我得到一行链接,文本左对齐,箭头右对齐。但我想要的是一个普通的按钮。我还不确定答案,但现在我还要寻找解决方案。如果您从一个视图开始并转到一个新视图(总共两个视图),上面的代码可以正常工作,就像您希望的那样。如果您从带有导航链接的列表视图开始,然后转到workoutDetail视图,然后是timer视图,它将放入>(总共3个视图)。用上面的代码尝试一个测试项目,你就会明白我的意思。是的,它的工作原理和我想要的完全一样,现在唯一的问题是按钮的外观。在你的WorkoutList中,将“List”更改为“ForEach”。这就消除了所有的>。可能不是最终的解决方案,但可能会让您更接近。谢谢-我已经寻找了一段时间。这是一个有趣的解决方案,我们不应该在Swift中遇到这个问题。当我在Swift 5.2中实现此功能时,偶尔会出现错误:SwiftUI在推送aNavigationLink时遇到问题。请提交一个bug。使用标签是一个危险的解决方案,因为可能存在另一个组件,您可以在其中获得混合行为或不同的方法,不建议这样做,而是创建一个包装器,允许您使用外部任何人都无法复制的特定IDit@Kross不了解这里的风险。在app store上有2个使用这种方法的复杂应用程序,并且从未在任何地方遇到过任何混合行为。标记是在组件内创建的,并与同一组件的NavigationLink连接,因此无法从任何其他组件访问该组件。因此,外部组件可以自由复制标记并附加其导航链接,这不会影响当前组件的行为和导航。如果这不是您提到的风险,请发布您的解决方案,它将有助于更好地理解。rbaldwin我在几个案例中尝试过,我甚至将更多组件放入其中,并且它正常工作。也许你可以上传那部分代码,这样我就能帮你了。这正是我想要的。没有意识到可以将按钮样式添加到Navigationlinks。哇!要简化这么多代码!同意。这是目前SwiftUI 2Best的最佳答案。我们可以为按钮实现自定义样式,因此这是对我来说最简单、最干净的解决方案。因为这是一个SwiftUI 1.0问题。因为即使在SwiftUI 2.0中,您也可以使用您的方法获得附件箭头