0Pricing
Swift Academy · درس

‏AnimatableModifier وAnimatable المخصّصان

حرّكوا المحتوى المرسوم مخصّصًا بجعله متوافقًا مع Animatable وAnimatableModifier.

‏AnimatableModifier وAnimatable المخصّصان درس مجاني في Swift Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 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. وتفي أنواع Swift مثل CGFloat وDouble وAnimatablePair بهذا الشرط.

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 جسم المعدِّل في كل إطار من إطارات الحركة. اجعل العمليات الحسابية داخل الجسم محدودة للحفاظ على سلاسة تبلغ 60 أو 120 إطارًا في الثانية.

// 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 المخصّصان» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Swift Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Swift Academy 4 دروس في المجموع.

ماذا ستتعلم في «‏AnimatableModifier وAnimatable المخصّصان»؟

حرّكوا المحتوى المرسوم مخصّصًا بجعله متوافقًا مع Animatable وAnimatableModifier. تتمرن على Swift Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Swift Academy؟

لا تُشترط خبرة سابقة. Swift Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.

كم من الوقت يستغرق درس «‏AnimatableModifier وAnimatable المخصّصان»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Swift Academy هذا؟

نعم. كل درس في Swift Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. الرسوم المتحركة الضمنية مقابل الصريحة
  2. ‏matchedGeometryEffect للانتقالات البارزة
  3. ‏AnimatableModifier وAnimatable المخصّصان
  4. ‏TimelineView وCanvas للرسم عالي الأداء
← العودة إلى Swift Academy