选择器中的选择(SegmentedPickerStyle)无法正常工作-SwiftUI

时间:2020-04-16 20:23:53

标签: ios swiftui picker

我有样式SegmentedPickerStyle()的Picker。现在,我正在基于选择器值进行一些计算,并且它正在工作。但是,如果我点击它,我的选择器就不会改变其选择值。要更改选择值,我需要在这些值上滑动。
另一个问题是,如果我需要计算TipAmount,那么首先我需要滑动到选择器值,然后选择该值。我不知道为什么会这样!

这是我的查看代码,

struct ContentView: View {

    @ObservedObject var tipViewModel = TipViewModel()

    var body: some View {

        VStack {

            TextField("Enter bill amount", text: $tipViewModel.billAmount)
                .textFieldStyle(RoundedBorderTextFieldStyle())

            Picker(selection: $tipViewModel.tipPercentage, label: Text("Select tip %")) {
                ForEach(tipViewModel.tipChoices, id: \.self) { choice in
                    //Text("\(self.tipViewModel.tipChoices[choice])")
                    Text("\(choice)")
                }
            }.pickerStyle(SegmentedPickerStyle())
                .onTapGesture {
                    self.tipViewModel.calculateTip()
            }
            Text("Tip Percentage \(tipViewModel.tipPercentage)")
            Text(tipViewModel.tipAmount == nil ? "Tip Amount" : "\(tipViewModel.tipAmount!)")
        }.padding()
    }
}

这是TipViewModel文件

class TipViewModel: ObservableObject {

    @Published var billAmount: String = "" {
        didSet{
            calculateTip()
        }
    }
    @Published var tipPercentage: Int = 10
    @Published var tipAmount: Double = 0

    let tipChoices = [10, 15, 20]

    let didChange = PassthroughSubject<TipViewModel, Never>()

    func calculateTip() {

        guard let billAmount = Double(billAmount) else { return }
        self.tipAmount = billAmount * Double(tipPercentage) / 100
        self.didChange.send(self)
    }
}

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:1)

您有一个onTapGesture修饰符,它正在拾取选择器上的轻击手势并尝试计算提示。

 .onTapGesture {
                self.tipViewModel.calculateTip()
        }

您可以仅将tipAmount计算为计算属性:

struct ContentView: View {

    @ObservedObject var tipViewModel = TipViewModel()

    var body: some View {

        VStack {

            TextField("Enter bill amount", text: $tipViewModel.billAmount)
                .textFieldStyle(RoundedBorderTextFieldStyle())

            Picker(selection: $tipViewModel.tipPercentage, label: Text("Select tip %")) {
                ForEach(tipViewModel.tipChoices, id: \.self) { choice in
                    //Text("\(self.tipViewModel.tipChoices[choice])")
                    Text("\(choice)")
                }
            }.pickerStyle(SegmentedPickerStyle())

            Text("Tip Percentage \(tipViewModel.tipPercentage)")
            Text("\(tipViewModel.tipAmount)")
        }.padding()
    }
}

class TipViewModel: ObservableObject {

    @Published var billAmount: String = ""
    @Published var tipPercentage: Int = 10

    var tipAmount: Double {
        guard let billAmount = Double(billAmount) else { return 0 }
        let tipAmount = billAmount * Double(tipPercentage) / 100
        return tipAmount
    }

    let tipChoices = [10, 15, 20]

}

由于您已经拥有billAmounttipPercentage作为@Published属性,因此您不必担心将消息发送到PassthroughSubject来告诉视图在计算属性更改时进行更新。当小费金额或总金额更改时,将发送willChange消息。这将导致视图刷新,该视图将调用tipAmount计算的属性,该属性将运行其关闭并将新值返回给视图。