• SwiftUI4.0有趣的动画升级:新iOS16视图内容过渡动画


    在这里插入图片描述

    概述

    我们知道,要想SwiftUI开发更加鲜活美味,为视图多添加点欢快的动画总是没错的。

    在iOS 13至15的系统中,当SwiftUI视图的外观发生改变时,我们可以很方便的为其自动产生动画效果:

    在这里插入图片描述

    这仅需用withAnimation方法块包裹驱动动画的属性变更即可:

    Text("Copyright@2022-08-08 🐼")
    	.font(.largeTitle)
    	.multilineTextAlignment(.center)
    	.offset(x: flag ? 50 : 0, y: flag ? 50 : 0)
    	.frame(height: flag ? 300 : 150)
    	.border(Color.red, width: 3.0)
    	.onTapGesture {
            withAnimation(.default.speed(0.5)) {
                flag.toggle()
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    不过,以上自动产生的动画效果仅限于视图特定属性的改变,比如尺寸或位置等。

    如果视图的内容发生了变化,是不会有任何动画效果的:

    Text("Copyright@2022-08-08 🐼")
    	.font(.largeTitle)
    	.fontWeight(flag ? .black : .thin)
    	.foregroundColor(flag ? .yellow : .red)
    	.multilineTextAlignment(.center)
    	.onTapGesture {
    	    withAnimation(.default.speed(0.5)) {
    	        flag.toggle()
    	    }
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    运行如下,毫无动画的痕迹:

    在这里插入图片描述

    不过,这在iOS 16中悄然发生了变化。

    在iOS 16中,我们可以为视图应用新的内容过渡动画(Content Transition),让其仅在内容发生变化时也能“明艳动人”。

    下面,就让我们一起来看下吧!😉


    iOS 16新Content Transition动画

    在iOS 16中,为视图应用新的内容过渡动画很简单,只需为其添加新的 contentTransition() 修改器方法即可:

    VStack {
    	Text("Copyright@2022-08-08 🐼")
    	    .font(.largeTitle)
    	    .fontWeight(flag ? .black : .thin)
    	    .foregroundColor(flag ? .yellow : .red)
    	    .multilineTextAlignment(.center)
    	    .contentTransition(.interpolate)
    	    .onTapGesture {
    	        withAnimation(.default.speed(0.2)) {
    	            flag.toggle()
    	        }
    	    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    注意,上面的代码需要在Xcode 14beta中才能编译通过。

    现在,来看一下效果:

    在这里插入图片描述

    不过据我测试,在iOS 16中即使不为视图应用contentTransition()方法,也会自动产生内容过渡动画。

    想在iOS 16中关闭内容动画也很简单,为contentTransition修改器传入.identity实参即可:

    view
    	.contentTransition(.identity)
    
    • 1
    • 2

    值得一提的是,对于文本的内容过渡动画,如果变化文本里包括中文等其它文字,可能不会产生你期待的效果:

    在这里插入图片描述

    如上图所示,貌似SwiftUI还不知道如何做中文文本的内容动画 😭

    专门适配数字的numericText内容动画

    如果被改变的只是视图中的数字显示,那么内容动画提供一个特别的numericText动画类型,专门用于此种情况:

    在这里插入图片描述

    如上,我们在最左边的视图上应用了numericText内容动画,在中间视图上应用了interpolate内容动画,而在最右边的视图上未应用任何动画。代码如下:

    @State var i = 1000
    
    HStack(spacing: 50) {
        Text(verbatim: "\(i)")
            .contentTransition(.numericText())
        
        Text(verbatim: "\(i)")
            .contentTransition(.interpolate)
        
        Text(verbatim: "\(i)")
            .contentTransition(.identity)
    }
    .font(.largeTitle)
    
    
    Button("减 1"){
        withAnimation {
            i -= 1
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    最后需要说明的是,numericText内容动画类型目前只在Xcode 14 beta4+ 版本中支持。

    环境变量中引用内容动画类型

    SwiftUI还为内容过渡动画提供环境变量的支持,这意味着我们可以根据上级视图指定动画类型做不同的操作了:

    struct CustomView: View {
        
        @Environment(\.contentTransition) var transition
        
        var body: some View {
            VStack {
                switch transition {
                case .interpolate:
                    Text("interpolate")
                case .identity:
                    Text("identity")
                case .opacity:
                    Text("opacity")
                //case .numericText(): 此句会出错,遂改用以下一句判断
                default:
                    Text("numericText")
                }
            }
        }
    }
    
    CustomView()
    	.contentTransition(.interpolate)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    总结

    在本篇博文中,我们介绍了iOS 16中新的内容过渡动画(Content Transition),使用它我们可以更富表现力的点缀SwiftUI视图了。

    那么,感谢观赏,再会。😎

  • 相关阅读:
    Day 57 条件变量
    SpringCloud 2022有哪些变化
    Python:实现bitonic sort双调排序算法(附完整源码)
    MySQL数据备份 mysqldump 详解
    【干货】RPA+AI入门必须知道的39个名词
    Jarvis OJ Webshell分析
    zeppelin安装python(使用pymysql包)
    java快速开发框架的功能怎么样?
    Protocol Buffers简介
    工业智能网关BL110应用之三十六: 如何连接配置金鸽 金鸽Modbus服务器
  • 原文地址:https://blog.csdn.net/mydo/article/details/126225652