SwiftUI Picker onReceive () вызывается каждый раз при рендеринге тела - PullRequest
1 голос
/ 10 июля 2020

Я использую Picker, чтобы показать сегментированный элемент управления, и wi sh, чтобы узнать, когда изменяется значение средства выбора, чтобы я мог выполнить действие, не связанное с пользовательским интерфейсом. Использование предложенного модификатора onReceive() (как предлагается здесь ) не работает, так как он вызывается каждый раз при отрисовке тела.

Вот код, который у меня есть:

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")
            }
        }
    }
}

Блок onReceive() будет вызываться каждый раз при рендеринге тела, включая первый раз и каждый раз, когда нажимается кнопка (которая переключает отображение сообщения).

Любые идеи, почему это происходит и как я могу реагировать только на изменение значения средства выбора?

1 Ответ

1 голос
/ 10 июля 2020

Вот возможное решение вместо .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)
}
...