โจ.tapToShake()
Last updated
Last updated
SwiftUI โฉ Animations โฉ Animatable โฉ Modifiers โฉ
็จ withAnimation() ไพ่จญๅฎ "keyframe" ็ๅๆธๅผใ
็จ Animatable Modifiers ไพ่จ็ฎๅ งๆๆผ "keyframe" ไน้็ "frame"ใ
ๆฌไพ็จๅ
ฉ็จฎๆนๅผ (TapToShake
, TapToShake2
) ไพ่จญๅฎ "keyframe" ็ๅๆธๅผใ
import SwiftUI
struct ContentView: View {
@State private var taps: CGFloat = 0
var body: some View {
VStack(spacing: 16) {
Text("๐ Shaking Banana ๐")
.foregroundColor(.yellow)
.tapToShake()
Text("๐ Shaking Hello ๐")
.foregroundColor(.blue)
.tapToShake2()
}
.font(.headline)
.padding()
.border(.secondary)
}
}
// ๐ ShakeOffset
// calculate animation frame for shake effect at specific time `t`
struct ShakeOffset: Animatable, ViewModifier {
var t: CGFloat = 0 // โญ๏ธ animation parameter
let amplitude: CGFloat = 10
// ๐
ฟ๏ธ Animatable
// โญ๏ธ animation parameter (for interpolation)
var animatableData: CGFloat {
get { t }
set { t = newValue }
}
// ๐
ฟ๏ธ ViewModifier
func body(content: Content) -> some View {
content
.offset(x: sin(t * .pi * 2) * amplitude)
}
}
// ๐ TapToShake
struct TapToShake: ViewModifier {
// โญ๏ธ "keyframe" parameter
@State private var t: CGFloat = 0
// ๐
ฟ๏ธ ViewModifier
func body(content: Content) -> some View {
content
// โญ๏ธ interpolates between "keyframes" using `ShakeOffset`
.modifier(ShakeOffset(t: t))
.onTapGesture {
withAnimation(.linear(duration: 0.5)) {
// โญ๏ธ "keyframe" param
// t = 0, 3, 6, 9 ...
// ๐ธ ่จป่งฃ๏ผ
// ้็จฎๆนๅผๆฏๆฌกๆ้ฝๆฏๅ
ๅพๅณๆบๅใ
t += 3
}
}
}
}
// ๐ TapToShake2
struct TapToShake2: ViewModifier {
@State private var flag = false
// โญ๏ธ "keyframe" parameter
var t: CGFloat { flag ? 1 : 0 }
// ๐
ฟ๏ธ ViewModifier
func body(content: Content) -> some View {
content
// โญ๏ธ interpolates between "keyframes" using `ShakeOffset`
.modifier(ShakeOffset(t: t))
.onTapGesture {
withAnimation(.linear(duration: 0.5).repeatCount(3, autoreverses: false)) {
// โญ๏ธ "keyframe" param toggles between 0 and 1
// t = 0, 1, 0, 1 ...
// ๐ธ ่จป่งฃ๏ผ
// ้็จฎๆนๅผ็ฌฌไธๆฌกๆๆๅ
ๅพๅณๆบๅ๏ผ็ฌฌไบๆฌกๆๆๅ
ๅพๅทฆๆบๅใ
flag.toggle()
}
}
}
}
// ๐ View+
extension View {
/// `view.tapToShake()`
func tapToShake() -> some View {
modifier(TapToShake())
}
/// `view.tapToShake2()`
func tapToShake2() -> some View {
modifier(TapToShake2())
}
}
SwiftOnTap โฉ Animatable โญ๏ธ