SwiftUI DatePicker、選択釦押されるまではBind元を反映させない

2021年8月19日

コード

DatePickerのselectionに「@Binding var day: Date」指定した場合、コール元が即座に反映されてしまう。
画面外タップでsheetをクローズ、またはキャンセル釦を追加してクローズした時に、選択が反映されてしまう。
一度選択用に「@State var selecting: Date = Date()」を用意して対応。

import SwiftUI

struct SelectDayView: View {
    @Environment(\.presentationMode) var presentationMode
    @Binding var day: Date
    @State var selecting: Date = Date()
    
    var body: some View {
        VStack {
            Text("Select Day")
                    .font(.largeTitle)
            DatePicker("", selection: self.$selecting, displayedComponents: [.date])
                .datePickerStyle(GraphicalDatePickerStyle())
                .labelsHidden()
            Button(action: {
                self.day = self.selecting
                self.presentationMode.wrappedValue.dismiss()
            }, label: {
                Text("Select")
                    .font(.largeTitle)
            })
        }
    }
}

コール元コードExample

:
:
.sheet(isPresented: self.$onDatePicker, onDismiss: {}, content: {
    SelectDayView(day: self.$day)
})
:
: