感谢here 的部分回答,这里有一些工作代码。
首先,我将所有内容都移到了EnvronmentObject 中,以便更轻松地传递给您的第二个视图。我还添加了一个 second 切换变量:
class Model: ObservableObject {
@Published var fieldValue = ""
@Published var showErrorMessage = false
@Published var showSecondView = false
}
接下来,更改 ContentView 中的两件事。我添加了一个隐藏的NavigationLink(带有isActive 参数)来实际触发推送,同时更改您的Button 操作以执行本地函数:
struct ContentView: View {
@EnvironmentObject var model: Model
var body: some View {
NavigationView {
VStack {
TextField("My Field", text: $model.fieldValue).textFieldStyle(RoundedBorderTextFieldStyle())
NavigationLink(destination: SecondView(), isActive: $model.showSecondView) {
Text("NavLink")
}.hidden()
Button(action: {
self.checkForText()
}) {
Text("Next")
}
.alert(isPresented: self.$model.showErrorMessage) {
Alert(title: Text("Error"), message: Text("Please enter some text!"), dismissButton: .default(Text("OK")))
}
}
}
}
func checkForText() {
if model.fieldValue.isEmpty {
model.showErrorMessage.toggle()
} else {
model.showSecondView.toggle()
}
}
}
切换showErrorMessage 将显示Alert,切换`showSecondView 将带您进入下一个视图。
最后是第二种观点:
struct SecondView: View {
@EnvironmentObject var model: Model
var body: some View {
ZStack {
Rectangle().fill(Color.green)
// workaround
.navigationBarBackButtonHidden(true) // not needed, but just in case
.navigationBarItems(leading: MyBackButton(label: "Back!") {
self.model.showSecondView = false
})
Text(model.fieldValue)
}
}
func popSecondView() {
model.showSecondView.toggle()
}
}
struct MyBackButton: View {
let label: String
let closure: () -> ()
var body: some View {
Button(action: { self.closure() }) {
HStack {
Image(systemName: "chevron.left")
Text(label)
}
}
}
}
这就是上面链接的答案对我有帮助的地方。似乎在 beta 6 中仍然存在导航返回的错误。如果没有此解决方法(切换 showSecondView),您将再次被发送回第二个视图。
您没有发布有关第二个视图内容的任何详细信息,因此我冒昧地将someText 添加到模型中,以向您展示如何使用EnvironmentObject 轻松将内容传递给它。在SceneDelegate 中需要进行一些设置:
var window: UIWindow?
var model = Model()
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
let contentView = ContentView()
// Use a UIHostingController as window root view controller.
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: contentView.environmentObject(model))
self.window = window
window.makeKeyAndVisible()
}
}
我注意到这有轻微的变化,具体取决于您的项目创建时间(beta 6 声明了 contentView 的实例,而旧版本没有)。无论哪种方式,声明一个model 的实例,然后将envoronmentObject 修饰符添加到contentView。