1. AnyTransition 过渡动画效果
1.1 创建过度动画案例 AnyTransitionBootcamp.swift
import SwiftUI
/// 旋转修饰 View
struct RotateViewModifier :ViewModifier{
let rotation: Double
func body(content: Content) -> some View {
content
.rotationEffect(Angle(degrees: rotation))
.offset(x: rotation != 0 ? UIScreen.main.bounds.width : 0,
y: rotation != 0 ? UIScreen.main.bounds.height : 0)
}
}
// 扩展
extension AnyTransition{
/// 旋转
static var rotation: AnyTransition{
modifier(
active: RotateViewModifier(rotation: 180),
identity: RotateViewModifier(rotation: 0))
}
/// 旋转自定义角度
static func rotation(rotation: Double) -> AnyTransition{
modifier(
active: RotateViewModifier(rotation: rotation),
identity: RotateViewModifier(rotation: 0))
}
/// 旋转 不对称方式
static var rotateOn: AnyTransition{
asymmetric(
insertion: .rotation,
removal: .move(edge: .leading))
}
}
/// 过渡动画
struct AnyTransitionBootcamp: View {
@State private var showRectangle: Bool = false
var body: some View {
VStack {
Spacer()
if showRectangle {
RoundedRectangle(cornerRadius: 25)
.fill(Color.black)
.frame(width: 250, height: 350)
.frame(maxWidth: .infinity, maxHeight: .infinity)
//.transition(.move(edge: .leading))
//.transition(AnyTransition.scale.animation(.easeInOut))
//.transition(AnyTransition.rotation.animation(.easeInOut))
// 旋转
//.transition(.rotation)
// 旋转自定义角度
//.transition(.rotation(rotation: 1080))
// 不对称旋转
.transition(.rotateOn)
}
Spacer()
Text("Click Me!")
.withDefaultButtonFormatting()
.padding(.horizontal, 40)
.onTapGesture {
//duration: 5.0
withAnimation(.easeInOut) {
showRectangle.toggle()
}
}
}
}
}
struct AnyTransitionBootcamp_Previews: PreviewProvider {
static var previews: some View {
AnyTransitionBootcamp()
}
}
1.2 效果图:
2. MatchedGeometryEffect 匹配几何动画效果
2.1 创建匹配几何效果案例,MatchedGeometryEffectBootcamp.swift
import SwiftUI
/// 匹配几何效果
struct MatchedGeometryEffectBootcamp: View {
/// 是否单击
@State private var isClicked: Bool = false
@Namespace private var namespace
var body: some View {
VStack {
if !isClicked {
Circle()
.matchedGeometryEffect(id: "rectangle", in: namespace)
.frame(width: 100, height: 100)
}
Spacer()
if isClicked {
Circle()
.matchedGeometryEffect(id: "rectangle", in: namespace)
.frame(width: 300, height: 200)
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.orange)
.onTapGesture {
withAnimation(.easeIn(duration: 0.5)) {
isClicked.toggle()
}
}
}
}
/// 匹配几何效果二
struct MatchedGeometryEffectBootcamp2: View{
let categories: [String] = ["Home", "Popular", "Saved"]
@State private var selected: String = "Home"
@Namespace private var namespace2
var body: some View{
HStack {
ForEach(categories, id: \.self) { category in
ZStack(alignment: .bottom) {
if selected == category{
RoundedRectangle(cornerRadius: 10)
.fill(Color.red.opacity(0.5))
.matchedGeometryEffect(id: "category_background", in: namespace2)
.frame(width: 35, height: 2)
.offset(y: 10)
}
Text(category)
.foregroundColor(selected == category ? .red : .black)
}
.frame(maxWidth: .infinity)
.frame(height: 55)
.onTapGesture {
withAnimation(.spring()) {
selected = category
}
}
}
}
.padding()
}
}
struct MatchedGeometryEffectBootcamp_Previews: PreviewProvider {
static var previews: some View {
MatchedGeometryEffectBootcamp()
//MatchedGeometryEffectBootcamp2()
}
}
2.2 效果图: