Menu

Animation

Skip support for SwiftUI.Animation.

The following example screens and source code is from SkipUI’s Showcase sample app AnimationPlayground.swift

import SwiftUI

struct AnimationPlayground: View {
    @State var isOn = false
    @State var unrelatedIsOn = false
    @State var isRepeatOn = false

    var body: some View {
        ScrollView {
            VStack(spacing: 16) {
                HStack {
                    Text(".opacity")
                    Spacer()
                    Color.red
                        .frame(width: 100, height: 100)
                        .opacity(isOn ? 0.2 : 1.0)
                        .onTapGesture {
                            isOn = !isOn
                        }
                }
                HStack {
                    Text(".opacity.animation")
                    Spacer()
                    Color.red
                        .frame(width: 100, height: 100)
                        .opacity(isOn ? 0.2 : 1.0)
                        .animation(.default, value: isOn)
                        .onTapGesture {
                            isOn = !isOn
                        }
                }
                HStack {
                    Text(".opacity.animation\n(different value)")
                    Spacer()
                    Color.red
                        .frame(width: 100, height: 100)
                        .opacity(isOn || unrelatedIsOn ? 0.2 : 1.0)
                        .animation(.default, value: isOn)
                        .onTapGesture {
                            unrelatedIsOn = !unrelatedIsOn
                        }
                }
                Button("withAnimation") {
                    withAnimation { isOn = !isOn }
                }
                .buttonStyle(.bordered)
                HStack {
                    Text(".foreground/.background")
                    Spacer()
                    Text("Text")
                        .font(.largeTitle)
                        .bold()
                        .frame(width: 100, height: 100)
                        .foregroundStyle(isOn ? Color.white : Color.black)
                        .background(isOn ? Color.black : Color.white)
                        .border(Color.blue)
                        .onTapGesture {
                            isOn = !isOn
                        }
                }
                HStack {
                    Text(".foreground/.background.animation")
                    Spacer()
                    Text("Text")
                        .font(.largeTitle)
                        .bold()
                        .frame(width: 100, height: 100)
                        .foregroundStyle(isOn ? Color.white : Color.black)
                        .background(isOn ? Color.black : Color.white)
                        .border(Color.blue)
                        .animation(.default, value: isOn)
                        .onTapGesture {
                            isOn = !isOn
                        }
                }
                Button("withAnimation") {
                    withAnimation { isOn = !isOn }
                }
                .buttonStyle(.bordered)
                HStack {
                    Text(".fill")
                    Spacer()
                    Circle()
                        .fill(isOn ? Color.blue : Color.red)
                        .frame(width: 100, height: 100)
                        .onTapGesture {
                            isOn = !isOn
                        }
                }
                HStack {
                    Text(".fill.animation")
                    Spacer()
                    Circle()
                        .fill(isOn ? Color.blue : Color.red)
                        .frame(width: 100, height: 100)
                        .animation(.default, value: isOn)
                        .onTapGesture {
                            isOn = !isOn
                        }
                }
                Button("withAnimation") {
                    withAnimation { isOn = !isOn }
                }
                .buttonStyle(.bordered)
                HStack {
                    Text(".offset")
                    Spacer()
                    ZStack {
                        Color.red
                            .frame(width: 20, height: 20)
                            .offset(isOn ? CGSize(width: 50, height: 10) : CGSize(width: 0, height: 0))
                    }
                    .frame(width: 100, height: 100)
                    .background(.gray)
                    .onTapGesture {
                        isOn = !isOn
                    }
                }
                HStack {
                    Text(".offset.animation")
                    Spacer()
                    ZStack {
                        Color.red
                            .frame(width: 20, height: 20)
                            .offset(isOn ? CGSize(width: 50, height: 10) : CGSize(width: 0, height: 0))
                            .animation(.default, value: isOn)
                    }
                    .frame(width: 100, height: 100)
                    .background(.gray)
                    .onTapGesture {
                        isOn = !isOn
                    }
                }
                Button("withAnimation") {
                    withAnimation { isOn = !isOn }
                }
                .buttonStyle(.bordered)
                HStack {
                    Text(".frame")
                    Spacer()
                    ZStack {
                        Color.red
                            .frame(width: isOn ? 100.0 : 40.0, height: isOn ? 60.0 : 40.0)
                    }
                    .frame(width: 100, height: 100)
                    .background(.gray)
                    .onTapGesture {
                        isOn = !isOn
                    }
                }
                HStack {
                    Text(".frame.animation")
                    Spacer()
                    ZStack {
                        Color.red
                            .frame(width: isOn ? 100.0 : 40.0, height: isOn ? 60.0 : 40.0)
                            .animation(.default, value: isOn)
                    }
                    .frame(width: 100, height: 100)
                    .background(.gray)
                    .onTapGesture {
                        isOn = !isOn
                    }
                }
                Button("withAnimation") {
                    withAnimation { isOn = !isOn }
                }
                .buttonStyle(.bordered)
                HStack {
                    Text(".rotationEffect")
                    Spacer()
                    Color.red
                        .frame(width: 100, height: 100)
                        .rotationEffect(isOn ? .degrees(45) : .degrees(0))
                        .onTapGesture {
                            isOn = !isOn
                        }
                }
                HStack {
                    Text(".rotationEffect.animation")
                    Spacer()
                    Color.red
                        .frame(width: 100, height: 100)
                        .rotationEffect(isOn ? .degrees(45) : .degrees(0))
                        .animation(.default, value: isOn)
                        .onTapGesture {
                            isOn = !isOn
                        }
                }
                Button("withAnimation") {
                    withAnimation { isOn = !isOn }
                }
                .buttonStyle(.bordered)
                HStack {
                    Text(".scaleEffect")
                    Spacer()
                    Color.red
                        .frame(width: 100, height: 100)
                        .scaleEffect(isOn ? 0.5 : 1.0)
                        .onTapGesture {
                            isOn = !isOn
                        }
                }
                HStack {
                    Text(".scaleEffect.animation")
                    Spacer()
                    Color.red
                        .frame(width: 100, height: 100)
                        .scaleEffect(isOn ? 0.5 : 1.0)
                        .animation(.default, value: isOn)
                        .onTapGesture {
                            isOn = !isOn
                        }
                }
                Button("withAnimation") {
                    withAnimation { isOn = !isOn }
                }
                .buttonStyle(.bordered)
                HStack {
                    Text(".font")
                    Spacer()
                    Text("Hello")
                        .font(.system(size: isOn ? 30.0 : 20.0))
                        .frame(width: 100, height: 100)
                        .border(Color.blue)
                        .onTapGesture {
                            isOn = !isOn
                        }
                }
                HStack {
                    Text(".font.animation")
                    Spacer()
                    Text("Hello")
                        .font(.system(size: isOn ? 30.0 : 20.0))
                        .frame(width: 100, height: 100)
                        .border(Color.blue)
                        .animation(.default, value: isOn)
                        .onTapGesture {
                            isOn = !isOn
                        }
                }
                Button("withAnimation") {
                    withAnimation { isOn = !isOn }
                }
                .buttonStyle(.bordered)
                HStack {
                    Text(".animation(.spring)")
                    Spacer()
                    ZStack {
                        Color.red
                            .frame(width: 20, height: 20)
                            .offset(isOn ? CGSize(width: 0, height: 50) : CGSize(width: 0, height: -50))
                            .animation(.spring, value: isOn)
                    }
                    .frame(width: 100, height: 100)
                    .background(.gray)
                    .onTapGesture {
                        isOn = !isOn
                    }
                }
                HStack {
                    Text("withAnimation(.spring)")
                    Spacer()
                    ZStack {
                        Color.red
                            .frame(width: 20, height: 20)
                            .offset(isOn ? CGSize(width: 0, height: 50) : CGSize(width: 0, height: -50))
                    }
                    .frame(width: 100, height: 100)
                    .background(.gray)
                    .onTapGesture {
                        withAnimation(.spring) { isOn = !isOn }
                    }
                }
                HStack {
                    Text(".animation(.easeIn(duration: 1))")
                    Spacer()
                    ZStack {
                        Color.red
                            .frame(width: 20, height: 20)
                            .offset(isOn ? CGSize(width: 0, height: 50) : CGSize(width: 0, height: -50))
                            .animation(.easeIn(duration: 1), value: isOn)
                    }
                    .frame(width: 100, height: 100)
                    .background(.gray)
                    .onTapGesture {
                        isOn = !isOn
                    }
                }
                HStack {
                    Text("withAnimation(.easeIn(duration: 1))")
                    Spacer()
                    ZStack {
                        Color.red
                            .frame(width: 20, height: 20)
                            .offset(isOn ? CGSize(width: 0, height: 50) : CGSize(width: 0, height: -50))
                    }
                    .frame(width: 100, height: 100)
                    .background(.gray)
                    .onTapGesture {
                        withAnimation(.easeIn(duration: 1)) { isOn = !isOn }
                    }
                }
                HStack {
                    Text(".animation(repeatCount(3))")
                    Spacer()
                    ZStack {
                        Color.red
                            .frame(width: 20, height: 20)
                            .offset(isOn ? CGSize(width: 0, height: 50) : CGSize(width: 0, height: -50))
                            .animation(.default.repeatCount(3), value: isOn)
                    }
                    .frame(width: 100, height: 100)
                    .background(.gray)
                    .onTapGesture {
                        isOn = !isOn
                    }
                }
                HStack {
                    Text("withAnimation(repeatCount(3))")
                    Spacer()
                    ZStack {
                        Color.red
                            .frame(width: 20, height: 20)
                            .offset(isOn ? CGSize(width: 0, height: 50) : CGSize(width: 0, height: -50))
                    }
                    .frame(width: 100, height: 100)
                    .background(.gray)
                    .onTapGesture {
                        withAnimation(.default.repeatCount(3)) { isOn = !isOn }
                    }
                }
                HStack {
                    Text(".animation(autoreverses: false))")
                    Spacer()
                    ZStack {
                        Color.red
                            .frame(width: 20, height: 20)
                            .offset(isOn ? CGSize(width: 0, height: 50) : CGSize(width: 0, height: -50))
                            .animation(.default.repeatCount(3, autoreverses: false), value: isOn)
                    }
                    .frame(width: 100, height: 100)
                    .background(.gray)
                    .onTapGesture {
                        isOn = !isOn
                    }
                }
                HStack {
                    Text(".repeatForever()")
                    Spacer()
                    ZStack {
                        Color.red
                            .frame(width: 20, height: 20)
                            .offset(isRepeatOn ? CGSize(width: 0, height: 50) : CGSize(width: 0, height: -50))
                            .animation(.default.repeatForever(), value: isRepeatOn)
                    }
                    .frame(width: 100, height: 100)
                    .background(.gray)
                    .onAppear {
                        isRepeatOn = true
                    }
                    .onTapGesture {
                        isOn = !isOn
                    }
                }
                NavigationLink("Push") {
                    Text("Pushed")
                }
                .buttonStyle(.bordered)
            }
            .padding()
        }
        .toolbar {
            PlaygroundSourceLink(file: "AnimationPlayground.swift")
        }
    }
}