Circle Indicator 만들기
오늘은 어떤 작업을 기다릴 때 사용할 수 있는 인디케이터를 만들어 보겠습니다.
프레임워크에서 제공하는 것을 사용할 수도 있지만 커스텀해서 사용하는 경우가 많기 때문에
간단히 만들 수 있는 UI를 소개할까 합니다.
@MainActor class UIActivityIndicatorView : UIView
인디케이터가 돌아가는 것을 볼 수 있게 원의 한 곳이 뚫린 UI를 만들 겁니다.

그려지는 UI는 같지만 방법은 두 가지로 설명드릴게요!
1) Path로 Shape를 만드는 방법
Shape는 View의 프로토콜은 따르는 타입입니다. 또한 (CGRect) -> Path를 구현해줘야 합니다.
struct CirclePath: Shape {
func path(in rect: CGRect) -> Path {
//rect가 주어지고 Path를 만들어서 반환하세요!
}
}
struct CirclePath: Shape {
func path(in rect: CGRect) -> Path {
let path = Path()
path.addArc(center: // 1)
CGPoint(x: rect.midX, y: rect.midY),
radius: rect.width/2,
startAngle: Angle.degrees(0),
endAngle: Angle(degrees: 320),
clockwise: false
)
return path
}
}
1) 원을 곡선으로 이뤄져 있기 때문에 addArc 메서드를 사용했습니다.
center: 이 도형의 중앙은 주어진 rect의 중간값으로 하였습니다.
radious: 중앙값으로부터 반지름이 얼마나 되냐?라는 것에 저는 rect 너비 값의 반을 주었습니다.
startAngle, endAngle: 0도부터 시계방향으로 320을 주면 40도가 빠진 곡선을 그리게 됩니다.
clockwise: 각도의 방향인데요.
true로 하면 시계 반대방향으로 각도 방향이 됩니다. 하여 저는 false로 하여 시계방향으로 각도 방향을 설정하였습니다.

회전하는 애니메이션을 만들겠습니다.
struct CircleIndicator: View {
@State var isRotationCircle: Bool = false
var body: some View {
VStack {
Text("Path Drawing indicator")
.onTapGesture {
isRotationCircle.toggle()
}
CirclePath()
.stroke(Color.indigo,
style: StrokeStyle(lineWidth: 3,
lineCap: .round)
)
.frame(width: 50, height: 50)
.rotationEffect(Angle(degrees: isRotationCircle ? 360 : 0))
.animation(.linear(duration: 0.5).repeatForever(autoreverses: false),value: isRotationCircle)
}
}
}
끝점이 뚫려있기 때문에. easeIn 같은 가변적인 애니메이션은 끊길 수 있습니다.
항상 같은 애니메이션인 linear로 해주세요!
2. 그냥 Circle을 쓰면 되잖아?
Circle()
.trim(from: 0.0, to: 320 / 360)
.stroke(Color.indigo,
style: StrokeStyle(lineWidth: 3,
lineCap: .round)
)
.frame(width: 50, height: 50)
.rotationEffect(Angle(degrees: isRotationCircle ? 360 : 0))
.animation(.linear(duration: 0.5).
repeatForever(autoreverses: false),
value: isRotationCircle
)
네.. 사실 Shape에 Path를 정의할 필요도 없습니다. trim이라는 메서드를 사용하여 0.0부터 320/ 360( 0.888888)까지 무시하라고 하면 똑같이 그려지고 애니메이션도 똑같이 작동합니다.

오늘은 원모양의 인디케이터를 만드는 두 가지 방법을 알아봤습니다. 읽으면서
"2번째 방법이 더 간단한데 굳이 Path를 그리는 것까지 알아야 할까?
라고 생각하실 수 있는데요.
SwiftUI는 뷰를 그리는 것이 개발자 친화적으로 잘되어있다고 생각하고 있기 때문에
Path를 그릴 줄 알면 나중에 좀 더 복잡하거나 디자이너분이 원하시는 UI/UX를 구현하는데
더 도움이 될 것이라고 생각해서 첫 번째 방법도 적어봤습니다.