안녕하세요!
이번에는 SwiftUI를 사용하여
사용자가 기다리고 있다는것을
인지할 수 있도록 직접 스켈레톤을 만들어 보려고 합니다.
대부분 개발하는 정대리님의 코드를 보고 작성하였습니다.
저는 스켈레톤뷰를 검정 -> 회색으로 배경화면이 바뀌도록 설정했습니다.
import SwiftUI
struct SkeletonView: View {
private let size: CGSize
@State private var isBlackBackground = true
var backgroundColor: Color { isBlackBackground ? .black : .gray
}
init(size: CGSize) {
self.size = size
}
var body: some View {
RoundedRectangle(cornerRadius: 8)
.fill(backgroundColor)
.opacity(0.5)
.frame(width: size.width, height: size.height)
.overlay(
RoundedRectangle(cornerRadius: 8)
.stroke(Color.white, lineWidth: 2)
.overlay(
RoundedRectangle(cornerRadius: 8)
.stroke(Color.white, lineWidth: 1)
.padding(1)
)
)
.overlay(content: {
ProgressView()
})
.redacted(reason: .placeholder)
.onAppear {
withAnimation(Animation.easeInOut(duration: 1.0).repeatForever(autoreverses: true)) {
isBlackBackground.toggle()
}
}
}
}
하나의 구조체로 생성을해 각 이미지마다 크기별로 스켈레톤을 입히기 위해서 생성자로 size를 받아왔습니당
그 후 RoundedRectangle을 사용하여 사이즈에 맞게 뷰의 크기를 적용하였고,
.onappear됐을 때 배경화면을 1초마다 변경하도록 하였습니다.
코드를 적용시킨 곳
var body: some View {
Button(action: {
isSheet = true
}, label: {
AsyncImage(url: URL(string: unsplash.urls.regular)) { image in
image
.resizable()
.aspectRatio(contentMode: .fill)
.frame(minWidth: 100, maxWidth: 200, maxHeight: 150)
.cornerRadius(10)
} placeholder: {
SkeletonView(size: CGSize(width: 200, height: 150))
} // 여깁니다
})
.fullScreenCover(isPresented: $isSheet, content: {
DetailView(bookmarkStore: bookmarkStore, unsplash: unsplash, id: "", isSheet: $isSheet)
})
}
주석을 달아놓은곳에 적용을 해보았는데요. 사이즈는 알아서 조절하시면 됩니다!