SwiftUI로 만드는 진행
소개
이 기사는 Diverse Advent Calendar 2020의 18 일째 기사입니다.
업무로 몇 가지 진행을 만들었으므로 소개합니다.
비슷한 디자인의 프로그레스를 만들 때는 꼭 활용해 주세요!
GitHub에이 기사의 샘플을 올리고 있습니다.
↓실제로 움직임을 보고 싶은 분은 이쪽
htps : // 기주 b. 코 m / 마사 타카 칸 / 수프 f 드 Prog rs
링
struct RingProgressView: View {
var value: CGFloat
var lineWidth: CGFloat = 6.0
var outerRingColor: Color = Color.black.opacity(0.08)
var innerRingColor: Color = Color.orange
var body: some View {
ZStack {
Circle()
.stroke(lineWidth: self.lineWidth)
.foregroundColor(self.outerRingColor)
Circle()
.trim(from: 0.0, to: CGFloat(min(self.value, 1.0)))
.stroke(
style: StrokeStyle(
lineWidth: self.lineWidth,
lineCap: .square, // プログレスの角を丸くしたい場合は.round
lineJoin: .round
)
)
.foregroundColor(self.innerRingColor)
.rotationEffect(.degrees(-90.0))
}
.padding(.all, self.lineWidth / 2)
}
}
@State var value: CGFloat = 0.0
var body: some View {
RingProgressView(value: value)
.frame(width: 150, height: 150)
.onAppear {
withAnimation(.linear(duration: 5)) {
self.value = 1.0
}
}
}
Pie
Shape를 계승해 PieShape라고 하는 것을 만들고 있습니다.
Shape를 자체 제작한 경우 애니메이션이 적용되지 않으므로 animatableData
를 override 해야 합니다.
struct PieProgressView: View {
var value: CGFloat
var body: some View {
ZStack {
Circle()
.fill(Color.black.opacity(0.08))
PieShape(progress: value)
.fill(Color.orange)
.rotationEffect(.degrees(-90))
}
}
}
struct PieShape: Shape {
var value: CGFloat
var animatableData: CGFloat {
get { value }
set { value = newValue }
}
func path(in rect: CGRect) -> Path {
Path { path in
let center = CGPoint(x: rect.midX, y: rect.midY)
path.move(to: center)
path.addArc(
center: center,
radius: rect.width / 2,
startAngle: .degrees(0),
endAngle: .degrees(Double(360 * value)),
clockwise: false
)
path.closeSubpath()
}
}
}
@State var value: CGFloat = 0.0
var body: some View {
PieProgressView(value: value)
.frame(width: 150, height: 150)
.onAppear {
withAnimation(.linear(duration: 5)) {
self.value = 1.0
}
}
}
광장
Rectangle을 2개 겹쳐 위의 Rectangle의 width를 value에 따라 바꾸는 것으로 실현하고 있습니다.
Square라고 명명하고 있지만 cornerRadius를 지정하여 둥글게 할 수도 있습니다.
struct SquareProgressView: View {
var value: CGFloat
var baseColor: Color = Color.black.opacity(0.08)
var progressColor: Color = Color.orange
var body: some View {
GeometryReader { geometry in
VStack(alignment: .trailing) {
ZStack(alignment: .leading) {
Rectangle()
.fill(self.baseColor)
Rectangle()
.fill(self.progressColor)
.frame(minWidth: 0, idealWidth:self.getProgressBarWidth(geometry: geometry),
maxWidth: self.getProgressBarWidth(geometry: geometry))
}
}
}
}
func getProgressBarWidth(geometry:GeometryProxy) -> CGFloat {
let frame = geometry.frame(in: .global)
return frame.size.width * value
}
}
@State var value: CGFloat = 0.0
var body: some View {
SquareProgressView(value: value)
.frame(height: 20)
//.cornerRadius(10) 角丸も可
.onAppear {
withAnimation(.linear(duration: 5)) {
self.value = 1.0
}
}
}
사이고에게
이번에는 작성한 프로그레스를 3개 소개했습니다.
기본적으로 copipe에서 사용할 수 있다고 생각하므로 꼭 활용하십시오.
Reference
이 문제에 관하여(SwiftUI로 만드는 진행), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/Masataka-n/items/6f7ca52e5acfe74af453
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
struct RingProgressView: View {
var value: CGFloat
var lineWidth: CGFloat = 6.0
var outerRingColor: Color = Color.black.opacity(0.08)
var innerRingColor: Color = Color.orange
var body: some View {
ZStack {
Circle()
.stroke(lineWidth: self.lineWidth)
.foregroundColor(self.outerRingColor)
Circle()
.trim(from: 0.0, to: CGFloat(min(self.value, 1.0)))
.stroke(
style: StrokeStyle(
lineWidth: self.lineWidth,
lineCap: .square, // プログレスの角を丸くしたい場合は.round
lineJoin: .round
)
)
.foregroundColor(self.innerRingColor)
.rotationEffect(.degrees(-90.0))
}
.padding(.all, self.lineWidth / 2)
}
}
@State var value: CGFloat = 0.0
var body: some View {
RingProgressView(value: value)
.frame(width: 150, height: 150)
.onAppear {
withAnimation(.linear(duration: 5)) {
self.value = 1.0
}
}
}
Pie
Shape를 계승해 PieShape라고 하는 것을 만들고 있습니다.
Shape를 자체 제작한 경우 애니메이션이 적용되지 않으므로 animatableData
를 override 해야 합니다.
struct PieProgressView: View {
var value: CGFloat
var body: some View {
ZStack {
Circle()
.fill(Color.black.opacity(0.08))
PieShape(progress: value)
.fill(Color.orange)
.rotationEffect(.degrees(-90))
}
}
}
struct PieShape: Shape {
var value: CGFloat
var animatableData: CGFloat {
get { value }
set { value = newValue }
}
func path(in rect: CGRect) -> Path {
Path { path in
let center = CGPoint(x: rect.midX, y: rect.midY)
path.move(to: center)
path.addArc(
center: center,
radius: rect.width / 2,
startAngle: .degrees(0),
endAngle: .degrees(Double(360 * value)),
clockwise: false
)
path.closeSubpath()
}
}
}
@State var value: CGFloat = 0.0
var body: some View {
PieProgressView(value: value)
.frame(width: 150, height: 150)
.onAppear {
withAnimation(.linear(duration: 5)) {
self.value = 1.0
}
}
}
광장
Rectangle을 2개 겹쳐 위의 Rectangle의 width를 value에 따라 바꾸는 것으로 실현하고 있습니다.
Square라고 명명하고 있지만 cornerRadius를 지정하여 둥글게 할 수도 있습니다.
struct SquareProgressView: View {
var value: CGFloat
var baseColor: Color = Color.black.opacity(0.08)
var progressColor: Color = Color.orange
var body: some View {
GeometryReader { geometry in
VStack(alignment: .trailing) {
ZStack(alignment: .leading) {
Rectangle()
.fill(self.baseColor)
Rectangle()
.fill(self.progressColor)
.frame(minWidth: 0, idealWidth:self.getProgressBarWidth(geometry: geometry),
maxWidth: self.getProgressBarWidth(geometry: geometry))
}
}
}
}
func getProgressBarWidth(geometry:GeometryProxy) -> CGFloat {
let frame = geometry.frame(in: .global)
return frame.size.width * value
}
}
@State var value: CGFloat = 0.0
var body: some View {
SquareProgressView(value: value)
.frame(height: 20)
//.cornerRadius(10) 角丸も可
.onAppear {
withAnimation(.linear(duration: 5)) {
self.value = 1.0
}
}
}
사이고에게
이번에는 작성한 프로그레스를 3개 소개했습니다.
기본적으로 copipe에서 사용할 수 있다고 생각하므로 꼭 활용하십시오.
Reference
이 문제에 관하여(SwiftUI로 만드는 진행), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/Masataka-n/items/6f7ca52e5acfe74af453
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
struct PieProgressView: View {
var value: CGFloat
var body: some View {
ZStack {
Circle()
.fill(Color.black.opacity(0.08))
PieShape(progress: value)
.fill(Color.orange)
.rotationEffect(.degrees(-90))
}
}
}
struct PieShape: Shape {
var value: CGFloat
var animatableData: CGFloat {
get { value }
set { value = newValue }
}
func path(in rect: CGRect) -> Path {
Path { path in
let center = CGPoint(x: rect.midX, y: rect.midY)
path.move(to: center)
path.addArc(
center: center,
radius: rect.width / 2,
startAngle: .degrees(0),
endAngle: .degrees(Double(360 * value)),
clockwise: false
)
path.closeSubpath()
}
}
}
@State var value: CGFloat = 0.0
var body: some View {
PieProgressView(value: value)
.frame(width: 150, height: 150)
.onAppear {
withAnimation(.linear(duration: 5)) {
self.value = 1.0
}
}
}
Rectangle을 2개 겹쳐 위의 Rectangle의 width를 value에 따라 바꾸는 것으로 실현하고 있습니다.
Square라고 명명하고 있지만 cornerRadius를 지정하여 둥글게 할 수도 있습니다.
struct SquareProgressView: View {
var value: CGFloat
var baseColor: Color = Color.black.opacity(0.08)
var progressColor: Color = Color.orange
var body: some View {
GeometryReader { geometry in
VStack(alignment: .trailing) {
ZStack(alignment: .leading) {
Rectangle()
.fill(self.baseColor)
Rectangle()
.fill(self.progressColor)
.frame(minWidth: 0, idealWidth:self.getProgressBarWidth(geometry: geometry),
maxWidth: self.getProgressBarWidth(geometry: geometry))
}
}
}
}
func getProgressBarWidth(geometry:GeometryProxy) -> CGFloat {
let frame = geometry.frame(in: .global)
return frame.size.width * value
}
}
@State var value: CGFloat = 0.0
var body: some View {
SquareProgressView(value: value)
.frame(height: 20)
//.cornerRadius(10) 角丸も可
.onAppear {
withAnimation(.linear(duration: 5)) {
self.value = 1.0
}
}
}
사이고에게
이번에는 작성한 프로그레스를 3개 소개했습니다.
기본적으로 copipe에서 사용할 수 있다고 생각하므로 꼭 활용하십시오.
Reference
이 문제에 관하여(SwiftUI로 만드는 진행), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/Masataka-n/items/6f7ca52e5acfe74af453
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(SwiftUI로 만드는 진행), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/Masataka-n/items/6f7ca52e5acfe74af453텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)