如何使用SwiftUI和Combine检测Datepicker的值变化? [英] How to detect a value change of a Datepicker using SwiftUI and Combine?
问题描述
在使用SwiftUI和Combine时如何检测Datepicker的值变化?
每当日期选择轮移动时,我都需要调用一个方法,以更新文本和滑块。
How would you detect a change of value of a Datepicker while using SwiftUI and Combine? I need to invoke a method whenever the datepicker wheel is moved, to update a Text and a Slider.
我一直在寻找可以识别值的特定方法更改(使用UIKit可以将动作与事件相关联),但是显然我在文档中没有找到任何有用的东西(我已经尝试过onTapGesture方法,但这不是我想要的,因为它迫使用户点击选择器以更新其他视图,而我希望每当用户移动方向盘时都进行自动更新。)
I have looked for specific methods to identify the value change (using UIKit it was possible to associate an action to an event), but apparently I haven't found anything useful in the documentation (I've tried the onTapGesture methods, but that's not what I want, since it forces the user to tap the picker to update the other views, whereas I would like to have an automatic update whenever the user moves the wheel).
import SwiftUI
struct ContentView: View {
private var calendar = Calendar.current
@State private var date = Date()
@State private var weekOfYear = Double(Calendar.current.component(.weekOfYear, from: Date()) )
@State private var lastWeekOfThisYear = 53.0
@State private var weekDay: String = { () -> String in
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "EEEE"
let weekDay = dateFormatter.string(from: Date())
return weekDay
}()
var body: some View {
VStack {
// Date Picker
DatePicker(selection: $date, displayedComponents: .date, label:{ Text("Please enter a date") }
)
.labelsHidden()
.datePickerStyle(WheelDatePickerStyle())
.onTapGesture {
self.updateWeekAndDayFromDate()
}
// Week number and day
Text("Week \(Int(weekOfYear.rounded()))")
Text("\(weekDay)")
// Slider
Slider(value: $weekOfYear, in: 1...lastWeekOfThisYear, onEditingChanged: { _ in
self.updateDateFromWeek()
})
}
}
func updateWeekAndDayFromDate() {
// To do
}
func updateDateFromWeek() {
// To do
}
func setToday() {
// To do
}
func getWeekDay(_ date: Date) -> String {
//To do
}
}
I猜想可以使用Combine(可以观察到的对象,已发布,接收器等)解决此问题,但是我尚不具备使用Combine的经验,因此我想寻求帮助...有什么想法吗? :)
I guess this could be solved using Combine (observableobject, published, sink, etc.), but I'm not experienced yet with Combine, therefore I'd like to ask for some help... any ideas? :)
非常感谢!
推荐答案
请在下面找到一个可能的方法(稍微修改一下代码)。这是使源状态透明以激活其中的依赖关系的想法。希望对您有所帮助。
Please find below one possible approach (with a bit modified your code). Here is an idea to have source state transparent to activate dependent within it. Hope it will be helpful somehow.
此处为演示
这里是代码
struct TestDatePicker: View {
private static func weekOfYear(for date: Date) -> Double {
Double(Calendar.current.component(.weekOfYear, from: date))
}
private static func weekDay(for date: Date) -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "EEEE"
let weekDay = dateFormatter.string(from: date)
return weekDay
}
@State private var date: Date
@State private var weekOfYear: Double
@State private var weekDay: String
@State private var lastWeekOfThisYear = 53.0
private var dateProxy:Binding<Date> {
Binding<Date>(get: {self.date }, set: {
self.date = $0
self.updateWeekAndDayFromDate()
})
}
init() {
let now = Date()
self._date = State<Date>(initialValue: now)
self._weekOfYear = State<Double>(initialValue: Self.weekOfYear(for: now))
self._weekDay = State<String>(initialValue: Self.weekDay(for: now))
}
var body: some View {
VStack {
// Date Picker
DatePicker(selection: dateProxy, displayedComponents: .date, label:{ Text("Please enter a date") }
)
.labelsHidden()
.datePickerStyle(WheelDatePickerStyle())
// Week number and day
Text("Week \(Int(weekOfYear.rounded()))")
Text("\(weekDay)")
// Slider
Slider(value: $weekOfYear, in: 1...lastWeekOfThisYear, onEditingChanged: { _ in
self.updateDateFromWeek()
})
}
}
func updateWeekAndDayFromDate() {
self.weekOfYear = Self.weekOfYear(for: self.date)
self.weekDay = Self.weekDay(for: self.date)
}
func updateDateFromWeek() {
// To do
}
func setToday() {
// To do
}
func getWeekDay(_ date: Date) -> String {
""
}
}
struct TestDatePicker_Previews: PreviewProvider {
static var previews: some View {
TestDatePicker()
}
}
这篇关于如何使用SwiftUI和Combine检测Datepicker的值变化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!