SwiftUI中Popover内列表仅在Picker存在时才填充数据的原因?
SwiftUI Popover 仅在Picker存在时加载数据的异常问题
问题背景
原本计划实现一个带Picker的日历选择菜单,需要显示带对应颜色的圆形标识及标题,但发现无法为Picker菜单中的图标上色,因此改用自定义Popover+列表的方案,却遇到了异常情况。
环境配置
- 存在异步数据管理类,负责数据的创建与获取,用于填充Picker菜单和Popover列表
- 视图通过
@State属性存储获取到的数据 - 使用
.task修饰符(也曾尝试在onAppear中启动Task)执行数据获取操作 - 视图结构为
VStack,包含触发Popover的按钮和作为菜单的Picker,两者共用同一数据源
问题现象
- 注释掉Picker代码时,Popover始终为空(仅保留框架)
- 取消注释Picker后,Picker和Popover内的列表均能正常显示数据
- 核心疑问:为何Popover内的列表仅在Picker存在时才会填充数据?
已尝试的解决方案
- 将Popover视图单独拆分到独立文件
- 用
onAppear替代.task修饰符执行数据获取 - 将Popover内的
List替换为VStack - 将数据获取结果存储在数据管理类的可选属性中,每次获取完成后重置该属性
可复现代码
import SwiftUI struct TestView: View { let dataManager = DataManager() @State private var items: [DataItem] = [] @State private var popoverIsPresented = false var body: some View { VStack { Button { popoverIsPresented = true } label: { Text("Choose Item") } .popover(isPresented: $popoverIsPresented, content: { List { ForEach(items) { item in Text(item.title) } } }) // List { // ForEach(items) { item in // Text(item.title) // } // } } .task { items = await dataManager.fetchData() } } } #Preview { TestView() .frame(minWidth: 300, minHeight: 300) } struct DataItem: Identifiable { let id = UUID() let title: String } class DataManager { func fetchData() async -> [DataItem] { Array(repeating: .init(title: "This is an example item"), count: 10) } }
操作步骤
- 直接运行上述代码
- 取消注释Picker部分的代码,即可观察到两个视图均正常显示数据
初步猜测
Popover未在@State属性更新后触发视图刷新,推测这是SwiftUI的框架bug。
内容的提问来源于stack exchange,提问作者MarlonJames
相关产品推荐
相关产品推荐

