简述
官方文档表示 No overview available . 没有简述,其实顾名思义:动画。
SwiftUI 中的动画相较于 UIKit 中的使用简化了很多。基本两个方法即可完成
@State var degrees: Double = 0
Text("Animation")
.rotationEffect(.degrees(degrees))
.animation(.linear(duration: 1).repeatForever())
上面代码的动画为旋转一定角度,在1秒内线性完成,并且重复该动画。
那么,如果我想使 Text 连续不断的顺时针旋转,这段代码可以实现吗?
答案是:不能。
Animation
曾经作者想做一个 loading 视图,并使用 Image 视图做旋转用,发现最后的结果是,Image 会从 (0, 0) 点动画到布局的位置,然后再从动画的位置动画的 (0, 0) 点,如此往复。
repeatForever() :重复之前的动画,如果这个动画是在1秒钟完成,那么重复的动画也会在1秒钟完成,并且与原路径返回。animation() :在视图初始化后即刻开始动画,即动画将从视图的 (0, 0) 点开始。
那么如何解决这个问题呢?
- 删除
.animation() 函数。 - 使用
withAnimation<Result>(_ animation: Animation? = .default, _ body: () throws -> Result) 函数,该函数可以在页面创建后进行调用。 - 多次调用
withAnimation 函数,修改 degrees 值,使视图旋转。
@State var degrees: Double = 0
@Binding var isShow: Bool
let timer = Timer.publish(every: 0.1, on: .main, in: .common).autoconnect()
var body: some View {
VStack {
if isShow {
Image("loading")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 72)
.clipShape(Circle())
} else {
Spacer()
}
}
.ignoresSafeArea()
.rotationEffect(.degrees(degrees))
.onReceive(timer) { _ in
withAnimation(.linear(duration: 1)) {
self.degrees += 33
}
}
作者使用定时器进行 withAnimation 的函数调用。
其他动画函数
@inlinable public func rotation3DEffect(_ angle: Angle, axis: (x: CGFloat, y: CGFloat, z: CGFloat), anchor: UnitPoint = .center, anchorZ: CGFloat = 0, perspective: CGFloat = 1) -> some View
@inlinable public func scaleEffect(_ scale: CGSize, anchor: UnitPoint = .center) -> some View
@inlinable public func scaleEffect(_ s: CGFloat, anchor: UnitPoint = .center) -> some View
@inlinable public func scaleEffect(x: CGFloat = 1.0, y: CGFloat = 1.0, anchor: UnitPoint = .center) -> some View
其实动画说白了就是动态的修改视图的值。
|