i-swift

Master the Art of Swift Programming

Mastering Animations in SwiftUI: Build Smooth and Engaging UIs

Animations can transform a mundane interface into a delightful and engaging experience. With SwiftUI, creating visually stunning animations is easier than ever.

In this article, we’ll create an elegant scaling and fading animation using SwiftUI. This animation brings your UI to life with minimal effort and maximum impact.

1. What Makes SwiftUI Animations Unique?

SwiftUI animations are declarative, intuitive, and flexible. With just a few lines of code, you can create:

  • Implicit Animations: Automatically animated state changes.
  • Explicit Animations: Defined animations using withAnimation blocks.
  • Custom Transitions: Animate views entering or exiting the screen.

2. Creating a Stunning Scaling and Fading Animation

Here’s what we’re building:

circle that scales and fades in/out with a beautiful spring animation when tapped.

Set Up Your SwiftUI View

Let’s start with a clean and organized SwiftUI view.

import SwiftUI

struct SmoothAnimationView: View {
    // MARK: - Properties
    @State private var isAnimated = false

    // MARK: - Body
    var body: some View {
        VStack {
            Spacer()
            
            AnimatedCircle(isAnimated: $isAnimated)
            
            Spacer()
            
            AnimateButton(isAnimated: $isAnimated)
        }
        .padding()
        .background(LinearGradient(colors: [Color.blue.opacity(0.2), Color.purple.opacity(0.1)],
                                   startPoint: .topLeading,
                                   endPoint: .bottomTrailing))
        .ignoresSafeArea()
    }
}

struct SmoothAnimationView_Previews: PreviewProvider {
    static var previews: some View {
        SmoothAnimationView()
    }
}
Swift

Build the Animated Circle

Extract the circle into a reusable component for better code organization.

struct AnimatedCircle: View {
    // MARK: - Properties
    @Binding var isAnimated: Bool

    // MARK: - Body
    var body: some View {
        Circle()
            .fill(
                LinearGradient(colors: [Color.purple, Color.blue],
                               startPoint: .top,
                               endPoint: .bottom)
            )
            .frame(width: isAnimated ? 200 : 100, height: isAnimated ? 200 : 100)
            .opacity(isAnimated ? 1.0 : 0.3)
            .scaleEffect(isAnimated ? 1.2 : 0.8)
            .shadow(color: .blue.opacity(0.5), radius: isAnimated ? 20 : 5)
            .animation(.spring(response: 0.6, dampingFraction: 0.5), value: isAnimated)
    }
}
Swift

Add an Interactive Button

The button toggles the animation state with a satisfying click.

struct AnimateButton: View {
    // MARK: - Properties
    @Binding var isAnimated: Bool

    // MARK: - Body
    var body: some View {
        Button(action: {
            withAnimation {
                isAnimated.toggle()
            }
        }) {
            Text(isAnimated ? "Reset Animation" : "Start Animation")
                .font(.headline)
                .foregroundColor(.white)
                .padding()
                .frame(maxWidth: .infinity)
                .background(
                    LinearGradient(colors: [Color.blue, Color.purple],
                                   startPoint: .leading,
                                   endPoint: .trailing)
                )
                .cornerRadius(12)
                .shadow(color: .blue.opacity(0.3), radius: 10, x: 5, y: 5)
        }
        .padding(.horizontal)
    }
}
Swift

3. Why This Design Works

This implementation focuses on:

  1. Reusability: By splitting the circle and button into separate views, you can reuse and adapt them easily.
  2. Visual Appeal: Gradients, shadows, and smooth transitions make the animation eye-catching.
  3. Simplicity: The declarative approach in SwiftUI keeps the code clean and readable.

Running the Code

When you tap the button:

  • The circle scales up, fades in, and casts a glowing shadow.
  • Tapping the button again reverses the animation.

You’ll notice the spring effect adds a natural bounce to the motion.


4. Enhancements to Try

1. Customize the Timing Curve:

Replace .spring with .easeInOut for a more elegant effect:

.animation(.easeInOut(duration: 1.0), value: isAnimated)
Swift

2. Add Dynamic Colors:

Use ColorPicker to let users customize the gradient.

3. Combine Animations:

Layer multiple animations for more complex effects:

.rotationEffect(.degrees(isAnimated ? 360 : 0))
Swift

Final Result

Here’s what the final animation looks like:

Leave a Reply

Your email address will not be published. Required fields are marked *

Quick contact info

© 2024 i-Swift. All rights reserved
Your go-to source for Swift tutorials, tips, and insights. Empowering developers with expert content since 2024.