带有“isActive=true”的嵌套 NavigationLinks 显示不正确
Nested NavigationLinks with `isActive=true` are not displaying correctly
我已经开始学习 SwiftUI,但是在构建我的 NavigationView 时遇到了一些问题 - 我不确定这是不是一个错误,或者我是否误解了嵌套导航 links 应该如何工作!
这是我当前的代码:
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
ViewOne()
}
}
}
struct ViewOne: View {
@State var isActiveOne: Bool = true
var body: some View {
VStack {
Text("View One")
NavigationLink(
destination: ViewTwo(),
isActive: $isActiveOne,
label: { EmptyView() }
)
Button(
action: { self.isActiveOne = true },
label: { Text("Set isActiveOne=true") }
)
}
}
}
struct ViewTwo: View {
@State var isActiveTwo: Bool = true
var body: some View {
VStack {
Text("View Two")
NavigationLink(
destination: Text("Success!"),
isActive: $isActiveTwo,
label: { EmptyView() }
)
Button(
action: { self.isActiveTwo = true },
label: { Text("Set isActiveTwo=true") }
)
}
}
}
struct ContentView_Preview: PreviewProvider {
static var previews: some View {
ContentView()
}
}
我预计:
- NavigationView 显示 ViewOne
- ViewOne 有 isActiveOne == true,因此显示第一个 NavigationLink 目标(显示 ViewTwo)
- ViewTwo 的 isActiveTwo == true,因此显示第二个 NavigationLink 目标(显示“成功!”)
但是,当我在 iOS 14.5 模拟器上 运行 这段代码时,第二个 NavigationLink 不会自动显示(我只看到 ViewTwo 按钮文本)。
我还觉得奇怪的是,如果我将 isActiveTrue 默认设置为 false,然后按下按钮,它会正确导航 - 关于默认“true”状态 + 嵌套导航的组合 link 似乎导致问题。
知道这是否是 SwiftUI 中的错误吗?还是我这里的设置有问题?
任何想法都会巨大帮助 - 我已经用头撞墙了一段时间......
这看起来像一个错误,您可以在 https://feedbackassistant.apple.com
提交它
临时解决方法是将您的 NavigationLink
放入列表中。这似乎适用于 iOS 14.5 和 15 (beta 2)
不可见列表
如果你不想要列表 behaviour/look 那么你可以将列表放在背景上并使其透明(使用 opacity
修饰符)
下面是不可见列表解决方法的示例:
struct WorkaroundLink<Destination: View>: View {
let destination: Destination
let isActive: Binding<Bool>
var body: some View {
List {
NavigationLink(
destination: destination,
isActive: isActive,
label: { EmptyView() }
)
}.opacity(0.01)
}
}
extension View {
func workaroundLink<D: View>(to destination: D, isActive: Binding<Bool>) -> some View {
background(WorkaroundLink(destination: destination, isActive: isActive))
}
}
用这个结构重写你的例子变成:
struct ContentView: View {
var body: some View {
NavigationView { ViewOne() }
}
}
struct ViewOne: View {
@State var isActiveOne = true
var body: some View {
VStack {
Text("View One")
Button("Set isActiveOne=true") { isActiveOne = true }
}.workaroundLink(to: ViewTwo(), isActive: $isActiveOne)
}
}
struct ViewTwo: View {
@State var isActiveTwo = true
var body: some View {
VStack {
Text("View Two")
Button(
action: { self.isActiveTwo = true },
label: { Text("Set isActiveTwo=true") }
)
}.workaroundLink(to: Text("Success!"), isActive: $isActiveTwo)
}
}
我已经开始学习 SwiftUI,但是在构建我的 NavigationView 时遇到了一些问题 - 我不确定这是不是一个错误,或者我是否误解了嵌套导航 links 应该如何工作!
这是我当前的代码:
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
ViewOne()
}
}
}
struct ViewOne: View {
@State var isActiveOne: Bool = true
var body: some View {
VStack {
Text("View One")
NavigationLink(
destination: ViewTwo(),
isActive: $isActiveOne,
label: { EmptyView() }
)
Button(
action: { self.isActiveOne = true },
label: { Text("Set isActiveOne=true") }
)
}
}
}
struct ViewTwo: View {
@State var isActiveTwo: Bool = true
var body: some View {
VStack {
Text("View Two")
NavigationLink(
destination: Text("Success!"),
isActive: $isActiveTwo,
label: { EmptyView() }
)
Button(
action: { self.isActiveTwo = true },
label: { Text("Set isActiveTwo=true") }
)
}
}
}
struct ContentView_Preview: PreviewProvider {
static var previews: some View {
ContentView()
}
}
我预计:
- NavigationView 显示 ViewOne
- ViewOne 有 isActiveOne == true,因此显示第一个 NavigationLink 目标(显示 ViewTwo)
- ViewTwo 的 isActiveTwo == true,因此显示第二个 NavigationLink 目标(显示“成功!”)
但是,当我在 iOS 14.5 模拟器上 运行 这段代码时,第二个 NavigationLink 不会自动显示(我只看到 ViewTwo 按钮文本)。
我还觉得奇怪的是,如果我将 isActiveTrue 默认设置为 false,然后按下按钮,它会正确导航 - 关于默认“true”状态 + 嵌套导航的组合 link 似乎导致问题。
知道这是否是 SwiftUI 中的错误吗?还是我这里的设置有问题?
任何想法都会巨大帮助 - 我已经用头撞墙了一段时间......
这看起来像一个错误,您可以在 https://feedbackassistant.apple.com
提交它临时解决方法是将您的 NavigationLink
放入列表中。这似乎适用于 iOS 14.5 和 15 (beta 2)
不可见列表
如果你不想要列表 behaviour/look 那么你可以将列表放在背景上并使其透明(使用 opacity
修饰符)
下面是不可见列表解决方法的示例:
struct WorkaroundLink<Destination: View>: View {
let destination: Destination
let isActive: Binding<Bool>
var body: some View {
List {
NavigationLink(
destination: destination,
isActive: isActive,
label: { EmptyView() }
)
}.opacity(0.01)
}
}
extension View {
func workaroundLink<D: View>(to destination: D, isActive: Binding<Bool>) -> some View {
background(WorkaroundLink(destination: destination, isActive: isActive))
}
}
用这个结构重写你的例子变成:
struct ContentView: View {
var body: some View {
NavigationView { ViewOne() }
}
}
struct ViewOne: View {
@State var isActiveOne = true
var body: some View {
VStack {
Text("View One")
Button("Set isActiveOne=true") { isActiveOne = true }
}.workaroundLink(to: ViewTwo(), isActive: $isActiveOne)
}
}
struct ViewTwo: View {
@State var isActiveTwo = true
var body: some View {
VStack {
Text("View Two")
Button(
action: { self.isActiveTwo = true },
label: { Text("Set isActiveTwo=true") }
)
}.workaroundLink(to: Text("Success!"), isActive: $isActiveTwo)
}
}