[SwiftUI 100天] BetterRest · part2

642 阅读2分钟
译自 Selecting dates and times with DatePicker
更多内容欢迎关注公众号 「Swift花园」

用 DatePicker 选取日期和时间

SwiftUI 提供给我们一个专用的 picker 类型,叫做 DatePicker ,它可以绑定到 date 属性。是的,Swift 对于日期处理有专门的类型,它叫Date

首先,用 @State 标记属性:

@State private var wakeUp = Date()

然后绑定到 DatePicker :

var body: some View {
    DatePicker("Please enter a date", selection: $wakeUp)
}

运行代码,在模拟器看效果,你会看到一个日期和时间的滚轮,左边是 “Please enter a date” 标签。

                                    


你可能觉得标签很丑,于是尝试把它替换成:

DatePicker("", selection: $wakeUp)

但在你这么做之后,会有两个问题:其一,尽管标签是空的,date picker 还是给它留出了空间;其二,如果用户是通过屏幕阅读来使用,date picker 的用途就无从得知。

有两个备选方案,两种都可以解决上面的问题。

第一种,我们把DatePicker 包装到 Form里:

var body: some View {
    Form {
        DatePicker("Please enter a date", selection: $wakeUp)
    }
}

就像常规的 Picker 一样,这会改变 SwiftUI 渲染视图的方式。我们会得到一个折叠了数据的列表单行,点击时展开。

                                    


                                    


这种外观看起来就舒服多了,它结合了表单的简洁以及 date picker 熟悉的基于滚轮的交互。不过,遗憾的是,这种方式有一些小缺陷,我们之后会说到。

相对表单,另一种选择是用 labelsHidden() modifier ,像下面这样:

var body: some View {
    DatePicker("Please enter a date", selection: $wakeUp)
        .labelsHidden()
}
                                 


虽然不展示,但是 VoiceOver 还是可以读取,而 date picker 已经可以充分占据屏幕的水平空间。

Date picker 提供了一组配置 configuration 选项,用于控制它的工作方式。首先,我们可以用 displayedComponents 来决定用户会看到哪些选项:

  • 如果你不提供这个参数,用户会看到天,小时和分钟。
  • 如果你用.date ,用户会看到月、天和年。
  • 如果你用 .hourAndMinute,用户会看到小时和分钟组件。

因此,我们这样配置时间精度:

DatePicker("Please enter a time", selection: $wakeUp, displayedComponents: .hourAndMinute)

最后,还有一个 in 参数,工作方式跟 Stepper 的参数一样:我们可以给它一个日期范围,date picker 会确保用户无法选择超出这个范围的时间。

目前,我们已经用了很多范围,你应该已经习惯看到 1 ... 5 或者 0 ..< 10这样的东西。其实我们也可以对 Swift 的 dates 应用范围。举个例子:

// when you create a new Date instance it will be set to the current date and time
let now = Date()

// create a second Date instance set to one day in seconds from now
let tomorrow = Date().addingTimeInterval(86400) 

// create a range from those two
let range = now ... tomorrow

这对 DatePicker非常偶用,不过还有更好用的:Swift 允许我们使用单边范围 —— 这是一种只需要指定起点或者终点的范围,Swift 会推断另一边。

举个例子,我们可以像下面这样创建一个 date picker:

DatePicker("Please enter a date", selection: $wakeUp, in: Date()...)

这将允许未来的所有 date,而过去的 date 则都不行。


相关文章

[SwiftUI 100 天] BetterRest - part1

[SwiftUI 100 天] BetterRest - part3


我的公众号 这里有Swift及计算机编程的相关文章,以及优秀国外文章翻译,欢迎关注~