دعنا SwiftUI
بطاقات متحركة تدعم الإيماءات على SwiftUI
:
أردت أن أضيف معاينة مفصلة ، ولكن حجم GIF ليس الأرثوذكسية. يمكن الاطلاع على معاينة كبيرة على الرابط أو في الفيديو التعليمي .
سوف تكون مطلوبة
SwiftUI
الآن في مرحلة تجريبية ، ويتم تثبيته مع Xcode الجديد ، والذي هو أيضا في مرحلة تجريبية. والخبر السار هو أن Xcode الجديد يمكن وضعه بجوار القديم ولا يمكن أن تشعر بأي ألم.

يمكنك تنزيله من الرابط في قسم Applications
.
ربما تكون قد شاهدت معاينات في الوقت الفعلي أثناء العمل مع SwiftUI
. لتنشيطه ، وكذلك بعض قوائم السياق ، تحتاج إلى تثبيت الإصدار التجريبي من نظام macOS Catalina
. لن تفعل من دون ألم. لم أراهن ، لذلك سأقوم بتشغيل المحاكاة بالطريقة القديمة.
مشروع جديد
إنشاء Single View Application
مع علامة اختيار إضافية - SwiftUI
:
انتقل إلى ملف ContentView.swift . وريث PreviewProvider
هو المسؤول عن المعاينة. نظرًا لأننا لن نستخدمها ، فسنترك الحد الأدنى من الشفرة اللازمة:
import SwiftUI struct ContentView: View { var body: some View { } }
آمل أن يكون هناك بالفعل فهم مشترك حول SwiftUI
، ونحن لن نتحدث عن نقاط تافهة.
بطاقات
يتم ترتيب البطاقات واحدة تلو الأخرى ، وبالتالي سنستخدم ZStack
. اسمحوا لي أن أذكرك أن هناك خيارين آخرين لتجميع العناصر: HStack
- أفقيًا و VStack
- عموديًا. للوضوح:

أضف البطاقة الأولى:
struct ContentView: View { var body: some View { return ZStack { Rectangle() .fill(Color.black) .frame(height: 230) .cornerRadius(10) .padding(16) } } }
أضفنا هنا مستطيلًا ، 230pt
باللون الأسود ، مرتفعًا 230pt
، 230pt
الحواف بمقدار 10pt
16pt
الهوامش من جميع الجوانب على 16pt
.
تتم إضافة النص الموجود في البطاقة إلى كتلة ZStack
بعد المستطيل:
Text("Main Card") .color(.white) .font(.title) .bold()
قم بتشغيل المشروع لمعرفة النتيجة المتوسطة:
ولكن هناك ثلاثة منهم!

للراحة ، MainCard
كود MainCard
:
struct MainCard: View { var title: String var body: some View { ZStack { Rectangle() .fill(Color.black) .frame(height: 230) .cornerRadius(10) .padding(16) Text(title) .color(.white) .font(.largeTitle) .bold() } } }
سيظهر title
في المُهيئ. هذا النص سيكون على البطاقة. أضف بطاقة إلى ContentView
، وفي الوقت نفسه سنرى معلمة جديدة في ContentView
:
struct ContentView: View { var body: some View { return MainCard(title: "Main Card") } }
نحن نعرف بالفعل كيفية عمل الكود ، لذلك حدد على الفور فئة لبطاقات الخلفية:
struct Card: View { var title: String var body: some View { ZStack { Rectangle() .fill(Color(red: 68 / 255, green: 41 / 255, blue: 182 / 255)) .frame(height: 230) .cornerRadius(10) .padding(16) Text(title) .color(.white) .font(.title) .bold() } } }
تعيين لون مختلف ونمط للنص. بقية الكود يكرر MainCard
الأسود. أضف بطاقتي خلفية إلى ContentView
. يتم ترتيب البطاقات واحدة تلو الأخرى ، لذلك ZStack
في ZStack
. كود عرض ContentView
:
struct ContentView: View { var body: some View { return ZStack { Card(title: "Third card") Card(title: "Second Card") MainCard(title: "Main Card") } } }
توجد بطاقات الخلفية تحت الأسود وحتى الآن غير مرئية. أضف إلى الأعلى إزاحة وحشوة من الحواف:
Card(title: "Third card") .blendMode(.hardLight) .padding(64) .padding(.bottom, 64) Card(title: "Second Card") .blendMode(.hardLight) .padding(32) .padding(.bottom, 32) MainCard(title: "Main Card")
الآن تشبه النتيجة الإعلان في بداية البرنامج التعليمي:
دعنا ننتقل إلى الإيماءات ، إلى جانب هذا إلى الرسوم المتحركة.
لفتات
الطريقة التي يتم بها تنفيذ الإيماءات ستجبرني على ناقص الكرمة وترك مراجعة سامة.

