SwiftUI 中 DatePicker 的两个 ClosedRanges

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

日期收盘区间示例:

var dateClosedRange: ClosedRange<Date> {
    let today = Calendar.current.date(byAdding: .minute, value: -1, to: Date())!
    let seven = Calendar.current.date(byAdding: .day, value: 7, to: Date())!
    return today...seven
}

时间封闭区间示例:

var timeClosedRange: ClosedRange<Date> {
    let min = Calendar.current.date(bySetting: .hour, value: 8, of: Date())!
    let max = Calendar.current.date(bySetting: .hour, value: 20, of: Date())!
    return min...max
}

应用范围示例:

DatePicker(selection: $scheduledStart, in: timeClosedRange) {
    Text("Start Date")
}

如果我输入

dateClosedRange
,那么我可以选择指定天内的日期,但时间可以是 24 小时之间的任何时间。

如果我输入

timeClosedRange
,那么我可以按照上午 8 点至晚上 8 点之间选择时间,但我只能选择当前日期,而不能选择其他日期。

有什么方法可以将两个范围放入一个 DatePicker 中吗?

ios swift datepicker swiftui
2个回答
0
投票

您可以使用

DateComponents
实例来实现这一点:

let dateAndTimeRange: ClosedRange<Date> = {
  let calendar = Calendar.current
  let startComponents = DateComponents(
                          year: 2020,
                          month: 1,
                          day: 1,
                          hour: 00,
                          minute: 00,
                          second: 00
  )
  let endComponents = DateComponents(
                        year: 2020,
                        month: 12,
                        day: 31,
                        hour: 23,
                        minute: 59,
                        second: 59
  )
  return calendar.date(from:startComponents)!
    ...
    calendar.date(from:endComponents)!
}()

0
投票

您可以使用

DatePicker
HStack
组合两个
.labelsHidden()
,以创建与单个
DatePicker
完全相同的 UI。最后,您可以从两个日期中选择日期组件并创建单个日期输出。我希望这有助于解决您的疑问。

我的代码的输出:

import SwiftUI

struct ContentView: View {
    
    @State private var selectedDate = Date()
    @State private var selectedTime = Date()
    
    var body: some View {
        
        VStack(spacing: 150) {
            
            Text("Two Dates Pickers combined")
        
            HStack {
                DatePicker(selection: $selectedDate, in: dateClosedRange, displayedComponents: .date)  {
                    Text("Start Date")
                }
                
                DatePicker("Select Time", selection: $selectedTime, in: timeClosedRange, displayedComponents: .hourAndMinute)
                    .labelsHidden()
            }
        }
    }
    
    var dateClosedRange: ClosedRange<Date> {
        let today = Calendar.current.date(byAdding: .minute, value: -1, to: Date())!
        let sevenDaysLater = Calendar.current.date(byAdding: .day, value: 7, to: Date())!
        return today...sevenDaysLater
    }
    
    var timeClosedRange: ClosedRange<Date> {
        let minTime = Calendar.current.date(bySettingHour: 8, minute: 0, second: 0, of: Date())!
        let maxTime = Calendar.current.date(bySettingHour: 20, minute: 0, second: 0, of: Date())!
        return minTime...maxTime
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

代码的 UI 输出是:

struct ContentView: View {
    @State private var scheduledStart = Date()

    var body: some View {
        VStack(spacing: 150) {
            
            Text("Single DatePicker")

            DatePicker(selection: $scheduledStart, in: dateClosedRange) {
                Text("Start Date")
            }
        }
    }
    
    var dateClosedRange: ClosedRange<Date> {
        let today = Calendar.current.date(byAdding: .minute, value: -1, to: Date())!
        let seven = Calendar.current.date(byAdding: .day, value: 7, to: Date())!
        return today...seven
    }

    var timeClosedRange: ClosedRange<Date> {
        let min = Calendar.current.date(bySetting: .hour, value: 8, of: Date())!
        let max = Calendar.current.date(bySetting: .hour, value: 20, of: Date())!
        return min...max
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.