8000 Skeleton Modifier · Issue #54 · mdb1/mdb1.github.io · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
Skeleton Modifier #54
Closed
Closed
@mdb1

Description

@mdb1
import SwiftUI

extension View {
    /// Adds a loading skeleton effect by masking the subviews when `condition` is true.
    /// If you want to add skeleton to all the subviews in a container (like a Stack),
    /// apply skeleton to the Stack itself.
    ///
    /// Apply to the whole view
    /// ==================
    /// If you need to apply the effect to the whole view instead of only to the subviews,
    /// create a conditional overlay color and apply the skeleton to it:
    ///
    /// ```swift
    /// view
    ///   .overlay(Color.gray)
    ///   .skeleton()
    /// ```
    @ViewBuilder
    func skeleton(condition: Bool = true) -> some View {
        if condition {
            redacted(reason: .placeholder)
                .modifier(Shimmer())
        } else {
            self
        }
    }
}

struct Shimmer: ViewModifier {
    @State private var isInitialState = true

    func body(content: Content) -> some View {
        content
            .mask(
                LinearGradient(
                    gradient: Gradient(
                        colors: [
                            .white.opacity(0.9),
                            .white.opacity(0.6),
                            .white.opacity(0.5),
                            .white.opacity(0.3),
                            .white.opacity(0),
                            .white.opacity(0.3),
                            .white.opacity(0.6),
                            .white.opacity(0.9),
                        ]
                    ),
                    startPoint: isInitialState ? .init(x: -1.0, y: 0) : .init(x: 1, y: 1),
                    endPoint: isInitialState ? .init(x: 0, y: 0) : .init(x: 1.9, y: 1)
                )
            )
            .animation(
                .easeIn(duration: 1.25)
                    .delay(0.25)
                    .repeatForever(autoreverses: false),
                value: isInitialState
            )
            .onAppear {
                // Needed to prevent a random bug in SwiftUI that makes this view
                // to move randomly while the animation is on.
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
                    isInitialState = false
                }
            }
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0