Mac 上的 DatePicker 不保存日期,直到按下返回键

fph*_*elp 11 macos datepicker swift mac-catalyst

我正在使用 Mac Catalyst 将我的 iPad 应用程序调整到 Mac,并且在使用 datePicker 时遇到了问题(它有一段datePickerMode时间)。在 iPad 上 datePicker 是一个轮子,每当用户在日期选择器上滚动时,就会触发 dateChanged 操作。但在 Mac 上,日期选择器不是滚动条,而是一种文本输入。我可以在 Mac 上键入和更改所有时间值,但在按下返回键之前不会触发 dateChanged 操作。

我想在用户进入某个时间时触发 dateChange 操作。我怎样才能做到这一点?我尝试向 datePicker 添加不同的目标,但没有任何效果。

我实际上更喜欢在 Mac 上使用日期滚动条,所以如果有人知道如何做到这一点,我将不胜感激(我在互联网上四处寻找,但一无所获)!

这是我的代码:

class DateVC: UIViewController {
     @IBOutlet weak var datePicker: UIDatePicker!

     override func viewDidLoad() {
          super.viewDidLoad()

          //Just show the time
          datePicker.datePickerMode = .time
    }

     //Action connected to datePicker. This is not called until I press enter on Mac
     @IBAction func datePickerChanged(_ sender: Any) {
        //do actions
     }

}
Run Code Online (Sandbox Code Playgroud)

wor*_*dog 0

这是一个 SwiftUI 解决方案,可在 iPad、iPhone 和 Mac Catalyst 上显示日期和时间滚动选择器。无需按回车键即可工作。如果需要,您可以轻松地仅显示 HoursMinutesPicker。

import SwiftUI

struct ContentView: View {
@State var date = Date()
var body: some View {
    NavigationView {
        NavigationLink(destination: DateHMPicker(date: self.$date)) {
            VStack {
                Text("Show time")
                Text("\(self.date)")
            }
        }
    }.navigationViewStyle(StackNavigationViewStyle())
}
}

struct DateHMPicker: View {
var titleKey: LocalizedStringKey = ""
@Binding var date: Date

var body: some View {
    HStack {
        Spacer()
        DatePicker(titleKey, selection: self.$date, displayedComponents: .date).datePickerStyle(WheelDatePickerStyle())
        HoursMinutesPicker(date: self.$date)
        Spacer()
    }
}
}

struct HoursMinutesPicker: View {
@Binding var date: Date
@State var hours: Int = 0
@State var minutes: Int = 0

var body: some View {
    HStack {
        Spacer()
        Picker("", selection: Binding<Int>(
            get: { self.hours},
            set : {
                self.hours = $0
                self.update()
        })) {
            ForEach(0..<24, id: \.self) { i in
                Text("\(i) hours").tag(i)
            }
        }.pickerStyle(WheelPickerStyle()).frame(width: 90).clipped()
        Picker("", selection: Binding<Int>(
            get: { self.minutes},
            set : {
                self.minutes = $0
                self.update()
        })) {
            ForEach(0..<60, id: \.self) { i in
                Text("\(i) min").tag(i)
            }
        }.pickerStyle(WheelPickerStyle()).frame(width: 90).clipped()
        Spacer()
    }.onAppear(perform: loadData)
}

func loadData() {
    self.hours = Calendar.current.component(.hour, from: date)
    self.minutes = Calendar.current.component(.minute, from: date)
}

func update() {
    if let newDate = Calendar.current.date(bySettingHour: self.hours, minute: self.minutes, second: 0, of: date) {
        date = newDate
    }
}
}
Run Code Online (Sandbox Code Playgroud)