SwiftUI Transitions
Create custom transitions in SwiftUI using the protocol Transition using view modifiers .scaleEffect, .opacity, .rotationEffect, .blur and others.
import SwiftUI
@available(iOS 17.0, *)
struct SampleTransitionView: View {
@State private var show: Bool = false
var body: some View {
VStack(spacing: 0) {
VStack {
Spacer(); Spacer(); Spacer()
Button(action: {
withAnimation {
show.toggle()
}
}, label: {
Circle()
.fill(Color.white)
.frame(width: 100, height: 100)
.shadow(radius: 10)
.overlay(content: {
Image(systemName: "power")
.resizable()
.aspectRatio(1.0, contentMode: .fit)
.scaleEffect(0.4)
.foregroundStyle(Color.blue)
})
})
Spacer()
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.overlay(alignment: .top) {
show ?
Circle()
.fill(Color.white)
.frame(width: 100, height: 100)
.shadow(radius: 10)
.overlay(content: {
Image(systemName: "checkmark")
.resizable()
.aspectRatio(1.0, contentMode: .fit)
.scaleEffect(0.4)
.foregroundStyle(Color.blue)
})
.transition(LoopTransition())
.padding(170)
: nil
}
}
.background {
Image("background")
.resizable()
.scaledToFill()
.padding(-80)
.blur(radius: 150.0)
.brightness(0.3)
}
}
}
@available(iOS 17.0, *)
struct LoopTransition: Transition {
func body(content: Content, phase: TransitionPhase) -> some View {
content
.scaleEffect(phase.isIdentity ? 1 : 0.5)
.opacity(phase.isIdentity ? 1 : 0)
.blur(radius: phase.isIdentity ? 0 : 10)
.rotationEffect(
.degrees(
phase == .willAppear ? 360 :
phase == .didDisappear ? -360 : .zero
)
)
}
}
@available(iOS 17.0, *)
#Preview {
SampleTransitionView()
}