首次传递可选类型变量至Sheet时被判定为nil的问题排查
问题原因及解决方案
问题原因
你遇到的问题核心在于SwiftUI中.sheet(isPresented:)的工作机制:当用isPresented绑定布尔值控制Sheet显示时,Sheet的内容视图会在父视图首次渲染时就被预加载,并捕获当时的状态值。首次点击按钮时,targetLast5Day = day和showLast5DaySheet.toggle()几乎同时触发,但SwiftUI的状态更新是批量处理的,Sheet可能在targetLast5Day完成赋值前就完成了初始化,因此拿到的还是初始的nil值。而第二次打开时,targetLast5Day已经是上次赋值后的非nil状态,Sheet就能正常获取到值。
解决方案
改用SwiftUI提供的.sheet(item:)绑定方式,这种方式专门处理基于可选值的Sheet显示,会监听可选值的变化,当可选值从nil变为非nil时自动显示Sheet,且能保证Sheet拿到最新的赋值:
- 确保
Day类型遵循Identifiable协议(如果还没实现):struct Day: Identifiable { let id = UUID() // 你的其他属性定义 } - 移除原有的
showLast5DaySheet布尔变量,直接用targetLast5Day控制Sheet:// 移除这个变量:@State private var showLast5DaySheet = false // 按钮代码修改为: Button { targetLast5Day = day } label: { CalendarItemMainPageView(passedDay: day) } // Sheet代码修改为: .sheet(item: $targetLast5Day) { selectedDay in DaySheetView(passedDay: selectedDay, habitMoved: { habit, to in handleHabitMove(for: habit, to: to) }) }
这样修改后,每次点击按钮给targetLast5Day赋值时,Sheet会直接基于最新的selectedDay初始化,完全避免了首次打开时状态不同步的问题。
内容的提问来源于stack exchange,提问作者Mark George
相关产品推荐
相关产品推荐

