Now Open Source by Emerge Tools

Transitions for your iOS app

SwiftUI transitions that make your app shine

Pow is free and Open Source.
Line Hole
Timing curve Comment star like

Now Open Source by Emerge Tools

Transitions for your iOS app

SwiftUI transitions that make your app shine

Pow is free and Open Source.
Shopping cart button Emoji picker
Rays
Line Hole
Timing curve Comment star like

Now Open Source by Emerge Tools

Transitions for your iOS app

SwiftUI transitions that make your app shine

Pow is free and Open Source.
Shopping cart button Emoji picker
Rays

Instant Delight

Pow is a collection of SwiftUI transitions that add that little bit of extra delight to your iOS app.

Adding a Pow Transition to your SwiftUI app often only takes a single line of code.

Fully Native

Pow leverages the powerful SwiftUI Transition API to deliver smooth animations and seamlessly integrates with system frameworks.

Expertly Crafted

Pow is made by a team of highly experienced designers and developers.

Whether you are starting a new project or adding to an existing app, Pow is here to make your app look the best it can.

A transition that drops the view down from the top.

The transition is only performed on insertion and takes 1.4 seconds.

												
import SwiftUI import Pow

struct PriceSlide: View {<#•••#>
@State var isPriceRevealed = false
var body: some View {<#•••#>
ZStack { LinearGradient( colors: [.black, Color(red: 0.45, green: 0.45, blue: 0.52)], startPoint: .top, endPoint: .bottom )
if isPriceRevealed { Text("$499") .transition( .identity .animation(.linear(duration: 1).delay(2)) .combined( with: .movingParts.anvil ) ) } else {<#•••#>
Text("$999") .transition( .asymmetric( insertion: .identity, removal: .opacity.animation(.easeOut(duration: 0.2))) ) } }<#•••#>
.font(.largeTitle.bold()) .foregroundColor(.white) .contentShape(Rectangle()) .onTapGesture { withAnimation { isPriceRevealed.toggle() } }
} }

A transition that reveals the view as if it was behind window blinds.

												
import SwiftUI import Pow

struct Example: View {<#•••#>
@State var isAdded = false
var body: some View { ZStack {<#•••#>
Color.clear
if isAdded { HelloView() .transition( .movingParts.blinds(slatWidth: 25) ) } }<#•••#>
.contentShape(Rectangle()) .onTapGesture { withAnimation { isAdded.toggle() } }
} }

A transition from blurry to sharp on insertion, and from sharp to blurry on removal.

												
import SwiftUI import Pow

struct Example: View {<#•••#>
@State var isAdded = false
var body: some View { ZStack {<#•••#>
Color.clear
if isAdded { HelloView() .transition(.movingParts.blur) } }<#•••#>
.contentShape(Rectangle()) .onTapGesture { withAnimation { isAdded.toggle() } }
} }

A transition that moves the view down with any overshoot resulting in an elastic deformation of the view.

												
import SwiftUI import Pow

struct Example: View {<#•••#>
@State var isAdded = false
var body: some View { ZStack {<#•••#>
Color.clear
if isAdded { HelloView() .transition( .movingParts.boing .combined(with: .opacity) .animation( .interactiveSpring(dampingFraction: 0.5) ) ) } }<#•••#>
.contentShape(Rectangle()) .onTapGesture { withAnimation { isAdded.toggle() } }
} }

A transition using a clockwise sweep around the centerpoint of the view.

												
import SwiftUI import Pow

struct Example: View {<#•••#>
@State var isAdded = false
var body: some View { ZStack {<#•••#>
Color.clear
HelloBackgroundView()
if isAdded { HelloView() .transition(.movingParts.clock( blurRadius: 50 )) .zIndex(1) } }<#•••#>
.contentShape(Rectangle()) .onTapGesture { withAnimation(.spring(dampingFraction: 1)) { isAdded.toggle() } }
} }

A transition from completely dark to fully visible on insertion, and from fully visible to completely dark on removal.

												
import SwiftUI import Pow

