SwiftUIでの図形の描写とアニメーションに関するドキュメントを探していたら
こちらに書いていました。
今回はSwiftUIのCircleコンポーネントを使って簡単なインジケーターを作成したと思います。前回はUIViewRepresentableを用いれば既存のUIKitのコンポーネントをSwiftUIでも利用できることを学びました。
今回はそれを応用してSwiftUIでよくiOSのライブラリになっているインジケーターを開発してみます。
スポンサーリンク
ソースコードについて
いきなりですが、完成品のソースコードを載せます。
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView{
Home()
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct Home: View {
/// ローディング中かどうか
@State var isLoading = false
var body: some View {
ZStack {
VStack(spacing: 25) {
Button(action: {
isLoading.toggle()
}, label: {
Text("インジケーター")
})
}
if isLoading {
HUDProgressView(placeHolder: "ローディング中", isShow: $isLoading)
}
}
.edgesIgnoringSafeArea(.all)
}
}
struct HUDProgressView: View {
var placeHolder: String
@Binding var isShow: Bool
@State var animated = false
var body: some View {
VStack(spacing: 28) {
Circle()
.stroke(AngularGradient(gradient: .init(colors: [Color.primary, Color.primary.opacity(0)]), center: .center))
.frame(width: 80, height: 80)
.rotationEffect(.init(degrees: animated ? 360: 0))
Text(placeHolder)
.fontWeight(.bold)
}
.padding(.vertical, 25)
.padding(.horizontal, 35)
.background(BlurView())
.cornerRadius(20)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(
Color.primary.opacity(0.35)
.onTapGesture {
withAnimation {
isShow.toggle()
}
}
)
.onAppear {
withAnimation(Animation.linear(duration: 1.5).repeatForever(autoreverses: false)) {
animated.toggle()
}
}
}
}
struct BlurView: UIViewRepresentable {
func makeUIView(context: Context) -> UIVisualEffectView {
let view = UIVisualEffectView(effect: UIBlurEffect(style: .systemThinMaterial))
return view
}
func updateUIView(_ uiView: UIVisualEffectView, context: Context) {
}
}
こちらをビルドすると次のような画面が表示されます。
前回のUIViewRepresentableプロトコルに準拠させたBlueViewの構造体をを背景色にしてCircleを描写されてます。BlueViewはUIVisualEffectViewをSwiftUIで利用できるようにしたコンポーネントです。
それでは、バイバイ。