SwiftUI中Bottom Sheet内DatePicker首次选日期时尺寸异常变化问题
问题
我在Bottom Sheet里嵌了个使用.graphical样式的DatePicker,打开Bottom Sheet后第一次选择日期时,这个DatePicker的高度会突然发生变化。要是用.frame给它设置自定义高度,Picker又会被挤压变形。
(动图说明:展示Bottom Sheet中DatePicker首次选择日期时出现的高度跳动现象)
原代码如下:
var body: some View { VStack { HStack { Text("date_picker_title".ld()) .font(.custom(Font.rRegular, size: 12)) .padding() Spacer() } HStack { Text(date.prettyDate) .font(.custom(Font.rMedium, size: 28)) Spacer() Text(date.prettyHour) .font(.custom(Font.rMedium, size: 28)) }.padding(.horizontal) Seperator(cellHeight: 0).frame(height: 2) Spacer().frame(height: 6) DatePicker("", selection: $date, in: Date()..., displayedComponents: .date) .datePickerStyle(.graphical) .labelsHidden() .tint(Color.appPurple) .padding(.horizontal) .padding(.bottom, -10) Seperator(cellHeight: 0).frame(height: 2) HStack { Text("date_picker_enter_time".ld()) .font(.custom(Font.rRegular, size: 12)) DatePicker("", selection: $date, displayedComponents: .hourAndMinute) .labelsHidden() .tint(Color.appPurple) Spacer() }.padding() HStack { Button { completion(nil) } label: { Text("date_picker_cancel".ld()) .font(.custom(Font.rRegular, size: 14)) .foregroundColor(Color.appPurple) } Spacer() Button { completion(date) } label: { Text("date_picker_ok".ld()) .font(.custom(Font.rRegular, size: 14)) .foregroundColor(Color.appPurple) } }.padding(.horizontal) Spacer().frame(height: 50) } .frame(maxWidth: .infinity) .background(Color.appLightPurple) .padding(.bottom, -50) }
解决办法
方法1:用fixedSize固定垂直高度
给Graphical样式的DatePicker添加fixedSize(horizontal: false, vertical: true),让它保持初始渲染的高度,避免交互时出现跳变:
DatePicker("", selection: $date, in: Date()..., displayedComponents: .date) .datePickerStyle(.graphical) .labelsHidden() .tint(Color.appPurple) .padding(.horizontal) .padding(.bottom, -10) .fixedSize(horizontal: false, vertical: true) // 新增这一行
方法2:设置最小高度
如果需要更灵活的布局控制,给DatePicker设置一个合适的最小高度,既能避免内容被挤压,又能阻止高度跳动:
DatePicker("", selection: $date, in: Date()..., displayedComponents: .date) .datePickerStyle(.graphical) .labelsHidden() .tint(Color.appPurple) .padding(.horizontal) .padding(.bottom, -10) .frame(minHeight: 300) // 数值可根据实际显示效果调整
补充说明
Graphical样式的DatePicker首次交互时,内部可能会重新加载月份数据或调整组件布局,导致系统重新计算高度。上面两种方法都是通过固定或限制高度来规避这个问题。如果不介意滚动体验,也可以把整个Bottom Sheet的内容包裹进ScrollView,让滚动来容纳高度变化,但体验不如前两种方法直接。
内容的提问来源于stack exchange,提问作者Vadim F.
相关产品推荐
相关产品推荐

