Search code examples
swiftfunctiontextviewsliderswiftui

SwiftUI - How to update a value through a function (with a slider)?


I am new to programming and SwiftUI and I am trying to get my head around this problem:

I have created a simple slider:

Slider(value: $sliderValue, in: 0...100, step: 1)
            .padding(8)
            .overlay(
                Capsule()
                    .stroke(Color.purple, style: StrokeStyle(lineWidth: 5))
        )

I can display the value in a TextView:

Text("\(sliderValue)")

Now what I want to do is create another TextView, which displays the Slider Value with a simple calculation. I can of course just multiplay the sliderValue inside the TextView - that works well.

Text("\(sliderValue * 10)")

But is there a way to put this into another function to be more flexible, especially if the calculation get's more complex? It should still be live updated whenever the slider is dragged.

Here is the full code a bit beautified. Maybe you can explain to me how this works in SwiftUI?

struct ContentView: View {

    @State private var sliderValue: Double = 0

    var body: some View {
        VStack(alignment: .leading) {
            VStack(alignment: .leading) {
                Text("value".uppercased())
                    .font(.largeTitle)
                    .fontWeight(.bold)
                Text("\(sliderValue)")
                    .font(.system(size: 60, weight: .bold))
                Text("new value".uppercased())
                    .font(.largeTitle)
                    .fontWeight(.bold)
                Text("\(sliderValue * 10)") // I'd like to put this into a function somehow!?
                    .font(.system(size: 60, weight: .bold))
            }


            Slider(value: $sliderValue, in: 0...100, step: 1)
                .padding(8)
                .overlay(
                    Capsule()
                        .stroke(Color.purple, style: StrokeStyle(lineWidth: 5))
            )


        }//END: VSTACK
        .padding()
    }
}

Thanks for your help!


Solution

  • Here is possible approach

    struct ContentView: View {
    
        @State private var sliderValue: Double = 0
    
        var body: some View {
            VStack(alignment: .leading) {
                VStack(alignment: .leading) {
                    Text("value".uppercased())
                        .font(.largeTitle)
                        .fontWeight(.bold)
                    Text("\(sliderValue)")
                        .font(.system(size: 60, weight: .bold))
                    Text("new value".uppercased())
                        .font(.largeTitle)
                        .fontWeight(.bold)
    
                    self.calculatedView(for: sliderValue)
                }
    
                Slider(value: $sliderValue, in: 0...100, step: 1)
                    .padding(8)
                    .overlay(
                        Capsule()
                            .stroke(Color.purple, style: StrokeStyle(lineWidth: 5))
                )
    
    
            }//END: VSTACK
            .padding()
        }
    
        private func calculatedView(for value: Double) -> some View {
            Text("\(value * 10)")
                .font(.system(size: 60, weight: .bold))
        }
    }
    

    and here is another possible approach

    struct ContentView: View {
    
        @State private var sliderValue: Double = 0
    
        var body: some View {
            VStack(alignment: .leading) {
                VStack(alignment: .leading) {
                    Text("value".uppercased())
                        .font(.largeTitle)
                        .fontWeight(.bold)
                    Text("\(sliderValue)")
                        .font(.system(size: 60, weight: .bold))
                    Text("new value".uppercased())
                        .font(.largeTitle)
                        .fontWeight(.bold)
    
                    CalculatedView(value: sliderValue)
                }
    
                Slider(value: $sliderValue, in: 0...100, step: 1)
                    .padding(8)
                    .overlay(
                        Capsule()
                            .stroke(Color.purple, style: StrokeStyle(lineWidth: 5))
                )
    
    
            }//END: VSTACK
            .padding()
        }
    }
    
    struct CalculatedView: View {
        let value: Double
    
        var body: some View {
            Text("\(value * 10)")
                .font(.system(size: 60, weight: .bold))
        }
    }