【问题标题】:Selection in Picker (SegmentedPickerStyle) isn't working well - SwiftUI选择器(SegmentedPickerStyle)中的选择效果不佳 - SwiftUI
【发布时间】:2020-04-16 20:23:53
【问题描述】:

我有风格选择器SegmentedPickerStyle()。现在我正在根据选择器值进行一些计算,并且它正在工作。但不知何故,如果我点击它,我的选择器不会改变它的选择值。要更改选择值,我需要滑动这些值。
另一个问题是,如果我需要计算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)
    }
}

任何帮助将不胜感激!

【问题讨论】:

    标签: ios swiftui picker


    【解决方案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 计算属性,该属性将运行其闭包并将新值返回给视图。

    【讨论】:

    • 是的,你是对的,它现在正在工作。我是 swiftUI 的新手,所以对 Published、ObservableObject、ObservedObject 有点困惑。顺便说一句,谢谢你节省了我的时间!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多