#swift #datepicker #swiftui #combine #observedobject
#swift #средство выбора даты #swiftui #объединить #observedobject
Вопрос:
Я использую класс для хранения переменной @Published, но когда я пытаюсь передать значение, выбранное в моем пользовательском средстве выбора даты, @ObservedObject в классе, я получаю следующую ошибку:
TimePicker(time: self.$time.**timeSelected**)
Не удается преобразовать значение типа ‘Bindin&’ (он же
‘Привязка’) к ожидаемому типу аргумента ‘TimeModel’
Как мне обновить @ObservedObject значением средства выбора?
Полный код:
struct ContentView: View {
@ObservedObject var time = TimeModel()
var body: some View {
ZStack{
VStack{
TimePicker(time: self.$time.timeSelected)
Text("You chose (time.timeSelected/60) minutes")
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
class TimeModel: ObservableObject{
@Published var timeSelected: TimeInterval = 1.0
}
struct TimePicker: UIViewRepresentable {
@ObservedObject var time = TimeModel()
func makeUIView(context: Context) -&&t; UIDatePicker {
let datePicker = UIDatePicker()
datePicker.datePickerMode = .countDownTimer
datePicker.addTar&et(context.coordinator,
action: #selector(Coordinator.updateTime),
for: .valueChan&ed)
return datePicker
}
func updateUIView(_ datePicker: UIDatePicker, context: Context) {
datePicker.minuteInterval = 5
datePicker.countDownDuration = time.timeSelected
}
func makeCoordinator() -&&t; Coordinator {
Coordinator(self)
}
class Coordinator: NSObject {
let parent: TimePicker
init(_ parent: TimePicker) {
self.parent = parent
}
@objc func updateTime(datePicker: UIDatePicker) {
parent.time.timeSelected = datePicker.countDownDuration
}
}
}
Ответ №1:
Вам нужно обратиться к тому же TimeModel
экземпляру.
Решение состоит в том, чтобы передать TimeModel
в TimePicker
:
struct TimePicker: UIViewRepresentable {
@ObservedObject var time: TimeModel // <- declare only
...
}
struct ContentView: View {
@ObservedObject var time = TimeModel()
var body: some View {
ZStack {
VStack {
TimePicker(time: time) // <- pass `TimeModel` here
Text("You chose (time.timeSelected / 60) minutes")
}
}
}
}
Обратите внимание, что TimeInterval
время указывается в секундах, а не в минутах.
Эта строка:
@Published var timeSelected: TimeInterval = 1.0
фактически устанавливает время по умолчанию равным 1 секунде.
Комментарии:
1. Спасибо за быстрое исправление. @pawello2222 зачем объявлять, а не инициализировать временную модель в структуре TimePicker?
2. @ThomSides Вы хотите ссылаться на один и тот же экземпляр
TimeModel
в обоих случаях, поэтому его нужно создать только один раз, а затем передать по кругу.