自定义ProgressBar
4个月前 • 177次点击 • 来自 SwiftUI
原文链接:
SwiftUI Progress bar/indicator
今日在开发中需要使用到ProgressBar,发现SwiftUI暂时未提供原生控件,虽然自己写也非常简单,一番Google对比之后发现上述文章的实现,故搬过来做个备忘,直接懒到一回。
实际上,如文章所述,SwiftUI中自定义控件的流程非常顺畅,只要思路清晰,非常少的代码就是能实现很好的UI效果。
1.Progressbar.swift:
import SwiftUI
struct ProgressBar: View {
var value: Float
private let backgroundColor: Color
private let foregroundColor: Color
init(value: Float,
backgroundColor: Color = Color.gray,
foregroundColor: Color = Color.green) {
self.value = value
self.backgroundColor = backgroundColor
self.foregroundColor = foregroundColor
}
var body: some View {
GeometryReader { geometry in
ZStack(alignment: .leading) {
Capsule().frame(width: geometry.size.width, height: geometry.size.height)
.opacity(0.25).foregroundColor(self.backgroundColor)
Capsule().frame(width: min(CGFloat(self.value) * geometry.size.width, geometry.size.width), height: geometry.size.height)
.foregroundColor(self.foregroundColor)
.animation(.easeIn)
}
}
}
}
2.ProgressCircle.swift:
import SwiftUI
struct ProgressCircle: View {
enum Stroke {
case line
case dotted
func strokeStyle(lineWidth: CGFloat) -> StrokeStyle {
switch self {
case .line:
return StrokeStyle(lineWidth: lineWidth,
lineCap: .round)
case .dotted:
return StrokeStyle(lineWidth: lineWidth,
lineCap: .round,
dash: [12])
}
}
}
private let value: Float
private let style: Stroke
private let backgroundEnabled: Bool
private let backgroundColor: Color
private let foregroundColor: Color
private let lineWidth: CGFloat
init(value: Float,
style: Stroke = .line,
backgroundEnabled: Bool = true,
backgroundColor: Color = Color(UIColor(red: 245 / 255,
green: 245 / 255,
blue: 245 / 255,
alpha: 1.0)),
foregroundColor: Color = Color.black,
lineWidth: CGFloat = 10) {
self.value = value
self.style = style
self.backgroundEnabled = backgroundEnabled
self.backgroundColor = backgroundColor
self.foregroundColor = foregroundColor
self.lineWidth = lineWidth
}
var body: some View {
ZStack {
if self.backgroundEnabled {
Circle()
.stroke(lineWidth: self.lineWidth)
.foregroundColor(self.backgroundColor)
}
Circle()
.trim(from: 0, to: CGFloat(self.value))
.stroke(style: self.style.strokeStyle(lineWidth: self.lineWidth))
.foregroundColor(self.foregroundColor)
.rotationEffect(Angle(degrees: -90))
.animation(.easeIn)
}
}
}
3.ContentView.swift:
import SwiftUI
struct ContentView: View {
@State var progressValue: Float = 0.0
private let maxValue: Float = 1.0
var body: some View {
VStack {
Spacer()
ProgressBar(value: progressValue).frame(height: 20)
Spacer()
ProgressCircle(value: $progressValue.wrappedValue,
style: .dotted,
foregroundColor: .red,
lineWidth: 10)
.frame(height: 100)
Spacer()
Slider(value: $progressValue,
in: 0 ... maxValue)
.padding()
}.padding()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
标签