当 SwiftUI Picker 选择更改 EnvironmentObject 时,有没有办法调用函数? [英] Is there a way to call a function when a SwiftUI Picker selection changes an EnvironmentObject?

查看:22
本文介绍了当 SwiftUI Picker 选择更改 EnvironmentObject 时,有没有办法调用函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个正在使用的 SwiftUI 表单,它更新 EnvironmentObject 的值.当 Picker 的值发生变化时,我需要调用一个函数,但我发现的每一种方式要么非常混乱,要么会导致其他问题.我正在寻找的是 Slider 工作的类似方式,但似乎没有.没有任何解决方案的基本代码在这里:

I have a SwiftUI Form I'm working with, which updates values of an EnvironmentObject. I need to call a function when the value of a Picker changes, but every way I've found is either really messy, or causes other problems. What I'm looking for is a similar way in which the Slider works, but there doesn't seem to be one. Basic code without any solution is here:

class ValueHolder : ObservableObject {

@Published var sliderValue : Float = 0.5
static let segmentedControlValues : [String] = ["one", "two", "three", "four", "five"]
@Published var segmentedControlValue : Int = 3

}
struct ContentView: View {

    @EnvironmentObject var valueHolder : ValueHolder

    func sliderFunction() {
        print(self.valueHolder.sliderValue)
    }
    func segmentedControlFunction() {
        print(ValueHolder.segmentedControlValues[self.valueHolder.segmentedControlValue])
    }

    var body: some View {
        Form {
            Text("\(self.valueHolder.sliderValue)")
            Slider(value: self.$valueHolder.sliderValue, onEditingChanged: {_ in self.sliderFunction()
            })
            Text("\(ValueHolder.segmentedControlValues[self.valueHolder.segmentedControlValue])")
            Picker("", selection: self.$valueHolder.segmentedControlValue) {
                ForEach(0..<ValueHolder.segmentedControlValues.count) {
                    Text("\(ValueHolder.segmentedControlValues[$0])")
                }
            }.pickerStyle(SegmentedPickerStyle())
        }
    }
}

在此处查看此类似(但不同)的问题后:有没有办法在 SwiftUI Picker 选择更改时调用函数? 我尝试使用 onReceive() 如下,但它也会在 Slider 值更改时调用,导致不良行为.

After reviewing this similar (but different) question here: Is there a way to call a function when a SwiftUI Picker selection changes? I have tried using onReceive() as below, but it is also called when the Slider value changes, resulting in unwanted behavior.

.onReceive([self.valueHolder].publisher.first(), perform: {_ in
                self.segmentedControlFunction()
            })

我尝试更改 onReceive 的参数以仅通过该值对其进行过滤.传递的值是正确的,但在滑块移动时仍会调用 segmentedControlFunction,而不仅仅是在选择器更改时.

I have tried changing the parameter for onReceive to filter it by only that value. The value passed is correct, but the segmentedControlFunction still gets called when the slider moves, not just when the picker changes.

.onReceive([self.valueHolder.segmentedControlValue].publisher.first(), perform: {_ in
                self.segmentedControlFunction()
            })

如何以与sliderFunction类似的方式调用segmentedControlFunction?

How can I get the segmentedControlFunction to be called in a similar way to the sliderFunction?

推荐答案

有更简单的方法,看起来更适合我.

There is much simpler approach, which looks more appropriate for me.

通用架构如下

Picker("Label", selection: Binding(    // proxy binding
    get: { self.viewModel.value },     // get value from storage
    set: {
            self.viewModel.value = $0  // set value to storage

            self.anySideEffectFunction() // didSet function
    }) {
       // picker content
    }

这篇关于当 SwiftUI Picker 选择更改 EnvironmentObject 时,有没有办法调用函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