# Animated Loading Button in SwiftUI

> Pattern for building a multi-state morphing button in SwiftUI

A concise guide for creating a state-driven iOS button that animates between normal, loading, and success states. It demonstrates how to transition button dimensions, corner radius, and inner content using standard SwiftUI primitives and spring animations. It is a practical reference for polished form submissions and async actions.

## How it works

Build an animated loading button in SwiftUI in 3 steps.

Step 1 — States & structure: define an enum ButtonState { normal, loading, success }; the view is AnimatedLoadingButton: View with title, action, @Binding var state, @State isAnimating, configurable colors (normal .blue, loading .orange, success .green), width 200 / height 50, and .disabled(state != .normal).

Step 2 — Shape transformation & colors: ZStack with RoundedRectangle whose cornerRadius is height/2 (circle) when loading, else 10; width morphs to height when loading. Foreground color switches per state. Group content animates with .animation(.spring(response: 0.3, dampingFraction: 0.7), value: state).

Step 3 — State-specific content: normal shows Text(title) semibold white with .opacity transition; loading shows a Circle().trim(0, 0.7).stroke(white, lineWidth 2) spinner rotating 360° with linear(1s).repeatForever; success shows Image(systemName: "checkmark") bold white with .scale.combined(with: .opacity) transition.

Full code: gist.github.com/maleem88/640f1be662d0edcc99363c1f438bb813

## What it is for

- Provide clear visual feedback during asynchronous API requests
- Morph standard buttons into loading spinners without layout shifts
- Display inline success confirmations upon form completion

## Key points

- ButtonState enum managing normal, loading, and success states
- Dynamic width and corner-radius morphing using spring animations
- Continuous rotating trim spinner for the loading state
- Scale and opacity transitions for success icons and labels
- Automatic interaction disabling while not in normal state

## Pricing

Free

## Details

- Type: Tip
- Category: [Development](https://xiry.app/topics/development.md)
- Topic: [UI Components](https://xiry.app/topics/development/ui-components.md)
- Open source: yes
- Platforms: iOS, macOS
- For: iOS and SwiftUI developers
- Tags: swiftui, ios, animation, swift, ui, mobile

## Why it was saved

- [@maleeem88, 15 March 2025](https://x.com/maleeem88/status/1901009594425495574): Reusable pattern for building state-driven animated buttons in iOS apps.

## Related

- [shadcn/ui](https://xiry.app/resources/shadcn-ui-1902): Copy-paste React UI components built with Tailwind CSS and Radix primitives. (Website, Open source)
- [Efferd](https://xiry.app/resources/efferd): Pre-built, responsive shadcn/ui blocks and layouts for React applications (Web app, Freemium)
- [Motion](https://xiry.app/resources/motion): Open-source animation library for React, Vue, and vanilla JavaScript (Website, Freemium)
- [React Bits](https://xiry.app/resources/react-bits): Open-source animated and interactive React UI components and backgrounds (Website, Freemium)
- [21st.dev](https://xiry.app/resources/21st-dev): Curated directory of crafted React, Tailwind, and shadcn UI components. (Website, Freemium)
- [lucide-animated](https://xiry.app/resources/lucide-animated): Open-source animated React icons built with Lucide and Motion (Web app, Open source)

Updated 11 October 2026. Page: https://xiry.app/resources/animated-loading-button-in-swiftui

Make your own library: Xiry takes your saved reels, tweets, Reddit bookmarks and Watch Later videos, makes them searchable and pulls the useful stuff out, like this library. It's invite-only for now; join the waitlist at https://xiry.app/#waitlist.
