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

SwiftUI中如何让DatePicker仅显示月份和年份?

SwiftUI实现仅显示年月的DatePicker

SwiftUI原生DatePicker的displayedComponents确实没有直接的「仅年月」选项,下面提供两种可行的实现方案:

方案1:包装UIKit的UIDatePicker(推荐)

UIKit的UIDatePicker原生支持仅选择年月的模式,通过UIViewRepresentable将其包装为SwiftUI组件,能获得原生的交互体验和样式:

struct MonthYearPicker: UIViewRepresentable {
    @Binding var selectedDate: Date
    
    func makeUIView(context: Context) -> UIDatePicker {
        let picker = UIDatePicker()
        picker.datePickerMode = .monthAndYear
        picker.preferredDatePickerStyle = .wheels
        picker.addTarget(context.coordinator, action: #selector(Coordinator.dateChanged(_:)), for: .valueChanged)
        picker.date = selectedDate
        return picker
    }
    
    func updateUIView(_ uiView: UIDatePicker, context: Context) {
        uiView.date = selectedDate
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    
    class Coordinator: NSObject {
        let parent: MonthYearPicker
        
        init(_ parent: MonthYearPicker) {
            self.parent = parent
        }
        
        @objc func dateChanged(_ picker: UIDatePicker) {
            parent.selectedDate = picker.date
        }
    }
}

修改你的DatePickerSheet,替换原有的DatePicker:

struct DatePickerSheet: View {
    @Binding var selectedDate: Date
    @Environment(\.dismiss) var dismiss
    
    var body: some View {
        NavigationStack {
            MonthYearPicker(selectedDate: $selectedDate)
                .padding()
                .navigationTitle("选择年月")
                .toolbar {
                    ToolbarItem(placement: .navigationBarTrailing) {
                        Button("完成") {
                            dismiss()
                        }
                    }
                }
        }
    }
}

方案2:纯SwiftUI自定义年月选择器

如果不想依赖UIKit,可以用两个Picker分别实现年份和月份选择,手动处理日期更新逻辑:

struct DatePickerSheet: View {
    @Binding var selectedDate: Date
    @Environment(\.dismiss) var dismiss
    
    private let years = Array(Calendar.current.component(.year, from: Date())-10 ... Calendar.current.component(.year, from: Date())+10)
    private let months = ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"]
    
    @State private var selectedYear: Int
    @State private var selectedMonth: Int
    
    init(selectedDate: Binding<Date>) {
        self._selectedDate = selectedDate
        let calendar = Calendar.current
        self._selectedYear = State(initialValue: calendar.component(.year, from: selectedDate.wrappedValue))
        self._selectedMonth = State(initialValue: calendar.component(.month, from: selectedDate.wrappedValue))
    }
    
    var body: some View {
        NavigationStack {
            HStack {
                Picker("年份", selection: $selectedYear) {
                    ForEach(years, id: \.self) { year in
                        Text("\(year)年")
                    }
                }
                .pickerStyle(.wheel)
                
                Picker("月份", selection: $selectedMonth) {
                    ForEach(1...12, id: \.self) { month in
                        Text(months[month-1])
                    }
                }
                .pickerStyle(.wheel)
            }
            .padding()
            .navigationTitle("选择年月")
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button("完成") {
                        var components = Calendar.current.dateComponents([.year, .month, .day], from: selectedDate)
                        components.year = selectedYear
                        components.month = selectedMonth
                        // 若需强制设置为当月第一天,可替换上面的day为:components.day = 1
                        if let newDate = Calendar.current.date(from: components) {
                            selectedDate = newDate
                        }
                        dismiss()
                    }
                }
            }
        }
    }
}

内容的提问来源于stack exchange,提问作者nkemjikaobi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 17:55:54