SwiftUI动画进阶,仿购票平台App行程目的地互换动效

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第25天,点击查看活动详情

项目背景

近几个月经常在国内出差,往常都是HR帮忙订好的机票和酒店,某天在打开某团搜索行程的时候发现地址切换动画蛮有意思。

当我们需要快捷切换出发地目的地时,只需要点击中间的切换按钮,然后就会有一个出发地和目的地“文字对调”的动画,这很人性化,也很优雅。

本章中,我们就来使用MatchedGeometryEffect构建这样的过渡动画。

那么,让我们开始吧。

项目搭建

首先,创建一个新的SwiftUI项目,命名为SwiftUIMGE

1.png

基础样式

先来看看基础样式部分,基础的结构我们可以看到有3个元素:起始地切换图标目的地

三个元素横向排布,我们先来完成下基础的样式,示例:

HStack {
    Spacer()
    Text("广州")
        .font(.title)
        .fontWeight(.bold)
        .foregroundColor(.black)

    Spacer()
    Image(systemName: "paperplane.circle")
        .foregroundColor(.red)
        .font(.title)

    Spacer()
    Text("北京")
        .font(.title)
        .fontWeight(.bold)
        .foregroundColor(.black)
    Spacer()
}
.frame(maxWidth: .infinity)
.padding()

2.png

上述代码中,我们使用HStack横向布局视图,使用Spacer将3个元素均衡分布。

基础动画

当我们点击中间的按钮时,需要对调出发地和目的地的位置,我们先声明一个变量表示当前的状态,示例:

@State var isSwitch: Bool = true

isSwitch处于不同状态时,我们展示不同的视图,同时在点击Image图标时,切换isSwitch的状态。

if isSwitch {

    HStack {
        Spacer()
        Text("广州")
            .font(.title)
            .fontWeight(.bold)
            .foregroundColor(.black)
        Spacer()
        Image(systemName: "paperplane.circle")
            .foregroundColor(.red)
            .font(.title)
            .onTapGesture {
                withAnimation(.linear) {
                    self.isSwitch.toggle()
                }
            }
        Spacer()
        Text("北京")
            .font(.title)
            .fontWeight(.bold)
            .foregroundColor(.black)
        Spacer()
    }
    .frame(maxWidth: .infinity)
    .padding()

} else {

    HStack {
        Spacer()
        Text("北京")
            .font(.title)
            .fontWeight(.bold)
            .foregroundColor(.black)

        Spacer()
        Image(systemName: "paperplane.circle")
            .foregroundColor(.red)
            .font(.title)
            .onTapGesture {
                withAnimation(.linear) {
                    self.isSwitch.toggle()
                }
            }
        Spacer()
        Text("广州")
            .font(.title)
            .fontWeight(.bold)
            .foregroundColor(.black)
        Spacer()
    }
    .frame(maxWidth: .infinity)
    .padding()
}

3.gif

过渡动画

上述代码中,我们根据isSwitch的状态切换两个视图,实现了基础的动画效果,但这不够优雅。

我们看到客户端的过渡动画是两个文字有一个优雅的“互调过渡”,我们先声明一个变量来存储交换位置的状态,示例:

@Namespace private var Transition

然后使用matchedGeometryEffect修饰符进行位置变换,示例:

//广州的id为guangzhou
Text("广州")
    .matchedGeometryEffect(id: "guangzhou", in: Transition)

//北京的id为beijing
Text("北京")
     .matchedGeometryEffect(id: "beijing", in: Transition)

4.png

我们给4个Text都加上matchedGeometryEffect修饰符,这里要区分ID,过渡动画才能知道那两个视图的元素进行交换。

这里如果我们要看到最终的效果,我们需要运行模拟器,在真机环境下才能看到最终的交互效果。

项目预览

5.gif

恭喜你,完成了本章的全部内容!

快来动手试试吧。

如果本专栏对你有帮助,不妨点赞、评论、关注~

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYeIh2R3' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片