Выбор в средстве выбора (SegmentedPickerStyle) работает плохо - SwiftUI - PullRequest
0 голосов
/ 16 апреля 2020

У меня есть Пикер стиля SegmentedPickerStyle(). Сейчас я делаю некоторые расчеты на основе значения выбора, и это работает. Но почему-то мой сборщик не меняет своего значения выбора, если я нажму на него. Для изменения значения выбора, мне нужно провести по значениям.
Другая проблема заключается в том, что если мне нужно вычислить TipAmount, то сначала мне нужно провести пальцем до значения выбора, а затем выбрать это значение. Я не знаю, почему это происходит !!

Вот мой код View,

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 Ответ

1 голос
/ 17 апреля 2020

У вас есть модификатор 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]

}

Поскольку у вас уже есть свойства billAmount и tipPercentage как @Published, которые вам не нужны беспокоиться об отправке сообщения объекту PassthroughSubject, чтобы сообщить представлению обновить при изменении вычисляемого свойства. Сообщение willChange будет отправлено при изменении суммы чаевых или общей суммы. Это заставит представление переопределить sh, что вызовет вычисляемое свойство tipAmount, которое запустит его закрытие и вернет новое значение в представление.

...