Skip to content

Instantly share code, notes, and snippets.

@mattyoung
Last active June 13, 2024 03:35
Show Gist options
  • Save mattyoung/6efbdf2c93f2265b365c0ae5a40fd848 to your computer and use it in GitHub Desktop.
Save mattyoung/6efbdf2c93f2265b365c0ae5a40fd848 to your computer and use it in GitHub Desktop.
//
// DelayAppearance.swift
// VariableSFSymbolAnimation
//
// Created by Matthew Young on 12/29/22.
//
// About animation transaction:
// https://swiftwithmajid.com/2020/10/07/transactions-in-swiftui/
import SwiftUI
struct DelayAppearanceModifier: ViewModifier {
@State var shouldDisplay = false
let delay: Double
let transition: AnyTransition
func body(content: Content) -> some View {
render(content)
// we want to allow transition, so we have to attach aninamtion and transition here
// To disable this, use .transaction modifier after this modifier to override this
.animation(.spring(), value: shouldDisplay)
.transition(transition)
.task {
try? await Task.sleep(nanoseconds: .init(delay * 1000_000_000))
shouldDisplay = true
}
}
@ViewBuilder
private func render(_ content: Content) -> some View {
if shouldDisplay {
content
} else {
content
.hidden()
}
}
}
public extension View {
/// Delay the appearance of this view
/// - Parameters:
/// - seconds: by how may seconds
/// - transition: what transition effect to use on appearance
/// - Returns: the modifiere view
func delayAppearance(bySeconds seconds: Double, transition: AnyTransition = .slide) -> some View {
modifier(DelayAppearanceModifier(delay: seconds, transition: transition))
}
}
struct DelayAppearanceDemo: View {
var body: some View {
VStack {
HStack {
Circle()
.delayAppearance(bySeconds: 0)
Circle()
.delayAppearance(bySeconds: 1)
Circle()
.delayAppearance(bySeconds: 2)
Circle()
.delayAppearance(bySeconds: 3)
Circle()
.delayAppearance(bySeconds: 4)
}
HStack {
Circle()
// attach another .transaction to re-enable animation here
.delayAppearance(bySeconds: 0)
// disable any animation and transition
.transaction { transaction in
transaction.disablesAnimations = true
}
Circle()
.delayAppearance(bySeconds: 1)
.transaction { transaction in
transaction.disablesAnimations = true
}
Circle()
.delayAppearance(bySeconds: 2)
.transaction { transaction in
transaction.disablesAnimations = true
}
Circle()
.delayAppearance(bySeconds: 3)
.transaction { transaction in
transaction.disablesAnimations = true
}
Circle()
.delayAppearance(bySeconds: 4)
.transaction { transaction in
transaction.disablesAnimations = true
}
}
}
}
}
struct DelayAppearanceDemo_Previews: PreviewProvider {
static var previews: some View {
DelayAppearanceDemo()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment