SwiftUI导航栏内嵌按钮打开DetailView的实现问题
我来帮你搞定这个问题!你现在的问题是直接在Button的action里创建DetailView实例根本不会生效——毕竟SwiftUI是声明式框架,视图的展示得靠状态驱动,不能像命令式那样直接“调用”视图。下面给你两种常用的实现方式,你可以根据需求选:
方案一:通过隐藏的NavigationLink实现导航栈跳转
如果希望DetailView是推入导航栈的形式(和普通NavigationLink跳转一致),可以把NavigationLink放到NavigationView的层级内,用你已经定义的isAddPresented状态来控制它的激活状态,同时把它隐藏起来不显示在界面上:
import SwiftUI struct ContentView: View { @ObservedObject var dm: DataManager @State var isAddPresented = false var body: some View { NavigationView { HStack { List () { ForEach (dm.storage) { data in StileCella(dm2: data) } } .navigationBarTitle("Lista Rubrica") .navigationBarItems(trailing: Button(action: { self.isAddPresented = true }) { Text("Button") }) // 隐藏的NavigationLink,通过状态控制跳转 NavigationLink( destination: DetailView(), isActive: $isAddPresented, label: { EmptyView() } ) .hidden() } } } } struct DetailView: View { var body: some View { VStack(alignment: .center) { Text("CIAO").bold() Spacer() Image(systemName: "star") .resizable() .frame(width: 100, height: 100) // 给图片加个尺寸,避免无法显示 } } }
这里的关键是:
- 把NavigationLink放在NavigationView的子视图层级里(必须在NavigationView范围内)
- 用
isActive绑定你的isAddPresented状态变量,点击按钮时修改状态,触发导航 - 用
EmptyView()作为标签并添加.hidden(),让它只负责逻辑,不显示界面元素
方案二:用Sheet实现模态弹出
如果你希望DetailView是以模态弹窗的形式出现(而非推入导航栈),可以用SwiftUI的.sheet修饰符,同样用isAddPresented状态控制:
import SwiftUI struct ContentView: View { @ObservedObject var dm: DataManager @State var isAddPresented = false var body: some View { NavigationView { HStack { List () { ForEach (dm.storage) { data in StileCella(dm2: data) } } .navigationBarTitle("Lista Rubrica") .navigationBarItems(trailing: Button(action: { self.isAddPresented = true }) { Text("Button") }) } } // 添加sheet修饰符,控制模态视图的展示 .sheet(isPresented: $isAddPresented) { DetailView() } } } struct DetailView: View { var body: some View { VStack(alignment: .center) { Text("CIAO").bold() Spacer() Image(systemName: "star") .resizable() .frame(width: 100, height: 100) } } }
这种方式下,点击按钮会从底部弹出DetailView,你可以通过点击弹窗的返回按钮(或者向下滑动弹窗)来关闭它,适合不需要加入导航栈的场景。
总的来说,SwiftUI的核心是状态驱动UI,所有视图的展示/隐藏/跳转都要通过状态变量来触发,而不是直接在action里创建视图实例。上面两种方式都能解决你的问题,选哪种就看你想要的交互形式啦!
内容的提问来源于stack exchange,提问作者Damiano Miazzi
相关产品推荐
相关产品推荐

