Reputation: 189
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
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
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
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
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