You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 22:10:44