Created
July 4, 2020 08:18
-
-
Save agelessman/789ae1b475ac02ca801fb09bd5b19b98 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import SwiftUI | |
struct ContentView: View { | |
var body: some View { | |
Example2() | |
} | |
} | |
struct Example2: View { | |
@State private var progress = 0.2 | |
var body: some View { | |
VStack { | |
MyTestProgressView(progress) | |
.frame(width: 200, height: 200, alignment: /*@START_MENU_TOKEN@*/ .center/*@END_MENU_TOKEN@*/) | |
Slider(value: self.$progress, in: 0...1) | |
.padding(.horizontal, 30) | |
HStack { | |
Group { | |
Button("20%") { | |
withAnimation(.easeInOut(duration: 0.5)) { | |
self.progress = 0.2 | |
} | |
} | |
Button("50%") { | |
withAnimation(.easeInOut(duration: 0.5)) { | |
self.progress = 0.5 | |
} | |
} | |
Button("80%") { | |
withAnimation(.easeInOut(duration: 0.5)) { | |
self.progress = 0.8 | |
} | |
} | |
} | |
.foregroundColor(.white) | |
.padding(/*@START_MENU_TOKEN@*/ .all/*@END_MENU_TOKEN@*/, /*@START_MENU_TOKEN@*/10/*@END_MENU_TOKEN@*/) | |
.background(RoundedRectangle(cornerRadius: 5.0).foregroundColor(.green)) | |
} | |
} | |
} | |
} | |
public struct MyProgressView: View { | |
let gradient = Gradient(colors: [.green, .blue]) | |
let sliceSize = 0.45 | |
let progress: Double | |
private let percentageFormatter: NumberFormatter = { | |
let numberFormatter = NumberFormatter() | |
numberFormatter.numberStyle = .percent | |
return numberFormatter | |
}() | |
var strokeGradient: AngularGradient { | |
AngularGradient(gradient: gradient, center: /*@START_MENU_TOKEN@*/ .center/*@END_MENU_TOKEN@*/, angle: .degrees(-10)) | |
} | |
var rotateAngle: Angle { | |
.degrees(90 + sliceSize * 360 * 0.5) | |
} | |
init(_ progress: Double = 0.3) { | |
self.progress = progress | |
} | |
private func strokeStyle(_ proxy: GeometryProxy) -> StrokeStyle { | |
StrokeStyle(lineWidth: 0.1 * min(proxy.size.width, proxy.size.height), | |
lineCap: .round) | |
} | |
public var body: some View { | |
GeometryReader { proxy in | |
ZStack { | |
Group { | |
Circle() | |
.trim(from: 0, to: 1 - CGFloat(self.sliceSize)) | |
.stroke(self.strokeGradient, | |
style: self.strokeStyle(proxy)) | |
.padding(.all, /*@START_MENU_TOKEN@*/10/*@END_MENU_TOKEN@*/) | |
Circle() | |
.trim(from: 0, to: CGFloat(self.progress * (1 - self.sliceSize))) | |
.stroke(Color.purple, | |
style: self.strokeStyle(proxy)) | |
.padding(.all, /*@START_MENU_TOKEN@*/10/*@END_MENU_TOKEN@*/) | |
} | |
.rotationEffect(self.rotateAngle, anchor: /*@START_MENU_TOKEN@*/ .center/*@END_MENU_TOKEN@*/) | |
.offset(x: 0, y: 0.1 * min(proxy.size.width, proxy.size.height)) | |
Text("\(self.percentageFormatter.string(from: NSNumber(value: self.progress))!)") | |
.font(.largeTitle) | |
.bold() | |
} | |
} | |
} | |
} | |
struct Example1: View { | |
@State private var progress = 0.2 | |
var body: some View { | |
VStack { | |
MyTestProgressView(progress) | |
.frame(width: 600, height: 200, alignment: /*@START_MENU_TOKEN@*/ .center/*@END_MENU_TOKEN@*/) | |
} | |
} | |
} | |
/// 拆分View组件 | |
public struct MyTestProgressView: View { | |
let gradient = Gradient(colors: [.green, .blue]) | |
let sliceSize = 0.45 | |
let progress: Double | |
private let percentageFormatter: NumberFormatter = { | |
let numberFormatter = NumberFormatter() | |
numberFormatter.numberStyle = .percent | |
return numberFormatter | |
}() | |
var strokeGradient: AngularGradient { | |
AngularGradient(gradient: gradient, center: /*@START_MENU_TOKEN@*/ .center/*@END_MENU_TOKEN@*/, angle: .degrees(-10)) | |
} | |
var rotateAngle: Angle { | |
.degrees(90 + sliceSize * 360 * 0.5) | |
} | |
init(_ progress: Double = 0.3) { | |
self.progress = progress | |
} | |
private func strokeStyle(_ proxy: GeometryProxy) -> StrokeStyle { | |
StrokeStyle(lineWidth: 0.1 * min(proxy.size.width, proxy.size.height), | |
lineCap: .round) | |
} | |
public var body: some View { | |
GeometryReader { proxy in | |
HStack { | |
VStack { | |
Circle() | |
.trim(from: 0, to: 1 - CGFloat(self.sliceSize)) | |
.stroke(self.strokeGradient, | |
style: self.strokeStyle(proxy)) | |
.padding(.all, /*@START_MENU_TOKEN@*/10/*@END_MENU_TOKEN@*/) | |
.rotationEffect(self.rotateAngle, anchor: /*@START_MENU_TOKEN@*/ .center/*@END_MENU_TOKEN@*/) | |
.offset(x: 0, y: 0.1 * min(proxy.size.width, proxy.size.height)) | |
Text("背景").font(.title).bold() | |
} | |
VStack { | |
Circle() | |
.trim(from: 0, to: CGFloat(self.progress * (1 - self.sliceSize))) | |
.stroke(Color.purple, | |
style: self.strokeStyle(proxy)) | |
.padding(.all, /*@START_MENU_TOKEN@*/10/*@END_MENU_TOKEN@*/) | |
.rotationEffect(self.rotateAngle, anchor: /*@START_MENU_TOKEN@*/ .center/*@END_MENU_TOKEN@*/) | |
.offset(x: 0, y: 0.1 * min(proxy.size.width, proxy.size.height)) | |
Text("当前进度").font(.title).bold() | |
} | |
Text("\(self.percentageFormatter.string(from: NSNumber(value: self.progress))!)") | |
.font(.largeTitle) | |
.bold() | |
} | |
} | |
} | |
} | |
struct ContentView_Previews: PreviewProvider { | |
static var previews: some View { | |
ContentView() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment