How to use
// prepare `isLoading: Bool` variable.
VStack { ... }
.redacted(reason: viewModel.isLoading ? .placeholder : [])
.animatePlaceholder(isLoading: $isLoading)
2 Steps
- Create AnimatePlaceholderModifier
- Add extension method to View
Step1: Create AnimatePlaceholderModifier
struct AnimatePlaceholderModifier: AnimatableModifier {
@Binding var isLoading: Bool
@State private var isAnim: Bool = false
private var center = (UIScreen.main.bounds.width / 2) + 110
private let animation: Animation = .linear(duration: 1.5)
init(isLoading: Binding<Bool>) {
self._isLoading = isLoading
}
func body(content: Content) -> some View {
content.overlay(animView.mask(content))
}
var animView: some View {
ZStack {
Color.black.opacity(isLoading ? 0.09 : 0.0)
Color.white.mask(
Rectangle()
.fill(
LinearGradient(gradient: .init(colors: [.clear, .white.opacity(0.48), .clear]), startPoint: .top , endPoint: .bottom)
)
.scaleEffect(1.5)
.rotationEffect(.init(degrees: 70.0))
.offset(x: isAnim ? center : -center)
)
}
.animation(isLoading ? animation.repeatForever(autoreverses: false) : nil, value: isAnim)
.onAppear {
guard isLoading else { return }
isAnim.toggle()
}
.onChange(of: isLoading) { _ in
isAnim.toggle()
}
}
}
Step2: Add extension method to View
extension View {
func animatePlaceholder(isLoading: Binding<Bool>) -> some View {
self.modifier(AnimatePlaceholderModifier(isLoading: isLoading))
}
}
Top comments (0)