SwiftUI学习(6)-SwiftUI动画入门Part1
2021, Apr 28
コニクマル撰写
本文使用目前最新版本的xcode 12 + macOS Big sur + iOS14
SwiftUI和UIKit一样提供了显式(Explicit)和隐式(Implicit )动画。
显式动画
在UIKit中显式动画通过UIView.animate
来触发, 如下
UIView.animate(withDuration: 0.5) {
someview.alpha = 0
}
在SwiftUI中则使用withAnimation
来完成显式动画,举个例子:
@State var alphaValue: Double = 1
var body: some View {
VStack {
Text("Hello, World!")
.opacity(self.alphaValue)
.padding()
Button("启动") {
withAnimation(.easeIn(duration: 0.5)) {
self.alphaValue = 0
}
}
}
}
隐式动画
通过设置View
的animation
装饰器(modifier), 当View
相关的属性值变化后,提供会自动添加过渡的动画。比如
@State var isClicked: Bool = false
var body: some View {
VStack {
RoundedRectangle(cornerRadius: 25)
.foregroundColor(self.isClicked ? .red : .green)
.frame(width: self.isClicked ? CGFloat(300.0) : CGFloat(200.0), height: 200)
.padding()
.animation(.default)
Button("启动") {
self.isClicked.toggle()
}
}
}
运行效果如果下:
Animation结构体
系统的Animation
结构体为我们提供一些常用的动画比如easeOut
` easeIn
easeInOut
spring等常用的动画。无论显式还是隐式动画都需要使用到
Animation可以通过直接传入
Animation`静态成员,
RoundedRectangle(cornerRadius: 25)
....
.animation(Animation.easeOut)
也可以调用Animation
的静态方法设置一些参数比如设置动画时间1秒
RoundedRectangle(cornerRadius: 25)
....
.animation(Animation.easeOut(duration: 1))
重复动画
Animation
具有repeatForever
repeatCount
的装饰器可以用来完成一些循环动画比如:
@State var isClicked: Bool = false
var body: some View {
VStack {
Image(systemName: "suit.heart.fill")
.resizable()
.scaledToFit()
.foregroundColor(.red)
.frame(width: 200, height: 200, alignment: .center)
.scaleEffect(self.isClicked ? 0.5: 1)
.animation(Animation.linear(duration: 0.5).repeatForever())
.padding()
Button("启动") {
self.isClicked.toggle()
}
.padding()
}
}
效果如下
延迟动画
Animation
的delay
装饰器可以延迟动画启动时间,对于多个View
的联合的动画相当有用, 比如实现各加载的indicator:
@State var isClicked: Bool = false
var body: some View {
VStack {
HStack{
let scale: CGFloat = isClicked ? 0 : 1
ForEach(0 ..< 5){ index in
Circle()
.frame(width: 50, height: 50, alignment: .center)
.scaleEffect(scale)
.foregroundColor(.red)
.animation(Animation.linear(duration: 0.8).repeatForever().delay(0.2 * Double(index)))
}
}
Button("启动") {
self.isClicked.toggle()
}
.padding()
}
}
效果如下: