I'm just using swiftUI. I want some one view to have a repeating animation: 1.move up, 2.pause, 3.move up, 4.pause, 5.move down, 6.pause, 7.move down, 8.pause.
Similar to the undulations of pixel wind in Contra.
In UIkit, I can use UIView.animateKeyframes
in the block to make the view change.Specify anywhere.
In swfitUI I don't know how to do.
can anyone help me?
I have understood that it is not simply moving the y-axis that can achieve the pixel wind effect.
VStack {
Text("❤️")
.font(.system(size: 200,weight: .bold))
.offset(y: offsetY)
.onAppear{
Timer.scheduledTimer(withTimeInterval: 3, repeats: true) { _ in
animate()
}
}
}
func animate() {
withAnimation(Animation.linear(duration: 0.3)) {
self.offsetY -= 10
}
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
withAnimation(Animation.linear(duration: 0.3)) {
self.offsetY -= 10
}
}
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
self.offsetY = 0
}
}
Ask about the code obtained after ChatGPT modification,I always feel weird.
let customView = Text("❤️")
func somMethod(){
customView use animate
}
Since iOS 17, keyframeAnimator
is available. You can specify the keyframes using that.
Based on your existing code, you seem to want the heart to move linearly to y offsets -10, -20, -10, and then back to 0. Each move takes 0.3 seconds, and waits for 0.7 seconds between moves. Here is the code with keyframeAnimator
.
struct ContentView: View {
var body: some View {
Text("❤️")
.font(.system(size: 200,weight: .bold))
.keyframeAnimator(initialValue: 0 as CGFloat, repeating: true) { content, value in
content.offset(y: value)
} keyframes: { _ in
KeyframeTrack {
LinearKeyframe(-10, duration: 0.3)
LinearKeyframe(-10, duration: 0.7)
LinearKeyframe(-20, duration: 0.3)
LinearKeyframe(-20, duration: 0.7)
LinearKeyframe(-10, duration: 0.3)
LinearKeyframe(-10, duration: 0.7)
LinearKeyframe(0, duration: 0.3)
LinearKeyframe(0, duration: 0.7)
}
}
}
}
If I want to specify any view to animate in a method, what should I do?
SwiftUI doesn't work imperatively like UIKit. If you want to reuse this code, you can extract it as a view modifier:
extension View {
func animateUpAndDown() -> some View {
self.keyframeAnimator(initialValue: 0 as CGFloat, repeating: true) { content, value in
content.offset(y: value)
} keyframes: { _ in
...
}
}
}
To use this, just add .animateUpAndDown()
like a normal view modifier at the end of the view you want to animate.