SwiftUI查漏补缺(2) - 自定义ProgressBar

3周前 58次点击 来自 SwiftUI

收录专题: SwiftUI查漏补缺

原文链接:
SwiftUI Progress bar/indicator

自定义ProgressBar和ProgressCircle

今日在开发中需要使用到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()
    }
}
Card image cap
开发者雷

尘世间一个小小的开发者

技术文档 >> 系列应用 >>
热推应用

EntryS

学习Swift的入门教程
标签