ProgressView 进度条

ProgressView 适合用于展示一个任务的进度


显示模糊进度

如果不明确该任务的完成所需时间,则使用 circular 样式,一个旋转的菊花(默认)。创建方式很简单:

// 直接展示一个旋转的 loading
ProgressView()

// 在菊花下面展示一个 Label
ProgressView("Downloading…")

// 在菊花下面展示自定义视图
ProgressView {
	VStack{
		Text("Loading")
		Image(systemName: "circle.dashed")
	}
	.font(.title)
	.foregroundStyle(.purple)
	.padding(.top)
}

// 设置菊花的颜色
ProgressView("Loading")
		.tint(.purple)

// 设置 Label 的颜色样式
ProgressView("Loading")
		.tint(.purple)
		.font(system(size: 25, weight: heavy, design: .rounded))
		.foregroundStyle(.purple)

显示准确进度

如果明确知道任务的完成所需时间,则使用 linear 样式,一个进度条。ProgressView 可以绑定到 Double 类型的属性,以显示水平进度条。

创建进度条的方法如下,只要给 ProgressView 设定 value 参数的值,swiftUI 就会自动将其显示为进度条的样式。

// value 的值默认是从 0 到 1
ProgressView(value: 0.4)

// 我们可以设置 total 参数,去自定义其最大值
ProgressView(value: 25, total: 100)

// 还可以设置 currentValueLabel 闭包,以显示当前具体进度值等信息
ProgressView (value: 25, total: 100){
		HStack{
			Spacer()
			Text("Download progress").fontWeight(.bold)
			Spacer()
		}
		.padding(.bottom)
} currentValueLabel: {
		HStack {
			Spacer()
			Text("25%").foregroundStyle(.blue .fontWeight(.bold)
			Spacer()
		}
		.padding(.top)
}
// 例如,这将创建一个标题为“Downloading”的进度条,该进度条将读取 downloadAmount 以确定进度条应有多满:
struct ContentView: View {
    @State private var downloadAmount = 0.0
    var body: some View {
        VStack {
            ProgressView("Downloading…", value: downloadAmount, total: 100)
		            // 改变其样式
		            .progressViewStyle(LinearProgressViewStyle(tint: Color.blue))
        }
    }
}

// 在实践中为了检查进度条是否正常工作,您需要某种方法来实际更改该值,例如计时器、网络请求或其他用户界面
struct ContentView: View {
    @State private var downloadAmount = 0.0
    let timer = Timer.publish(every: 0.1, on: .main, in: .common).autoconnect()
    var body: some View {
        ProgressView("Downloading…", value: downloadAmount, total: 100)
            .onReceive(timer) { _ in
                if downloadAmount < 100 {
                    downloadAmount += 2
                }
            }
    }
}

注意:如果您将进度值设置为高于进度 total 参数 ,Xcode 会生气,请确保设置正确的上限。


使用 ProgressViewStyle 自定义

SwiftUI 提供了 ProgressViewStyle 协议,来为 ProgressView 创建自定义设计,具体步骤如下:

以下有一个自定义样式,它创建一个仪表,将进度显示为一个描边圆圈,随着进度的增加而完成:

struct GaugeProgressStyle: ProgressViewStyle {
    var strokeColor = Color.blue
    var strokeWidth = 25.0

    func makeBody(configuration: Configuration) -> some View {
        let fractionCompleted = configuration.fractionCompleted ?? 0
        return ZStack {
            Circle()
                .trim(from: 0, to: fractionCompleted)
                .stroke(strokeColor, style: StrokeStyle(lineWidth: strokeWidth, lineCap: .round))
                // 自定义样式如何将圆圈逆时针旋转 90 度,因此圆圈从顶部开始绘制进度
                .rotationEffect(.degrees(-90))
        }
    }
}

// A view letting you adjust the progress with tap gestures
struct ContentView: View {
    @State private var progress = 0.2
    var body: some View {
        ProgressView(value: progress, total: 1.0)
            .progressViewStyle(GaugeProgressStyle())
            .frame(width: 200, height: 200)
            .contentShape(Rectangle())
            .onTapGesture {
                if progress < 1.0 {
                    withAnimation {
                        progress += 0.2
                    }
                }
            }
    }