struct Example: View {<#•••#>
@State var url: URL?
var body: some View { ZStack {<#•••#>
Color.clear
AsyncImage( url: url, transaction: .init(animation: .easeInOut(duration: 1.8)) ) { phase in ZStack {<#•••#>
Color.black
switch phase { case .success(let image): image .resizable() .aspectRatio(contentMode: .fit) .zIndex(1) .transition(.movingParts.filmExposure)<#•••#>
case .failure(let error): Text(error.localizedDescription) .font(.caption) case .empty: EmptyView() @unknown default: EmptyView() } }<#•••#>
.aspectRatio(contentMode: .fit)
}<#•••#>
.clipShape(RoundedRectangle(cornerRadius: 32, style: .continuous)) .frame(width: 250, height: 250)
}<#•••#>
.contentShape(Rectangle()) .onTapGesture { if url == nil { // Photo by [Andrew Ridley](https://unsplash.com/@aridley88) on [Unsplash](https://unsplash.com) url = URL(string: "https://picsum.photos/id/1018/500") } else { url = nil } }
} }

A transition that toggles the visibility of the view multiple times before settling.

												
import SwiftUI import Pow

struct Example: View {<#•••#>
@State var isAdded = false
var body: some View { ZStack {<#•••#>
Color.clear
if isAdded { HelloView() .transition( .movingParts.flicker(count: 3) ) } }<#•••#>
.contentShape(Rectangle()) .onTapGesture { withAnimation(.linear) { isAdded.toggle() } }
} }

A transition that inserts by rotating the view towards the viewer, and removes by rotating the view away from the viewer.

												
import SwiftUI import Pow

struct Example: View {<#•••#>
@State var isAdded = false
var body: some View { ZStack {<#•••#>
Color.clear
if isAdded { HelloView() .transition(.movingParts.flip) } }<#•••#>
.contentShape(Rectangle()) .onTapGesture { withAnimation(.interpolatingSpring(mass: 1, stiffness: 10, damping: 10, initialVelocity: 10)) { isAdded.toggle() } }
} }

A transitions that shows the view by combining a diagonal wipe with a white streak.

												
import SwiftUI import Pow

struct Example: View {<#•••#>
@State var isAdded = false
var body: some View { ZStack {<#•••#>
Color.clear
if isAdded { HelloView() .transition(.movingParts.glare) } }<#•••#>
.contentShape(Rectangle()) .onTapGesture { withAnimation { isAdded.toggle() } }
} }

An effect that highlights the view with a glow around it.

												
import SwiftUI import Pow

struct Example: View {<#•••#>
@State var canContinue = false
var body: some View { ZStack {<#•••#>
Color.clear
Button {<#•••#>
} label: { Text("Continue") .padding(.horizontal, 64) } .conditionalEffect( .repeat( .glow(color: .blue, radius: 50), every: 1.5 ), condition: canContinue )<#•••#>
.disabled(!canContinue) .animation(.default, value: canContinue) .font(.body.bold()) .buttonStyle(.borderedProminent) .buttonBorderShape(.capsule) .controlSize(.large)
} } }

A transition that takes the shape of a growing circle when inserting, and a shrinking circle when removing.

												
import SwiftUI import Pow

struct Example: View {<#•••#>
@State var isAdded = false
var body: some View { ZStack {<#•••#>
Color.clear
HelloBackgroundView()
if isAdded { HelloView() .transition(.movingParts.iris( blurRadius: 50 )) .zIndex(1) } }<#•••#>
.contentShape(Rectangle()) .onTapGesture { withAnimation(.spring(dampingFraction: 1)) { isAdded.toggle() } }
} }

An effect that makes the view jump.

												
import SwiftUI import Pow

struct Example: View {<#•••#>
@State var count = 0
var body: some View { ZStack {<#•••#>
Color.clear
HelloView() .overlay(alignment: .topTrailing) { NotificationBadge(count) } .changeEffect(.jump(height: 100), value: count) }<#•••#>
.contentShape(Rectangle()) .onTapGesture { count += 1 }
} }

A transition that moves the view from the specified edge of the on insertion and towards it on removal.

												
import SwiftUI import Pow

struct Example: View {<#•••#>
@State var isAdded = false
var body: some View { ZStack {<#•••#>
Color.clear
if isAdded { HelloView() .transition( .asymmetric( insertion: .movingParts.move( angle: .degrees(-45) ), removal: .movingParts.move( angle: .degrees(135) ) ).combined(with: .opacity) ) } }<#•••#>
.contentShape(Rectangle()) .onTapGesture { withAnimation { isAdded.toggle() } }
} }

A transition that removes the view in a dissolving cartoon style cloud.

												
import SwiftUI import Pow

struct Example: View {<#•••#>
@State var isAdded = false
var body: some View { ZStack {<#•••#>
Color.clear
if isAdded { HelloView() .transition(.movingParts.poof) } }<#•••#>
.contentShape(Rectangle()) .onTapGesture { withAnimation { isAdded.toggle() } }
} }

A transition that shows a view with a ripple effect and a flurry of tint-colored particles.

The transition is only performed on insertion and takes 1.2 seconds.

												
import SwiftUI import Pow

struct LikeButton: View {<#•••#>
@Binding var isFavorited = false
var favoriteCount: Int
var body: some View { Button {<#•••#>
withAnimation { isFavorited.toggle() } } label: { HStack { if isFavorited { Image(systemName: "heart.fill") .foregroundColor(.red) .transition( .movingParts.pop(.red) ) } else {<#•••#>
Image(systemName: "heart") .foregroundColor(.gray) .transition(.identity) }<#•••#>
Text(favoriteCount.formatted()) .foregroundColor(isFavorited ? .red : .gray) .animation(isFavorited ? .default.delay(0.4) : nil, value: isFavorited)
} } } }

An effect that adds one or more shapes that slowly grow and fade-out behind the view.

												
import SwiftUI import Pow

struct Example: View {<#•••#>
@State var count = 0
var body: some View { ZStack {<#•••#>
Color.clear
HelloView() .overlay(alignment: .topTrailing) { NotificationBadge(count) .changeEffect(.pulse(shape: Circle(), count: 3), value: count) } }<#•••#>
.contentShape(Rectangle()) .onTapGesture { count += 1 }
} }

An effect that pushes down the view while a condition is true.

												
import SwiftUI import Pow

struct Example: View {<#•••#>
var body { Button("Submit") { submit() } .buttonStyle(PushDownButtonStyle()) }
}

struct PushDownButtonStyle: ButtonStyle { func makeBody(configuration: Configuration) -> some View { configuration.label .bold() .foregroundStyle(.white) .padding(.vertical, 12) .padding(.horizontal, 64) .background(.tint, in: Capsule()) .opacity(configuration.isPressed ? 0.75 : 1) .conditionalEffect( .pushDown, condition: configuration.isPressed ) } }

An effect that emits the provided particles from the origin point and slowly float up while moving side to side.

												
import SwiftUI import Pow

struct Example: View {<#•••#>
@State var stars = 18
var body: some View { ZStack {<#•••#>
Color.clear
Button {<#•••#>
stars += 1 } label: { Label(stars.formatted(), systemImage: "star.fill") } .changeEffect( .rise(origin: UnitPoint(x: 0.75, y: 0.25)) { Text("+1") }, value: count) .foregroundStyle(.yellow) } } }

An effect that shakes the view when a change happens.

												
import SwiftUI import Pow

struct Example: View {<#•••#>
@State var password = "" @State var loginAttempts = 0 @State var isProcessing = false
var body: some View { ZStack {<#•••#>
Color.clear
SecureField("Password", text: $password) .changeEffect(.shake(rate: .fast), value: loginAttempts) .onSubmit {<#•••#>
Task { isProcessing = true defer { isProcessing = false } do { try await login() } catch { loginAttempts += 1 } } } .disabled(isProcessing) .textFieldStyle(.roundedBorder) } } }

An effect that highlights the view with a shine moving over the view.

												
import SwiftUI import Pow

struct Example: View {<#•••#>
@State var isFormValid = false
var body: some View { ZStack {<#•••#>
Color.clear
Button("Submit") {<#•••#>
submit() } .disabled(!isFormValid) .animation(.default, value: isFormValid) .changeEffect( .shine.delay(0.5), value: isFormValid, isEnabled: isFormValid ) }<#•••#>
.contentShape(Rectangle()) .onTapGesture { isFormValid.toggle() }
} }

A transition that moves the view in from its leading edge with any overshoot resulting in an elastic deformation of the view.

												
import SwiftUI import Pow

struct Example: View {<#•••#>
@State var isAdded = false
var body: some View { ZStack {<#•••#>
Color.clear
if isAdded { HelloView() .transition( .asymmetric( insertion: .movingParts.skid, removal: .movingParts.skid( direction: .trailing ) ) .animation( .interactiveSpring(dampingFraction: 0.66) .speed(0.25) ) ) } }<#•••#>
.contentShape(Rectangle()) .onTapGesture { withAnimation { isAdded.toggle() } }
} }

An effect that emits smoke from the view.

												
import SwiftUI import Pow

struct Example: View {<#•••#>
@State var isOn = false
@State var count = 300
var body: some View { ZStack {<#•••#>
Color.clear
HelloView() .overlay(alignment: .topTrailing) { NotificationBadge(count: count) .conditionalEffect(.smoke, condition: isOn) } }<#•••#>
.contentShape(Rectangle()) .onTapGesture { isEnabled = true Task { for i in (0...12) { count += 1 try? await Task.sleep(nanoseconds: 250_000_000 - UInt64(i) * 10_000_000) } isEnabled = false } }
} }

A transition from completely bright to fully visible on insertion, and from fully visible to completely bright on removal.

												
import SwiftUI import Pow

struct Example: View {<#•••#>
@State var url: URL?
var body: some View { ZStack {<#•••#>
Color.clear
AsyncImage( url: url, transaction: .init(animation: .easeInOut(duration: 1.8)) ) { phase in ZStack {<#•••#>
Color.white
switch phase { case .success(let image): image .resizable() .aspectRatio(contentMode: .fit) .zIndex(1) .transition(.movingParts.snapshot)<#•••#>
case .failure(let error): Text(error.localizedDescription) .font(.caption) case .empty: EmptyView() @unknown default: EmptyView() } }<#•••#>
.aspectRatio(contentMode: .fit)
}<#•••#>
.clipShape(RoundedRectangle(cornerRadius: 32, style: .continuous)) .frame(width: 250, height: 250)
}<#•••#>
.contentShape(Rectangle()) .onTapGesture { if url == nil { // Photo by [Robert Bye](https://unsplash.com/@robertbye) on [Unsplash](https://unsplash.com) url = URL(string: "https://picsum.photos/id/1061/500") } else { url = nil } }
} }

An effect that spins the view when a change happens.

												
import SwiftUI import Pow

struct Example: View {<#•••#>
@State var count = 0
var body: some View { ZStack {<#•••#>
Color.clear
HelloView() .overlay(alignment: .topTrailing) { NotificationBadge(count) .changeEffect(.spin, value: count) } }<#•••#>
.contentShape(Rectangle()) .onTapGesture { count += 1 }
} }

An effect that emits multiple particles in different shades and sizes moving up from the origin point.

												
import SwiftUI import Pow

struct Example: View {<#•••#>
@State var isLiked = false
var body: some View { ZStack {<#•••#>
Color.clear
Button {<#•••#>
isLiked.toggle() } label: { Label(likes.formatted(), systemImage: "heart.fill") } .changeEffect( .spray(origin: UnitPoint(x: 0.25, y: 0.5)) { Image(systemName: "heart.fill") .foregroundStyle(.red) }, value: count) .tint(isLiked ? .red : .gray) } } }

A three-dimensional transition from the back of the towards the front during insertion and from the front towards the back during removal.

												
import SwiftUI import Pow

struct Example: View {<#•••#>
@State var isAdded = false
var body: some View { ZStack {<#•••#>
Color.clear
if isAdded { HelloView() .transition( .asymmetric( insertion: .movingParts.swoosh, removal: .opacity ) ) } }<#•••#>
.contentShape(Rectangle()) .onTapGesture { withAnimation(.spring()) { isAdded.toggle() } }
} }

A transition that dissolves the view into many small particles.

The transition is only performed on removal.

												
import SwiftUI import Pow

struct Example: View {<#•••#>
@State var isAdded = false
var body: some View { ZStack {<#•••#>
Color.clear
if isAdded { HelloView() .transition( .movingParts.vanish(.blue) ) } }<#•••#>
.contentShape(Rectangle()) .onTapGesture { withAnimation { isAdded.toggle() } }
} }

An effect that wiggles the view when a change happens.

												
import SwiftUI import Pow

struct Example: View {<#•••#>
@State var isCalling = false
var body: some View { ZStack {<#•••#>
Color.clear
Button {<#•••#>
answer()
} label: { Label("Answer", systemName: "phone.fill") } .conditionalEffect(.repeat(.wiggle(rate: .fast), every: .seconds(1)), condition: isCalling) .buttonStyle(.borderedProminent) .controlSize(.large) .tint(.green) } } }

A transition using a sweep from the specified edge on insertion, and towards it on removal.

												
import SwiftUI import Pow

struct Example: View {<#•••#>
@State var isAdded = false
var body: some View { ZStack {<#•••#>
Color.clear
HelloBackgroundView()
if isAdded { HelloView() .transition(.movingParts.wipe( angle: .degrees(-45), blurRadius: 50 )) .zIndex(1) } }<#•••#>
.contentShape(Rectangle()) .onTapGesture { withAnimation(.spring(dampingFraction: 1)) { isAdded.toggle() } }
} }

Install Package

1
2
  1. In Xcode, select Add Packages… from the File menu.

  2. Enter https://github.com/Emerge­Tools/Pow in the search field.
    Then, click Add Package.
    We recommend setting the Dependency Rule to Up to Next Major Version.
    After adding the package, you will be able to import Pow in your project.