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
相关产品推荐
相关产品推荐

