AnimatableModifier และ Animatable แบบกำหนดเอง
ทำให้เนื้อหาที่วาดเองเคลื่อนไหวได้ด้วยการสอดคล้องกับ Animatable และ AnimatableModifier
AnimatableModifier และ Animatable แบบกำหนดเอง เป็นบทเรียน Swift Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Swift Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Swift Academy มีบทเรียนทั้งหมด 4 บทเรียน
โปรโตคอล Animatable
Animatable บอก SwiftUI ว่าควรคำนวณค่าระหว่างของประเภทหนึ่งอย่างไรระหว่างการทำแอนิเมชัน รูปร่างต่าง ๆ จะสอดคล้องกับโปรโตคอลนี้โดยอัตโนมัติ
struct Wave: Shape, Animatable {
var amplitude: Double
var animatableData: Double {
get { amplitude }
set { amplitude = newValue }
}
func path(in rect: CGRect) -> Path { Path() }
}คุณสมบัติ animatableData
SwiftUI จะอ่านและเขียน animatableData ในทุกเฟรมของแอนิเมชัน เพื่อคำนวณค่าระหว่างค่าต้นทางและค่าปลายทาง
struct GrowingCircle: Shape {
var radius: Double
var animatableData: Double {
get { radius }
set { radius = newValue }
}
func path(in rect: CGRect) -> Path {
Path(ellipseIn: CGRect(x: rect.midX-radius, y: rect.midY-radius, width: radius*2, height: radius*2))
}
}AnimatablePair สำหรับหลายค่า
ใช้ AnimatablePair เพื่อทำให้ค่าที่เป็นอิสระต่อกันสองค่าเคลื่อนไหวพร้อมกัน
struct Sector: Shape {
var startAngle: Double, endAngle: Double
var animatableData: AnimatablePair<Double, Double> {
get { AnimatablePair(startAngle, endAngle) }
set { startAngle = newValue.first; endAngle = newValue.second }
}
func path(in rect: CGRect) -> Path { Path() }
}ViewModifier + Animatable
การทำให้ ViewModifier สอดคล้องกับ Animatable ทำให้คุณสามารถทำให้เอฟเฟกต์ภาพที่กำหนดเองเคลื่อนไหวได้
struct Shake: ViewModifier, Animatable {
var animatableData: Double = 0
func body(content: Content) -> some View {
content.offset(x: sin(animatableData * .pi * 4) * 8)
}
}การขับเคลื่อนแอนิเมชัน
เปลี่ยนค่าที่ทำให้เคลื่อนไหวได้ภายใน withAnimation แล้ว SwiftUI จะคำนวณค่าระหว่างผ่าน animatableData
struct ShakeView: View {
@State private var shakes = 0.0
var body: some View {
Text("Hello")
.modifier(Shake(animatableData: shakes))
.onTapGesture {
withAnimation(.linear(duration: 0.5)) { shakes += 1 }
}
}
}AnimatableModifier (เลิกใช้งานแล้ว) เทียบกับ Animatable + ViewModifier
AnimatableModifier เลิกใช้งานแล้วใน SDK รุ่นหลัง ๆ ควรทำให้ ViewModifier ของคุณสอดคล้องกับ Animatable โดยตรง
// Modern approach:
struct MyMod: ViewModifier, Animatable { ... }
// Avoid (deprecated):
// struct MyMod: AnimatableModifier { ... }ประเภทตัวเลขกำหนดเองในฐานะ animatableData
ประเภทใดก็ตามที่สอดคล้องกับ VectorArithmetic สามารถใช้เป็น animatableData ได้ CGFloat, Double และ AnimatablePair ของ Swift ล้วนใช้ได้
extension MyColor: VectorArithmetic {
static func += (lhs: inout MyColor, rhs: MyColor) { ... }
mutating func scale(by rhs: Double) { ... }
var magnitudeSquared: Double { ... }
}ตัวปรับแต่งที่อิงตามความคืบหน้า
รูปแบบที่ใช้กันทั่วไปคือ ทำให้ค่า progress เคลื่อนจาก 0 ถึง 1 แล้วคำนวณคุณสมบัติด้านภาพภายในตัวปรับแต่ง
struct FillModifier: ViewModifier, Animatable {
var progress: Double
var animatableData: Double { get { progress } set { progress = newValue } }
func body(content: Content) -> some View {
content.overlay(Color.blue.opacity(progress))
}
}การเชื่อมต่อด้วย .animation
แนบแอนิเมชันเพื่อขับเคลื่อนค่าความคืบหน้าของตัวปรับแต่งที่ทำให้เคลื่อนไหวได้โดยอัตโนมัติเมื่อสถานะเปลี่ยนแปลง
Text("Loading")
.modifier(FillModifier(progress: isLoaded ? 1 : 0))
.animation(.easeInOut(duration: 1.0), value: isLoaded)การทำให้รูปร่างกำหนดเองเคลื่อนไหว
การใช้งานที่ทรงพลังที่สุดคือการแปลงรูปร่างของเส้นทางสองแบบ โดยคำนวณค่าระหว่างจุดควบคุมผ่าน animatableData
struct Blob: Shape, Animatable {
var bulge: Double
var animatableData: Double { get { bulge } set { bulge = newValue } }
func path(in rect: CGRect) -> Path {
// compute bezier with bulge-adjusted control points
Path()
}
}ประสิทธิภาพ
SwiftUI เรียกใช้ body ของตัวปรับแต่งในทุกเฟรมของแอนิเมชัน ควรให้การคำนวณภายใน body มีน้อย เพื่อให้ได้ 60/120 fps อย่างราบรื่น
// OK: simple math in body
// AVOID: network calls, heavy computation in animated bodyตรวจสอบความเข้าใจ
ในทุกเฟรมของแอนิเมชัน SwiftUI อ่านและเขียนสิ่งใดเพื่อคำนวณค่าระหว่างของประเภทที่ทำให้เคลื่อนไหวได้ที่กำหนดเอง
สรุปบทเรียน
ทำให้รูปร่างหรือตัวปรับแต่งวิวสอดคล้องกับ Animatable และเปิดเผย animatableData (ค่าประเภท VectorArithmetic) SwiftUI จะคำนวณค่าระหว่างให้ในทุกเฟรม ใช้ AnimatablePair สำหรับสองค่า และขับเคลื่อนด้วย withAnimation หรือ .animation
คำถามที่พบบ่อย
บทเรียน “AnimatableModifier และ Animatable แบบกำหนดเอง” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “AnimatableModifier และ Animatable แบบกำหนดเอง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Swift Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Swift Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “AnimatableModifier และ Animatable แบบกำหนดเอง”
ทำให้เนื้อหาที่วาดเองเคลื่อนไหวได้ด้วยการสอดคล้องกับ Animatable และ AnimatableModifier คุณปฏิบัติ Swift Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Swift Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Swift Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “AnimatableModifier และ Animatable แบบกำหนดเอง” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Swift Academy นี้ได้ไหม
ได้ บทเรียน Swift Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- แอนิเมชันโดยนัยและโดยชัดแจ้ง
- matchedGeometryEffect สำหรับการเปลี่ยนฉากแบบฮีโร่
- AnimatableModifier และ Animatable แบบกำหนดเอง
- TimelineView และ Canvas สำหรับการวาดประสิทธิภาพสูง