Saya menggunakan Picker untuk menunjukkan kontrol tersegmentasi dan ingin tahu kapan nilai pemilih berubah sehingga saya dapat melakukan tindakan non-UI. Menggunakan pengubah onReceive() yang diusulkan (seperti yang disarankan di sini) tidak berfungsi seperti yang dipanggil setiap kali tubuh dirender.

Berikut kode yang saya miliki:

struct PickerView: View {

    @State private var weather = 0
    @State private var showMessage = false

    var body: some View {

        VStack(spacing: 24) {
            Picker(selection: $weather, label: Text("Weather")) {
                Image(systemName: "sun.max.fill").tag(0)
                Image(systemName: "cloud.sun.rain.fill").tag(1)
            }
            .pickerStyle(SegmentedPickerStyle())
            .frame(width: 120, height: 48)
            .onReceive([weather].publisher.first()) { connectionType in
                print("connection type is: \(connectionType)")
            }

            Button(action: { self.showMessage.toggle() }) {
                Text("Press Me")
            }

            if showMessage {
                Text("Hello World")
            }
        }
    }
}

Blok onReceive() akan dipanggil setiap kali tubuh dirender, termasuk pertama kali dan setiap kali tombol (yang matikan menampilkan pesan) ditekan.

Adakah ide mengapa ini terjadi dan bagaimana saya hanya bisa bereaksi ketika nilai pemilih diubah?

3
number4 10 Juli 2020, 21:02

1 menjawab

Jawaban Terbaik

Berikut adalah solusi yang mungkin alih-alih .onReceive

Picker(selection: Binding(           // << proxy binding
                get: { self.weather },
                set: { self.weather = $0
                    print("connection type is: \($0)")  // side-effect
                })
    , label: Text("Weather")) {
    Image(systemName: "sun.max.fill").tag(0)
    Image(systemName: "cloud.sun.rain.fill").tag(1)
}
3
Asperi 10 Juli 2020, 18:16