GithubHelp home page GithubHelp logo

markiv / swiftui-shimmer Goto Github PK

View Code? Open in Web Editor NEW
909.0 12.0 55.0 252 KB

Shimmer is a super-light modifier that adds a shimmering effect to any SwiftUI View, for example, to show that an operation is in progress. It works well on light and dark modes, and across iOS, macOS, tvOS, watchOS and visionOS.

License: MIT License

Swift 89.74% Ruby 10.26%
swiftui swift ios macos tvos watch shimmer skeleton visionos

swiftui-shimmer's Introduction

SwiftUI-Shimmer ✨

Shimmer is a super-light modifier that adds a "shimmering" effect to any SwiftUI View, for example, to show that an operation is in progress. It works well on light and dark modes, left-to-right and right-to-left layout directions, and across all Apple platforms: iOS, macOS, tvOS, watchOS and even visionOS! 📱💻🖥️📺⌚️🥽✨

visionOS watchOS

Usage

import SwiftUI
import Shimmer


Text("SwiftUI Shimmer").modifier(Shimmer())

or more conveniently

Text("SwiftUI Shimmer").shimmering()

Light Mode Dark Mode

Optional Parameters ⚙️

  • active: Convenience parameter to conditionally enable the effect. Defaults to true.
  • animation: A custom animation. Defaults to Shimmer.defaultAnimation.
  • gradient: A custom gradient. Defaults to Shimmer.defaultGradient.
  • bandSize: The size of the animated mask's "band". Defaults to 0.2 unit points, which corresponds to 20% of the extent of the gradient.

Backward Compatible Parameters

  • active: Convenience parameter to conditionally enable the effect. Defaults to true.
  • duration: The duration of a shimmer cycle in seconds. Default: 1.5.
  • bounce: Whether to bounce (reverse) the animation back and forth. Defaults to false.
  • delay: A delay in seconds. Defaults to 0.

Bounce 3

Custom Animations

You can supply any custom animation:

Text("Loading...")
    .shimmering(
        active: isAnimating,
        animation: .easeInOut(duration: 2).repeatCount(5, autoreverses: false).delay(1)
    )

Animated Skeletons ☠️

Of course, you can combine .shimmering(...) with the .redacted(...) modifier to create interesting animated skeleton views.

Loading

Text("Some text")
    .redacted(reason: .placeholder)
    .shimmering()

Right-To-Left (RTL) Support

The mask and animation now adjusts automatically to the environment's layoutDirection in order to better support different languages and locales.

Installation

Swift Package Manager

Use the package URL or search for the SwiftUI-Shimmer package: https://github.com/markiv/SwiftUI-Shimmer.

For how-to integrate package dependencies refer to Adding Package Dependencies to Your App documentation.

Cocoapods

Add this to your Podfile:

pod 'SwiftUI-Shimmer', :git => 'https://github.com/markiv/SwiftUI-Shimmer.git'

What About UIKit?

For an older, UIKit-based shimmer effect, see UIView-Shimmer.

swiftui-shimmer's People

Contributors

ast3150 avatar markiv avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

swiftui-shimmer's Issues

High CPU load even if hidden

Hi. If I have a view like this:

	@ViewBuilder var listView: some View {
		if isLoading {
			skeletonView.shimmer()
		} else {
			listView
		}
	}

Then even if isLoading is false is still consumes CPU. The more cells the more consumption. I have about 36% on my iPhone 11 even if there's no shimmering view on screen. If remove shimmering then CPU load is 0%.

View moves downwards when applying basic shimmer

I noticed since the last update that using .shimmering() on a view will cause it to move.

This is the code using .shimmering:

Text("Test shimmer")
    .shimmering()

The result:

Screen.Recording.2023-08-30.at.11.29.55.mov

When using 1.3.0 the view stays in place and behaves as expected.

This is using Xcode 14.3 with iPhone 14 Pro (16.4) simulator

Animation bug

When I launch my application for the first time the animation is not applied only to the redacted view but to the whole view:

This is my code:

ScrollView {
                    TodayFeaturedRecipesView()
                        .environmentObject(viewModel)
                        .tag(0)
                    
                    TodayStatisticsView()
                        .environmentObject(viewModel)
                        .padding(.top)
                    
                    if !(accManager.user?.isPremium ?? false) {
                        TodayFreeRecipesView()
                            .environmentObject(viewModel)
                        ExplorePremiumBannerView()
                            .redacted(reason: viewModel.isLoading ? .placeholder : [])
                            .shimmering(active: viewModel.isLoading, gradient: colorScheme == .dark ? K.Gradients.lightShimmeringGradient : K.Gradients.darkShimmeringGradient)
                    }
                }

image

image

I cannot run M1

it runs with Rosseta but it doesn't run without Rosseta. Xcode version 14.3.1
Screenshot 2023-08-26 at 5 48 41 PM

Animation sometimes stops after one iteration.

I have no idea why, but the shimmer animation often stops for me after a single pass. This is using the default .shimmering() modifier, so it should repeat forever.

Oddly, sometimes it does seem to work properly. It may have to do with refreshes of the view somehow interrupting the animation.

Any thoughts as to what might cause the animation to stop?

Not working anymore on iOS 17 + memory leak

On iOS 17.0.3 seems that a SwiftUI component using shimmering(active:) leaks memory if active status doesn't change to false. In addition animation doesn't work anymore.

Here's behaviors on:

  • iOS 16.6.1

  • iOS 17.0.3

iOS 17 Memory Spike

It appears this has been reported a few times. But, there hasn't been a corresponding code change to resolve this. Any idea what might be happening?
#15
#16

Conditional ViewModifier issue

Hello. Thank you for a great code sample.

I found that it uses a conditional view modifier which is an incorrect implementation in SwiftUI and causes hard-to-track bugs.
The antipattern described in more details here: https://www.objc.io/blog/2021/08/24/conditional-view-modifiers/

Unfortunately, I don't have a possibility to open a PR with a fix, but I can provide suggestions.
Instead of returning modified view if the active argument is true we should pass that argument down to the ShimmerView and compute the duration of the animation based on that argument:

AnimatedMask(
    isActive: isActive,
    phase: phase
).animation(
    .linear(duration: isActive ? duration : 0) // FW: This is a correct way to stop animation. If using `isActive ? .linear(...) : .none` instead then the animation would be choppy. https://stackoverflow.com/questions/61830571/whats-causing-swiftui-nested-view-items-jumpy-animation-after-the-initial-drawi/61841018#61841018
    .repeatForever(autoreverses: bounce)
)

We will also need to retrigger the animation if view didn't reappear but the isActive property flipped from false to true

.onChange(of: isActive) { isActive in
    if isActive {
        phase = 0.8
    } else {
        phase = 0
    }
}

We should pass down the isActive argument down to the AnimatedMask modifier and down to the GradientMaskModifier so that we can compute edgeColor opacity and return 1 if isActive is false.
Let me know if you need more details.

Spikes CPU and leads to a crash on iOS 17

If you run the most basic example of this project on iOS 17, the CPU spikes and eventually leads to the application crashing. Perhaps this is because under the hood it is using AnimatableModifier, which is now deprecated.

struct ContentView: View {
    var body: some View {
        Text("Testing")
            .shimmering()
    }
}
Screenshot 2023-09-26 at 8 29 07 AM

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.