Swift Animations for Flutter - Complete Guide to Declarative Animations
Learn how to create SwiftUI-like declarative animations in Flutter with zero boilerplate. No controllers, no ticker providers required!
Introduction
Creating smooth, beautiful animations in Flutter has traditionally required setting up controllers, managing ticker providers, and writing boilerplate code. But what if you could create animations as easily as in SwiftUI?
Swift Animations is a Flutter package that brings SwiftUI-like declarative animations to Flutter. With zero boilerplate and no mixins required, you can create stunning animations with simple, chainable methods.
Quick start (drop-in example)
import 'package:flutter/material.dart';
import 'package:swift_animations/swift_animations.dart';
class Demo extends StatelessWidget {
const Demo({super.key});
@override
Widget build(BuildContext context) {
return Center(
child: Container(width: 120, height: 120, color: Colors.blue)
.animate()
.fadeIn()
.scale(1.2)
.springIOS(), // smooth spring preset
);
}
}
Tip: Keep animations to <300ms for list items; use
.springGentle()for UI polish without jank.
Why Swift Animations?
Traditional Flutter Animation Approach
class MyAnimatedWidget extends StatefulWidget {
@override
_MyAnimatedWidgetState createState() => _MyAnimatedWidgetState();
}
class _MyAnimatedWidgetState extends State<MyAnimatedWidget>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _animation;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: Duration(milliseconds: 500),
vsync: this,
);
_animation = Tween<double>(begin: 0.0, end: 1.0).animate(_controller);
_controller.forward();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return FadeTransition(
opacity: _animation,
child: Container(
width: 100,
height: 100,
color: Colors.blue,
),
);
}
}
That’s a lot of code for a simple fade-in animation!
Swift Animations Approach
Container(
width: 100,
height: 100,
color: Colors.blue,
)
.animate()
.fadeIn()
.scale(1.2)
.duration(500.ms)
That’s it! No controllers, no mixins, no boilerplate.
Installation
Add swift_animations to your pubspec.yaml:
dependencies:
swift_animations: ^1.2.2
Then run:
flutter pub get
Core Features
Transformations
Scale Animations
Container(
width: 100,
height: 100,
color: Colors.blue,
)
.animate()
.scale(1.5) // Scale to 150%
You can also scale on specific axes:
.animate()
.scaleX(1.2) // Scale only on X axis
.scaleY(0.8) // Scale only on Y axis
Rotation
.animate()
.rotate(180) // Rotate 180 degrees
Opacity Animations
// Fade in from 0 to 1
.animate()
.fadeIn()
// Fade out from 1 to 0
.animate()
.fadeOut()
// Custom opacity
.animate()
.opacity(0.5) // 50% opacity
Slide Animations
// Slide in from different directions
.animate()
.slideInTop()
.slideInBottom()
.slideInLeft()
.slideInRight()
// Custom slide values
.animate()
.slideX(100) // Slide 100 pixels on X axis
.slideY(-50) // Slide -50 pixels on Y axis
Special Effects
Bounce Animation
Container(
width: 100,
height: 100,
color: Colors.purple,
)
.animate()
.fadeIn()
.scale(1.2)
.bounce() // Adds bounce effect
Pulse Animation
.animate()
.fadeIn()
.pulse() // Creates pulsing effect
Combined Effects
.animate()
.fadeInScale(1.3) // Fade in + scale simultaneously
Spring Physics
One of the most powerful features is spring physics, which creates natural, iOS-like animations.
Pre-configured Springs
// iOS-style snappy spring
.animate()
.fadeIn()
.springIOS()
// Gentle spring with smooth bounce
.animate()
.fadeIn()
.springGentle()
// Bouncy spring with high bounce
.animate()
.fadeIn()
.springBouncy()
Custom Spring
.animate()
.fadeIn()
.spring(
mass: 1.0, // Mass of the spring
stiffness: 100.0, // Stiffness coefficient
damping: 10.0, // Damping coefficient
initialVelocity: 0.0 // Initial velocity
)
Duration and Timing
Duration Shorthand
Swift Animations provides convenient duration syntax:
.animate()
.duration(500.ms) // 500 milliseconds
.duration(0.5.s) // 0.5 seconds
.duration(5.m) // 5 minutes
.duration(".500ms") // String format
Delay
.animate()
.fadeIn()
.delay(200.ms) // Wait 200ms before starting
Custom Curves
.animate()
.fadeIn()
.curve(Curves.easeInOut)
.curve(Curves.bounceOut)
Advanced Patterns
Repeating Animations
// Infinite repeat
.animate()
.fadeIn()
.scale(1.2)
.repeat(reverse: true) // Reverse on each cycle
// Repeat specific number of times
.animate()
.fadeIn()
.repeatCount(3, reverse: true) // Repeat 3 times
Complex Animation Chain
Container(
width: 120,
height: 120,
decoration: BoxDecoration(
color: Colors.purple,
borderRadius: BorderRadius.circular(20),
),
)
.animate()
.fadeIn()
.scale(1.2)
.slideInBottom()
.rotate(180)
.duration(1.5.s)
.curve(Curves.easeInOut)
.repeat(reverse: true)
Gesture Extensions
Liquid Tap Effects
The sGestureDetector extension adds beautiful liquid tap effects with spring physics:
Container(
width: 100,
height: 100,
color: Colors.blue,
)
.sGestureDetector(
onPressed: () => print('Tapped'),
onLongPress: () => print('Long pressed'),
scaleOnPress: 1.1, // Scale amount on tap
longPressDuration: 500.ms,
)
Configuration Options
.sGestureDetector(
onPressed: () {},
scaleOnPress: 1.15, // Custom scale
autoScaleBySize: true, // Auto-scale based on widget size
stretchSensitivity: 0.5, // Stretch effect sensitivity
translateSensitivity: 0.3, // Translation sensitivity
)
Navigation Animations
Swift Animations also provides platform-specific navigation animations:
iOS-Style Navigation
swift.push(NextPage())
.ios()
.duration(500)
.curve(Curves.easeInOut)
.go(context);
Android-Style Navigation
swift.push(NextPage())
.android()
.duration(500)
.curve(Curves.easeInOut)
.go(context);
Push Replacement
swift.pushReplacement(HomePage())
.ios()
.duration(300)
.go(context);
Push Named Route
swift.pushNamed('/details')
.android()
.duration(400)
.go(context, arguments: {'id': 123});
Real-World Examples
Loading Indicator
CircularProgressIndicator()
.animate()
.fadeIn()
.rotate(360)
.repeat(reverse: false)
.duration(1.s)
Card Entrance Animation
Card(
child: ListTile(
title: Text('Item'),
),
)
.animate()
.fadeIn()
.slideInRight()
.duration(300.ms)
.delay((index * 50).ms) // Staggered animation
Button Press Animation
ElevatedButton(
onPressed: () {},
child: Text('Press Me'),
)
.sGestureDetector(
onPressed: () {
// Handle button press
},
scaleOnPress: 0.95,
)
Best Practices
- Use Spring Physics for Natural Feel: Spring animations feel more natural than linear animations
- Stagger List Animations: Add delays to create cascading effects
- Keep Durations Short: 200-500ms is usually optimal for UI animations
- Use Appropriate Curves: Match animation curves to the action (e.g.,
easeOutfor entrances) - Test on Real Devices: Animation performance can vary between devices
Common Issues and Solutions
Animation Not Starting
Problem: Animation doesn’t play when widget appears.
Solution: Ensure the widget is visible when animation should start. Swift Animations automatically detects visibility.
Performance Issues
Problem: Animations are laggy.
Solution:
- Avoid animating too many widgets simultaneously
- Use
persist()if widget rebuilds frequently - Consider using
RepaintBoundaryfor complex widgets
Animation Not Reversing
Problem: repeat(reverse: true) doesn’t reverse.
Solution: Ensure you’re using the correct syntax and that the animation has completed its forward cycle.
Conclusion
Swift Animations brings the simplicity and elegance of SwiftUI animations to Flutter. With zero boilerplate and a clean, chainable API, you can create beautiful animations that enhance your app’s user experience.
Key takeaways:
- ✅ No controllers or mixins required
- ✅ Clean, declarative API
- ✅ Spring physics for natural animations
- ✅ Platform-specific navigation animations
- ✅ Gesture extensions for interactive effects
Start using Swift Animations in your next Flutter project and experience the difference!
Resources
Happy Animating! ✨
📚 Recommended Resources
Hardware & Equipment
* Some links are affiliate links. This helps support the blog at no extra cost to you.
Explore More
Quick Links
Related Posts
Flutter Screen Launch by Notification - Deep Linking & Navigation Guide
Learn how to detect notification launches, handle deep links, and route directly to specific screens in Flutter apps. Skip splash screens when launched from notifications!
January 20, 2025
Adaptive Micro Factory Model Analysis: Flexible Manufacturing for Automotive (2024-2030)
A complete guide to adaptive micro factory economics, architecture, ROI, use-cases, and deployment models for automotive manufacturers.
February 20, 2025
AMR Deployment Cost Breakdown for Automotive Plants: ROI Analysis & Implementation Guide (2025)
Complete cost breakdown for AMR deployment in automotive manufacturing. Hardware, software, integration, ROI analysis, payback period, fleet cost, and benchmarks. Includes real case studies and implementation timelines.
February 20, 2025
Automation CAPEX vs OPEX in Automotive: Complete Financial Analysis & Decision Framework
Complete financial guide for automotive CAPEX vs OPEX automation models, including ROI analysis, cost-per-unit comparison, case studies, and decision framework.
February 20, 2025