web-dev-qa-db-ja.com

Swiftuiを使用したDatePickerの価値変更を検出する方法は?

Swiftuiを使用している間のDatePickerの価値の変更をどのように検出しますか? Textとスライダを更新するには、DatePickerホイールが移動したときはいつでもメソッドを呼び出す必要があります。

私は価値の変化を識別するための具体的な方法を検討しました(アクションをイベントに関連付けることが可能であったUIKitを使用して)、明らかに私はドキュメントで役に立つものを見つけていません(私はontApgessureメソッドを試しましたが、そうではありません)私が欲しいのは、ユーザーがPicterをタップして他のビューを更新することを強制しますが、ユーザーがホイールを移動するたびに自動アップデートをしたいのですが。

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
    }
}
 _

私はこれが組み合わせ(ObservableObject、出版された、シンクなど)を使って解決できると思いますが、私はまだコンバインでは経験していません、したがって私はいくつかの助けを求めたいです...任意のアイデア? :)

どうもありがとう!

6
Thorh73

別のアプローチは、ViewModelのオブザーバが日付が変更されたときに呼ばれる場合

class TestPikerModel: ObservableObject {
    @Published var expireDate: Date = Date()

init() {
       setupObserver()
    }
    
private func setupObserver() {
        $expireDate
            .sink { date in
                // do some networking call
            }
            .store(in: &cancellables)
    }
}

struct TestPikerView: View {

    @ObservedObject var testPikerModel = TestPikerModel()
    @State private var weekOfYear = Double(Calendar.current.component(.weekOfYear, from: Date()) )

    var body: some View {
    
        VStack {
            Text("\(Int(weekOfYear))")
            DatePicker("", selection: $testPikerModel.expireDate, displayedComponents: .date)
            .datePickerStyle(CompactDatePickerStyle())
            .clipped()
            .labelsHidden()
        }

    }

}
 _
0
Wasim

ObservableObjectを使用した可能なアプローチ

class TestPikerModel: ObservableObject {
    @Published var expireDate: Date = Date()
}

struct TestPikerView: View {

    @ObservedObject var testPikerModel = TestPikerModel()
    @State private var weekOfYear = Double(Calendar.current.component(.weekOfYear, from: Date()) )

    var body: some View {
    
        VStack {
            Text("\(Int(weekOfYear))")
            DatePicker("", selection: $testPikerModel.expireDate, displayedComponents: .date)
            .datePickerStyle(CompactDatePickerStyle())
            .clipped()
            .labelsHidden()
        }
        .onReceive(testPikerModel.$expireDate) { date in
            weekOfYear = Double(Calendar.current.component(.weekOfYear, from: date))
            updateWeekAndDayFromDate()
        }
    }

    func updateWeekAndDayFromDate() {
        print("updateWeekAndDayFromDate performed")
    }
}

struct TestPikerView_Previews: PreviewProvider {
    static var previews: some View {
        TestPikerView()
    }
}
 _
0