不使用NavigationStack/NavigationView,点击按钮能否跳转新视图?
在SwiftUI里,你不能像命令式编程那样直接在按钮的action闭包里"调用"视图——因为SwiftUI是声明式UI框架,视图的显示完全由状态驱动,action闭包只负责修改状态,视图会根据状态自动更新。你之前的代码里,getView(view:)只是返回了一个视图实例,但没有把它加入到当前的视图层级中,所以才会出现"Result of call to 'getView(view:)' is unused"的提示。
下面提供两种常用的实现方式:
方式一:用Sheet弹窗显示新视图
通过@State变量控制弹窗的显示/隐藏,点击按钮时修改状态,SwiftUI会自动弹出目标视图:
import SwiftUI struct BasicButton: View { var buttonLabel = "Create User" // 添加状态变量,控制是否显示目标视图 @State private var showTargetView = false var body: some View { Button { // 点击按钮时切换状态,触发弹窗 showTargetView = true } label: { Text(buttonLabel) .foregroundStyle(.white) .font(.title2) } .frame(width: 250, height: 55) .background(.blue) .cornerRadius(10) // 绑定状态,状态为true时显示目标视图 .sheet(isPresented: $showTargetView) { getView(view: "CreateUser") } } } // 将返回类型改为some View,适配SwiftUI的不透明类型返回,比any View更高效 @ViewBuilder func getView(view: String) -> some View { switch view { case "CreateUser": CreateUser() default: EmptyView() } } struct CreateUser: View { var body: some View { Text("Hello") .navigationTitle("Create User") } } #Preview { BasicButton() } #Preview { CreateUser() }
方式二:用条件渲染替换当前视图
如果需要直接替换当前页面的内容(而非弹窗),可以通过状态变量控制视图的切换:
import SwiftUI struct BasicButton: View { var buttonLabel = "Create User" // 状态变量标记当前显示的视图类型 @State private var currentView: String? = nil var body: some View { // 根据状态值决定显示的视图 if let viewName = currentView { getView(view: viewName) } else { Button { // 点击按钮切换视图状态 currentView = "CreateUser" } label: { Text(buttonLabel) .foregroundStyle(.white) .font(.title2) } .frame(width: 250, height: 55) .background(.blue) .cornerRadius(10) } } } @ViewBuilder func getView(view: String) -> some View { switch view { case "CreateUser": CreateUser() default: EmptyView() } } struct CreateUser: View { // 利用环境变量实现返回逻辑 @Environment(\.dismiss) private var dismiss var body: some View { VStack { Text("Hello") Button("返回") { dismiss() } .padding() } .navigationTitle("Create User") } } #Preview { BasicButton() } #Preview { CreateUser() }
关键说明:
- 状态驱动核心:所有视图的显示、切换都依赖
@State这类状态变量,SwiftUI会自动监听状态变化并更新视图层级。 - @ViewBuilder优化:将
getView的返回类型从any View改为some View,能避免不必要的类型擦除,更符合SwiftUI的设计逻辑。 - 返回逻辑:弹窗方式可通过
@Environment(\.dismiss)实现返回;条件渲染方式可修改状态变量回到原视图。
内容的提问来源于stack exchange,提问作者Bartender1382
相关产品推荐
相关产品推荐

