Johanna
Johanna

Reputation: 189

Rectangle progress bar swiftUI

Hey does someone know how can I create rectangle progress bar in swiftUI?

Something like this? https://i.sstatic.net/CMwB3.gif

I have tried this:

struct ProgressBar: View
{
    @State var degress = 0.0
    @Binding var shouldLoad: Bool

    var body: some View
    {
        RoundedRectangle(cornerRadius: cornerRadiusValue)
            .trim(from: 0.0, to: CGFloat(degress))
            .stroke(Color.Scheme.main, lineWidth: 2.0)
            .frame(width: 300, height: 40, alignment: .center)
            .onAppear(perform: shouldLoad == true ? {self.start()} : {})
    }

    func start()
    {
        Timer.scheduledTimer(withTimeInterval: 0.3, repeats: true)
        {
            timer in

            withAnimation
            {
                self.degress += 0.3
            }
        }
    }
}

Upvotes: 2

Views: 3463

Answers (3)

Sethmr
Sethmr

Reputation: 3074

I prefer this!

struct ContentView: View {
    @State private var downloaded = 0.0
    let total = 100

    var body: some View {
        ProgressView("Demo", value: downloaded, total: total)
            .progressViewStyle(RectangleProgressViewStyle())
            .onAppear {
                Timer.scheduledTimer(withTimeInterval: 0.3, repeats: true) { timer in
                    downloaded = min(downloaded + 0.3, total)
                }
            }
    }
}

struct ContentView: View {
    @State private var interval: TimeInterval = 6
    @State private var restartId: Int = 0
        
    var body: some View {
        var timeInterval: ClosedRange<Date> {
            let start = Date()
            let end = start.addingTimeInterval(interval)
            return start...end
        }
        ProgressView(timerInterval: timeInterval)
            .progressViewStyle(RectangleProgressViewStyle())
            .id(restartId)
            .labelsHidden()
            .overlay { Text("Demo") }
    }
}


struct RectangleProgressViewStyle: ProgressViewStyle {
    let width: CGFloat?
    let height: CGFloat
    let cornerRadius: CGFloat

    init(width: CGFloat? = nil, height: CGFloat = 28, cornerRadius: CGFloat = 4) {
        self.width = width
        self.height = height
        self.cornerRadius = cornerRadius
    }

    func makeBody(configuration: Configuration) -> some View {
        ZStack {
            RoundedRectangle(cornerRadius: cornerRadius)
                .trim(from: 0.0, to: configuration.fractionCompleted ?? 0)
                .stroke(Color.red, lineWidth: 2.0)
            configuration.label
        }
        .frame(maxWidth: width ?? .infinity, minHeight: height, maxHeight: height)
    }
}

Upvotes: 0

Asperi
Asperi

Reputation: 257693

Here is simple demo of possible approach for [0..1] range progress indicator.

Updated: re-tested with Xcode 13.3 / iOS 15.4

demo

struct ProgressBar: View {
    @Binding var progress: CGFloat // [0..1]

    var body: some View {
        RoundedRectangle(cornerRadius: 10)
            .trim(from: 0.0, to: CGFloat(progress))
            .stroke(Color.red, lineWidth: 2.0)
            .animation(.linear, value: progress)
    }
}

struct DemoAnimatingProgress: View {
    @State private var progress = CGFloat.zero

    var body: some View {
        Button("Demo") {
            if self.progress == .zero {
                self.simulateLoading()
            } else {
                self.progress = 0
            }
        }
        .padding()
        .background(ProgressBar(progress: $progress))
    }

    func simulateLoading() {
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
            self.progress += 0.1
            if self.progress < 1.0 {
                self.simulateLoading()
            }
        }
    }
}

Upvotes: 6

gandhi Mena
gandhi Mena

Reputation: 2293

Available for XCode 12.

import SwiftUI

//MARK: - ProgressBar
struct ContentView: View {
    
    @State private var downloaded = 0.0
    
    var body: some View {
        ProgressView("Downloaded...", value: downloaded, total: 100)
    }
}

//MARK: - Circular ProgressBar
struct ContentView: View {
        
    @State private var downloaded = 0.0
        
    var body: some View {
        ProgressView("Downloaded...", value: downloaded, total: 100)
            .progressViewStyle(CircularProgressViewStyle())
    }
}

Upvotes: 0

Related Questions