Слайдер SwiftUI, как изменить вторую переменную

#swift #swiftui #slider

#swift #swiftui #слайдер

Вопрос:

На данный момент мой слайдер изменяет только мою переменную kms, но я также хотел бы, чтобы он увеличивал или уменьшал переменную цены на процентную переменную для каждого шага слайдера. Есть ли простой способ реализовать это? Спасибо.

 import SwiftUI

struct SliderStruct: View {
   
   @State var kms: Double = 100_000
   var kms2: Double = 100_000
   
   var price: Double = 5_000
   var percentage: Double = 0.05
   
   var body: some View {
       VStack{
           
           //increase price by percentage as kms decrease, decrease price by percentage as kms increase
           //price *= percentage, price /= percentage

           Text("$(self.price, specifier: "%.0f")")
           
           Text("(self.kms, specifier: "%.0f") Kms")
           Slider(value: $kms, in: kms2 - kms2...kms2   kms2, step: 20_000)
       }
   }
}
 

Ответ №1:

Вопрос здесь в том, как получить два значения из одного слайдера.

К сожалению, слайдер предоставляет только одно значение, поскольку имеется только один дескриптор:

Слайдер с одним дескриптором

Таким образом, мы не можем получить из нее два значения мгновенно. Вместо этого мы можем получить это одно значение и преобразовать его в наши два значения, используя некоторые формулы.

Для километров — формула довольно проста, она просто умножает значение ползунка на некоторый коэффициент.

Что касается цены — формула немного сложнее, так как нам нужно рассчитать проценты.

Итак, вот окончательный код с вычислениями. Пожалуйста, проверьте комментарии, которые я туда добавляю, чтобы лучше понять решение.

 struct SliderStruct: View {

    /// This state stores slider value that is in the range from 0 to 10
    @State var sliderValue: Double = 5

    // Constants
    let kmsStep: Double = 20_000
    let pricePercentesStep: Double = 0.05

    // Computed properties

    /// Calculating kms by simply multiplying the slider value
    var kms: Double { sliderValue * kmsStep }

    /// Calculating the price using percentage formula
    var price: Double {
        // You might need to adjust the formula here,
        // as it wasn't super clear to me from the question
        // But I guess regularly percentes work like this
        5_000 * (
            1   pricePercentesStep * (sliderValue - 5)
        )
    }

    var body: some View {
        VStack{
            Text("$(self.price, specifier: "%.0f")")

            Text("(self.kms, specifier: "%.0f") Kms")
            Slider(value: $sliderValue, in: 0 ... 10, step: 1)
        }
    }
}
 

И вот что мы имеем в результате. Пожалуйста, измените формулу вычисления процента, если я не правильно понял из вашего описания.

Результат вычислений, полученный из значения ползунка SwiftUI

Комментарии:

1. Большое вам спасибо. Мой вопрос был не таким ясным, как следовало бы, но ваш ответ был очень информативным. Я немного изменил формулу, чтобы цена снижалась по мере увеличения kms и наоборот.

2. @decibeljames вы бы согласились пометить ответ как принятый, если тогда это сработает для вас?

Ответ №2:

Это была интересная проблема, которую я никогда раньше не пробовал, поэтому я предпринял быструю попытку ее решения (вроде как заставил ее работать!), Но работал с ограничениями исходного вопроса. Хотя, некоторая информация все еще была довольно расплывчатой.

 class DistanceObject: ObservableObject {
    @Published var kms: Double = 100_000
    var kms2: Double = 100_000
    var price: Double = 5_000
    var pricePlaceHolder: Double = 5_000
    var percentage: Double = 0.05
    private var oldValue: Double = 100_000 // set to initial kms
    func getPrice() -> Double {
        if kms.truncatingRemainder(dividingBy: 20000) == 0.0 {
            if kms != oldValue {
                if kms < oldValue {
                    price = price   (pricePlaceHolder * percentage)
                } else if kms > oldValue {
                    price = price - (pricePlaceHolder * percentage)
                }
                oldValue = kms
            }
        }
        return price
    }
    func setPrice(price: Double) {
        self.price = price
    }
}

struct ContentView: View {
    @ObservedObject var distance: DistanceObject = DistanceObject()
    var body: some View {
        let price_mod = Binding<Double>(
            get: { return distance.getPrice() },
            set: { distance.setPrice(price: $0) }
        )
        NavigationView {
            VStack {
                Text("$(price_mod.wrappedValue, specifier: "%.0f")")
                Text("(distance.kms, specifier: "%.0f") Kms")
                Slider(value: $distance.kms, in: distance.kms2 - distance.kms2...distance.kms2   distance.kms2, step: 20_000)
            }
        }
    }
}
 

Я решил использовать пользовательский подход привязки внутри contentView, и эта привязка выполняет вычисления в ObservableObject класс object . Это не лучшее решение, но этот и другой ответ должны помочь вам двигаться в правильном направлении.

Комментарии:

1. Спасибо за ваш вклад. Я реализовал здесь часть вашей логики, и теперь у меня есть результат, к которому я стремился.