49 lines
1.4 KiB
Swift
49 lines
1.4 KiB
Swift
//
|
|
// https://mczachurski.dev
|
|
// Copyright © 2023 Marcin Czachurski and the repository contributors.
|
|
// Licensed under the Apache License 2.0.
|
|
//
|
|
|
|
import SwiftUI
|
|
|
|
/// Modifier for using with view placeholders (with redacted modifier).
|
|
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)
|
|
private let animation: Animation = .easeOut(duration: 1)
|
|
|
|
init(isLoading: Binding<Bool>) {
|
|
self._isLoading = isLoading
|
|
}
|
|
|
|
func body(content: Content) -> some View {
|
|
content.overlay(animView.mask(content))
|
|
}
|
|
|
|
var animView: some View {
|
|
LinearGradient(
|
|
gradient: .init(colors: [.black, .black.opacity(0.6), .black.opacity(0.3), .clear]),
|
|
startPoint: .leading,
|
|
endPoint: isAnim ? .trailing : .leading)
|
|
.animation(isLoading ? animation.repeatForever(autoreverses: false) : nil, value: isAnim)
|
|
.onAppear {
|
|
guard isLoading else { return }
|
|
isAnim.toggle()
|
|
}
|
|
.onChange(of: isLoading) { _ in
|
|
isAnim.toggle()
|
|
}
|
|
}
|
|
}
|
|
|
|
extension View {
|
|
|
|
/// Animate redacted placeholders.
|
|
func animatePlaceholder(isLoading: Binding<Bool>) -> some View {
|
|
self.modifier(AnimatePlaceholderModifier(isLoading: isLoading))
|
|
}
|
|
}
|