قبل أن ترى الكود ، يرجى ملاحظة أنه مدرج على developer.apple.com كمثال. الانطباع الأول هو خادع ، في الواقع أحببت ذلك.
قم بتعريف التعداد في ContentView
:
enum DragState { case inactive case dragging(translation: CGSize) var translation: CGSize { switch self { case .inactive: return .zero case .dragging(let translation): return translation } } var isActive: Bool { switch self { case .inactive: return false case .dragging: return true } } }
سوف DragState
جعل العمل مع لفتة أكثر راحة. إضافة dragState
ContentView
إلى ContentView
:
@GestureState var dragState = DragState.inactive
سيكون هناك السحر.

أينما يتم استخدام dragState
، سيتم تطبيق القيم الجديدة تلقائيًا. أعلن لفتة:
let dragGester = DragGesture() .updating($dragState) { (value, state, transaction) in state = .dragging(translation: value.translation) }
أضف لفتة إلى البطاقة الرئيسية وقم بتعيين offset
:
MainCard(title: "Main Card") .offset( x: dragState.translation.width, y: dragState.translation.height ) .gesture(dragGester)
هل تساوي الإزاحة قيمة المعلمة عند الوصول إليها؟ لا ، سيكون دائمًا متساويًا . هذا هو السحر.
سوف تتبع البطاقة بإصبع باستخدام الماوس ، ولكن بدون رسوم متحركة:
يجب أن تغير بطاقات الخلفية أيضًا موضعها ( على الأقل أردنا ذلك ). أضف رمزًا لهم مرتبطًا بحالة الإيماءة. سوف rotation3DEffect
تدوير البطاقة حتى تصبح الإيماءة نشطة:
Card(title: "Third card") .rotation3DEffect(Angle(degrees: dragState.isActive ? 0 : 60), axis: (x: 10.0, y: 10.0, z: 10.0)) .blendMode(.hardLight) .padding(dragState.isActive ? 32 : 64) .padding(.bottom, dragState.isActive ? 32 : 64) Card(title: "Second Card") .rotation3DEffect(Angle(degrees: dragState.isActive ? 0 : 30), axis: (x: 10.0, y: 10.0, z: 10.0)) .blendMode(.hardLight) .padding(dragState.isActive ? 16 : 32) .padding(.bottom, dragState.isActive ? 0 : 32)
كيف يمكنك أيضا استخدام 3D ، يمكنك أن تبحث هنا . أضفت أيضا blendMode
. تشبه الأوضاع الأدوات الموجودة في Photoshop و Sketch.
على الرغم من أن التغييرات مطبقة وليست متحركة ، فلنصلحها.
حيوية
سوف يفاجأ كم هو بسيط. فقط أضف خطًا:
.animation(.spring())
إضافة لكل بطاقة. الآن سيتم تطبيق أي تغييرات بشكل متحرك ، في حالتنا ، هذه هي أحجام المسافة البادئة ودوران ثلاثي الأبعاد offset
. إذا كنت بحاجة إلى رسوم متحركة ذات منحنيات ، استخدم الوضع basic
.
الزينة
أضف ظل العرض الرئيسي ودورته ، مرتبطًا بالإزاحة:
.rotationEffect(Angle(degrees: Double(dragState.translation.width / 10))) .shadow(radius: dragState.isActive ? 8 : 0)
إذا قمت بتشغيل المشروع ، فسترى المرجع منذ بداية البرنامج التعليمي. تشغيل المعاينة غير مرئي ، واسحب البطاقة إلى الجانب لرؤية التأثير.
للباحثين
→ يمكن العثور على رمز المشروع في المستودع
يكفي نسخ الملف إلى المشروع ، ولا توجد إعدادات إضافية مطلوبة. لا تخف من أن الكود الصغير هو أحد SwiftUI
.
إذا كان من المناسب لك مشاهدة الفيديو ، فقم بإلقاء نظرة على البرنامج التعليمي. بالمناسبة ، في الفيديو يمكنني استخدام معاينات الوقت الحقيقي.