SwiftUI - 日期选择器仅显示年份

问题描述 投票:0回答:2

是否可以使用Apple自己的日期选择器并仅显示年份?

这是我当前的代码:

  DatePicker("", selection: $cameraViewModel.age, displayedComponents: .date)
        .datePickerStyle(CompactDatePickerStyle())

当然,

.displayedComponents
允许我更改 UI/元素,但是,仅一年就不需要了。

谢谢你。我搜索了 Stackoverflow,找到了一个线程,但 OP 从未跟进。

datepicker swiftui
2个回答
5
投票

我认为你不能用

DatePicker
来做到这一点 - 它是为了选择
Date
而一年只是一个简单的
Int

仅显示年份可以通过标准

Picker
实现(尽管外观可能有所不同):

struct ContentView: View {
    @State var selection = Date()
    var body: some View {
        Picker("", selection: $selection) {
            ForEach(2000...2020, id: \.self) {
                Text(String($0))
            }
        }
        .pickerStyle(InlinePickerStyle())
    }
}

0
投票

我创建了这个

YearPicker
SwiftUI 组件

代码观察:需要在Picker中为.tag创建年、月、日、时、分、秒、纳秒和时区,正确分配初始值给select。

任何优化帮助都值得赞赏。

年份选择器

import SwiftUI

struct YearPicker: View {
    
    @Binding var selectedDate: Date
    let yearRange: ClosedRange<Int>
    
    init(selection: Binding<Date>, yearRange: ClosedRange<Int> = 1900...2060) {
        self._selectedDate = selection
        self.yearRange = yearRange
        
        // Ajustar el año seleccionado dentro del rango
        let calendar = Calendar.current
        let year = calendar.component(.year, from: selection.wrappedValue)
        if !yearRange.contains(year) {
            var adjustedYear = year
            if year < yearRange.lowerBound {
                adjustedYear = yearRange.lowerBound
            } else if year > yearRange.upperBound {
                adjustedYear = yearRange.upperBound
            }
            let originalComponents = calendar.dateComponents([.month, .day, .hour, .minute, .second, .nanosecond, .timeZone], from: selection.wrappedValue)
            var components = DateComponents()
            components.year = adjustedYear
            components.month = originalComponents.month
            components.day = originalComponents.day
            components.hour = originalComponents.hour
            components.minute = originalComponents.minute
            components.second = originalComponents.second
            components.nanosecond = originalComponents.nanosecond
            components.timeZone = originalComponents.timeZone
            self._selectedDate = Binding.constant(calendar.date(from: components)!)
        }
    }
    
    var body: some View {
        VStack {
            Picker("Year", selection: $selectedDate) {
                ForEach(yearRange, id: \.self) { year in
                    Text(displayYear(year: year))
                        .tag(self.dateFromYear(year))
                }
            }
        }
    }
        
    private func displayYear(year: Int) -> String {
        let numberFormatter: NumberFormatter = {
            let nf = NumberFormatter()
            nf.usesGroupingSeparator = false
            return nf
        }()
        return numberFormatter.string(from: NSNumber(value: year)) ?? "\(year)"
    }
    
    private func dateFromYear(_ year: Int) -> Date {
        let calendar = Calendar.current
        let originalComponents = calendar.dateComponents([.month, .day, .hour, .minute, .second, .nanosecond, .timeZone], from: selectedDate)
        var components = DateComponents()
        components.year = year
        components.month = originalComponents.month
        components.day = originalComponents.day
        components.hour = originalComponents.hour
        components.minute = originalComponents.minute
        components.second = originalComponents.second
        components.nanosecond = originalComponents.nanosecond
        components.timeZone = originalComponents.timeZone
        return calendar.date(from: components)!
    }
}

预览

您可以指定范围值,默认

1900...2060

#Preview {
    struct PreviewWrapper: View {
        @State var value: Date = Date()
        
        var body: some View {
            VStack {
                YearPicker(selection: $value)
                    .onChange(of: value) { oldValue, newValue in
                        print("chanege:", value)
                    }
                Text(value.description)
            }
        }
    }
    return PreviewWrapper()
}

您可以在 YouTube 上看到实际操作 SwiftUI 中的 YearPicker

© www.soinside.com 2019 - 2024. All rights reserved.