SwiftUI 選時間的歲月神偷 — DatePicker

SwiftUI 的 DatePicker 方便我們選擇時間,而且它還能設定顯示的時間格式跟可選擇的區間。接下來就讓我們好好認識它跟實驗它的相關功能。

綁定型別 Date 變數的 DatePicker

DatePicker 的 init 接受型別 Binding<Date> 的參數,所以我們必須傳入型別 Date 的變數讓它綁定。當使用者選擇某個時間時,DatePicker 綁定的資料會更新。

利用 DatePicker 選時間

利用 DatePicker 選擇工具人送宵夜的時間,從 state property snackTime 讀取和更新時間。當 Text 顯示 Date 型別的資料時,有兩種不同的寫法,以下我們分別介紹。

寫法 1: 使用 Text 顯示 Date 型別的資料時,搭配 iOS 15 的 formatted function 或 format 參數,將它變成特定時間格式的字串

  • 範例 1。
struct ContentView: View {
@State private var snackTime = Date()

var body: some View {
VStack {
DatePicker("工具人送宵夜的時間", selection: $snackTime)
Text(snackTime.formatted(.dateTime))
Text(snackTime, format: .dateTime)
}
}
}
  • 範例 2。
struct ContentView: View {
@State private var snackTime = Date()

var body: some View {
VStack {
DatePicker("工具人送宵夜的時間", selection: $snackTime)
Text(snackTime.formatted(.dateTime.year().month()))
}
}
}
  • 範例 3。
struct ContentView: View {
@State private var snackTime = Date()

var body: some View {
VStack {
DatePicker("工具人送宵夜的時間", selection: $snackTime)
Text(snackTime.formatted(date: .complete, time: .standard))
}
}
}

寫法 2: 從 Text 的參數 style 設定時間格式

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

var body: some View {
VStack {
DatePicker("工具人送宵夜的時間", selection: $snackTime)
Text(snackTime, style: .date)
Text(snackTime, style: .time)
}
}
}

設定 DatePicker 顯示的時間格式

產生 DatePicker 時,透過型別 DatePickerComponents 的參數 displayedComponents 可以設定顯示的時間格式,比方 .date 表示只顯示年月日。

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

var body: some View {
VStack {
DatePicker("記得在這天送我生日禮物", selection: $birthday, displayedComponents: .date)
Text(birthday.formatted(date: .long, time: .omitted))
}
}
}

傳入 .hourAndMinute 表示只顯示幾點幾分。

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

var body: some View {
VStack {
DatePicker("記得在這個時間送我生日禮物", selection: $birthday, displayedComponents: .hourAndMinute)
Text(birthday.formatted(date: .omitted, time: .shortened))
}
}
}

設定可選擇的時間區間

產生 DatePicker 時,透過參數 in 可以設定可選擇的時間區間,因此傳入 Date()...Date()...Date.distantFuture 表示我們將從今天之後的某一天開始認真寫 App。

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

var body: some View {
VStack {
DatePicker("我要在這一天開始認真寫 App", selection: $studyTime, in: Date()..., displayedComponents: .date)
Text(studyTime.formatted(date: .long, time: .omitted))
}
}
}

如下圖所示,由於今天是 10/14,因此 10/14 之前的日期無法點選。

我們也可以指定某某日期,比方以下例子表示我們將在今天之後, 2023/10/17 之前告白。

struct ContentView: View {
@State private var loveTime = Date()
let dateRange: ClosedRange<Date> = {
let calendar = Calendar.current
let endComponents = DateComponents(year: 3000, month: 12, day: 31)
return Date.now
...
calendar.date(from:endComponents)!
}()

var body: some View {
VStack {
DatePicker("我要在這一天告白", selection: $loveTime, in: dateRange, displayedComponents: .date)
Text(loveTime.formatted(date: .long, time: .omitted))
}
}
}

我們也可以只限制時間的上限,比方參數 in 傳入...Date()Date.distantPast...Date.now,選擇我們初吻的時間,因為它發生在過去。

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

var body: some View {
VStack {
DatePicker("我的初吻發生在", selection: $firstKissDay, in: ...Date(), displayedComponents: .date)
Text(firstKissDay.formatted(date: .long, time: .omitted))
}
}
}

利用 labelsHidden 隱藏 DatePicker 左邊的文字

設定 date picker 的樣式

參考以下連結的說明。

--

--

彼得潘的 iOS App Neverland
彼得潘的 Swift iOS App 開發問題解答集

彼得潘的iOS App程式設計入門,文組生的iOS App程式設計入門講師,彼得潘的 Swift 程式設計入門,App程式設計入門作者,http://apppeterpan.strikingly.com