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

Posted 大熊猫侯佩

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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()
        
    

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

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

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()
	    
	

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

不过,这在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()
	        
	    

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

现在,来看一下效果:

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

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

view
	.contentTransition(.identity)

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

如上图所示,貌似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
    

最后需要说明的是,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)

总结

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

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

以上是关于SwiftUI4.0有趣的动画升级:新iOS16视图内容过渡动画的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI 4.0(iOS 16+)使用新的 Gauge 视图极简实现仪表盘外观

SwiftUI 4.0(iOS 16+)使用新的 Gauge 视图极简实现仪表盘外观

SwiftUI4.0在iOS 16中新添加的inner和drop阴影效果

SwiftUI4.0在iOS 16中新添加的inner和drop阴影效果

iOS 16 SwiftUI 列表(List)footer 中 ProgressView “转圈圈”动画只显示一次的解决

iOS 16 SwiftUI 列表(List)footer 中 ProgressView “转圈圈”动画只显示一次的解决