AnyTransition/过渡动画, MatchedGeometryEffect/匹配几何动画效果 的使用

1. AnyTransition 过渡动画效果

1.1 创建过度动画案例 AnyTransitionBootcamp.swift

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

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 效果图:

相关推荐
UI设计兰亭妙微7 小时前
飞秒激光时域热反射测量系统软件UI界面设计
ui·ui设计公司
鹏多多.7 小时前
Flutter使用screenshot进行截屏和截长图以及分享保存的全流程指南
android·前端·flutter·ios·前端框架
少云清7 小时前
【UI自动化测试】1_IOS自动化测试 _环境搭建
ui·ios
Awna9 小时前
移动端游戏 UI 与动效设计参考指南
游戏·ui
鄃鳕11 小时前
耗时IO对象移到子线程,防止UI卡顿
ui
yijianxiangde10012 小时前
iOS 无根越狱前期准备
ios
库奇噜啦呼13 小时前
【iOS】Effective Objective-C第一章
开发语言·ios·objective-c
少云清13 小时前
【UI自动化测试】4_TPshop项目实战 _后台管理-新增商品成功
ui
IT 行者15 小时前
每天了解几个MCP SERVER:21st.dev Magic
人工智能·ui·mcp
songgeb15 小时前
UITableView 在 width=0 时 reloadData 被"空转消费"导致 Cell 显示错乱
swift·cursor