3초에 거쳐 테두리 원이 완성되는 코드입니다
간단한 설명
percent: 테두리의 회전 정도를 의미합니다 (0~1)
count: 1초에서 3초동안 바뀌는 과정을 보여주기 위해서 사용되는 프로퍼티 값입니다.
DispatchQueue.main.asyncAfter를 사용하여 현 시점에서 애니메이션을 한번 1초 뒤에 다시 한번 2초 뒤에 다시 한번 각각 1초를 거쳐 값을 변화도록 만들었습니다.
trim은 불필요한 것을 자른다는 의미로 0부터 1사이의 값으로 도형을 자르는 것입니다.
stroke는 테두리를 꾸미는데 사용됩니다.
fill로 원을 채울 색깔을 지정합니다.
rotationEffect으로 원을 회전시킵니다.
아래코드를 위에 사진에서 하얀색 원에 해당되는 코드입니다.
.overlay(
Circle()
.foregroundStyle(.red)
.frame(width: pinHeight, height: pinHeight)
.offset(y: -pinHeight / 2)
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
.rotationEffect(Angle(degrees: 360 * Double(completion)))
)
총 코드
import SwiftUI
struct CircleView: View {
@State var percent: CGFloat = 0
@State var count: Int = 0
var body: some View {
Loader(percent: $percent, count: $count)
.onAppear {
DispatchQueue.main.asyncAfter(deadline: .now()) {
withAnimation(Animation.easeInOut(duration: 1.0)) {
percent = 0.33
count = 1
}
}
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
withAnimation(Animation.easeInOut(duration: 1.0)) {
percent = 0.66
count = 2
}
}
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
withAnimation(Animation.easeInOut(duration: 1.0)) {
percent = 1
count = 3
}
}
}
}
}
struct CircleView_Previews: PreviewProvider {
static var previews: some View {
CircleView()
}
}
struct Loader: View {
@Binding var percent: CGFloat
@Binding var count: Int
var colors: [Color] = [
Color(hex: "#AAFFA9"),
Color(hex: "#11FFBD")
]
let circleHeight: CGFloat = 300
var body: some View {
let pinHeight = circleHeight * 0.1
let completion = percent
Circle()
.trim(from: 0, to: completion)
.stroke(style: StrokeStyle(lineWidth: 22, lineCap: .butt, lineJoin: .round, miterLimit: 50))
.fill(AngularGradient(gradient: .init(colors: colors), center: .center, startAngle: .zero, endAngle: .init(degrees: 360)))
.rotationEffect(.degrees(-90))
.frame(width: circleHeight, height: circleHeight)
.overlay(
Text(String(count))
.animation(nil)
)
.overlay(
Circle()
.frame(width: pinHeight, height: pinHeight)
.offset(y: -pinHeight / 2)
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
.rotationEffect(Angle(degrees: 360 * Double(completion)))
)
}
}
extension Color {
init(hex: String) {
let scanner = Scanner(string: hex)
_ = scanner.scanString("#")
var rgb: UInt64 = 0
scanner.scanHexInt64(&rgb)
let r = Double((rgb >> 16) & 0xFF) / 255.0
let g = Double((rgb >> 8) & 0xFF) / 255.0
let b = Double((rgb >> 0) & 0xFF) / 255.0
self.init(red: r, green: g, blue: b)
}
}
'SwiftUI' 카테고리의 다른 글
네이버 지도 클러스터링 (0) | 2024.05.02 |
---|---|
네이버 지도 시작하기 (0) | 2024.05.01 |
Cocoapods (0) | 2024.05.01 |
KaKao Map 카카오맵 (0) | 2024.04.30 |
Protocols 프로토콜 (0) | 2024.04.27 |