ارتفاع تقليد المادة WeChat الكرة العائمة
في الإصدار الأخير 6.6.7 من WeChat، تمت إضافة مقال جديد لوظيفة الكرة العائمة. أثناء قراءتك للمقالة، فجأة يرسل لك أحد الأصدقاء رسالة عاجلة، وعليك الرد فورًا. أو ربما تمر بجوار مطعم للوجبات الخفيفة وتحتاج إلى فتح دفع WeChat مؤقتًا، أو مقاطعة القراءة مؤقتًا. في الماضي، لم يكن بإمكاني سوى الخروج من صفحة تفاصيل المقالة، وبعد الانتهاء من عملي، كان بإمكاني العثور على المقالة الأصلية بجوار بعضها البعض. بالنسبة لمستخدمي WeChat بكثرة مثلنا، يكون الأمر مؤلمًا حقًا في كل مرة نواجه فيها هذا الموقف. لذلك، عندما تم إطلاق هذه الوظيفة، تم تحديثها على الفور إلى أحدث إصدار. تبدو هذه الوظيفة وكأنها تقابل صديقًا مقربًا، وهي سهلة الاستخدام للغاية. يمكنك أن تشعر بذلك من خلال الرسوم المتحركة أدناه
في الواقع، كان مفهوم الكرات العائمة موجودًا منذ فترة طويلة. على سبيل المثال، كرة مراقبة حركة المرور الخاصة بـ 360 Assistant، و AssistiveTouch الخاص بجهاز iPhone (تلك الكرة البيضاء الصغيرة اللطيفة)، وما إلى ذلك.
إذا أعجبك عنوان جيثب، فانقر عليه ❤️
بعد تجربتها، شعرت بالحكة في يدي ولا يسعني إلا أن أرغب في تقليدها. إذا كان تطبيقك يمكنه دمج هذه الوظيفة، فأعتقد أنه يمكنه رفع تطبيقك على الفور إلى مستوى جديد. حسنًا، دعونا نحلل النقاط الفنية الأساسية لمقال WeChat للكرة العائمة واحدة تلو الأخرى:
عندما نستخدم إيماءة حافة الشاشة لعرض العرض، سيكون هناك مطالبة بزاوية مستديرة في الزاوية اليمنى السفلية، والتي تتحرك مع تقدم الإيماءة. كيفية الحصول على تقدم UIScreenEdgePanGestureRecognizer
؟ نظرًا لأن interactivePopGestureRecognizer
الذي يأتي مع النظام مغلف، فلا يمكننا ربط الإجراء الخاص به للحصول على تقدم الإيماءة بالداخل. ولذلك، علينا أن نجد طريقة أخرى.
self . interactivePopGestureRecognizer ? . delegate = self
func gestureRecognizer ( _ gestureRecognizer : UIGestureRecognizer , shouldRecognizeSimultaneouslyWith otherGestureRecognizer : UIGestureRecognizer ) -> Bool {
return true
}
UIScreenEdgePanGestureRecognizer
إلى UINavigationController للحصول على تقدم إيماءة البوب. let gesture = UIScreenEdgePanGestureRecognizer ( target : self , action : #selector ( handleNavigationTransition ( gesture : ) ) )
gesture . edges = . left
self . view . addGestureRecognizer ( gesture )
بهذه الطريقة، هناك نوعان من UIScreenEdgePanGestureRecognizer
التي يمكنها الاستجابة في نفس الوقت، والتي تأتي مع النظام ولا تزال تحتفظ بمنطقها الأصلي، ويتم استخدام المنطق الجديد الذي أضفناه للحصول على تقدم إيماءة البوب الانسجام مع بعضهم البعض وهم سعداء. يتم استخدام هذه التقنية الخاصة بي أيضًا في هذه المقالة على iOS: دمج صفحات الملف الشخصي للتطبيقات الرئيسية (مثل Jianshu وWeibo وما إلى ذلك) في دقيقة واحدة
نظرًا لأنه يمكن تعليق الكرة العائمة على أي صفحة، فيجب وضعها في نافذة UIWindow جديدة. على سبيل المثال، عندما تنبثق لوحة مفاتيح النظام، تتم استضافتها بواسطة UIRemoteKeyboardWindow
. ثم إن دورة حياة هذه النافذة لا تعتمد على صفحة معينة، لذا من الأفضل استخدام صفحة مفردة لتنفيذها. هذا الجزء من التعليمات البرمجية متناثر نسبيًا. يمكنك فهمه من خلال النظر مباشرة إلى الكود المصدري.
override func point ( inside point : CGPoint , with event : UIEvent ? ) -> Bool {
let roundEntryViewPoint = self . convert ( point , to : roundEntryView )
if roundEntryView . point ( inside : roundEntryViewPoint , with : event ) == true {
return true
}
let collectViewPoint = self . convert ( point , to : collectView )
if collectView . point ( inside : collectViewPoint , with : event ) == true {
return true
}
return false
}
UIBezierPath
، ثم استخدم طريقة contains(point)
الخاصة بـ CGPath
لتحديد ذلك. func updateBGLayerPath ( isSmall : Bool ) {
var ratio : CGFloat = 1
if !isSmall {
ratio = 1.3
}
let path = UIBezierPath ( )
path . move ( to : CGPoint ( x : viewSize . width , y : ( 1 - ratio ) * viewSize . height ) )
path . addLine ( to : CGPoint ( x : viewSize . width , y : viewSize . height ) )
path . addLine ( to : CGPoint ( x : ( 1 - ratio ) * viewSize . width , y : viewSize . height ) )
path . addArc ( withCenter : CGPoint ( x : viewSize . width , y : viewSize . height ) , radius : viewSize . width*ratio , startAngle : CGFloat ( Double . pi ) , endAngle : CGFloat ( Double . pi*3 / 2 ) , clockwise : true )
path . close ( )
bgLayer . path = path . cgPath
}
override func point ( inside point : CGPoint , with event : UIEvent ? ) -> Bool {
return bgLayer . path! . contains ( point )
}
يمكن للطلاب الذين لا يعرفون الكثير عن هذا الموضوع الرجوع إلى هذه المقالة. مقالة لفهم استخدام تسليم الأحداث، وسلسلة الاستجابة، وhitTest، وpointInside
يمكنك أن ترى أن المقالة المفتوحة بالنقر على الكرة العائمة يتم تنفيذها من خلال حركة انتقالية مخصصة، بدءًا من موضع الكرة العائمة. هناك العديد من المقالات التي تشرح كيفية تخصيص الرسوم المتحركة الانتقالية، لكنني أوصيك بقراءة هذه المقالة لدمج تأثيرات الانتقال المخصصة بسرعة + برنامج تشغيل الإيماءات الكامل مع بضعة أسطر من التعليمات البرمجية
تستخدم الكرة العائمة في WeChat العديد من النقاط الفنية نسبيًا، ويكون الكود متناثرًا نسبيًا. إذا كان تطبيقك يريد دمج هذه الوظيفة، فأنت بحاجة إلى حزم الكود بعناية. أعتقد أن كيفية تصميم المتطلبات أكثر أهمية من كيفية تنفيذها. أثناء عملية التقليد، وجدت أن هناك العديد من المنطق التفصيلي المتشابك مع بعضها البعض، وأخيرًا تم عرض وظيفة الكرة العائمة التي تستخدمها. يقال أن المبرمجين ومديري المنتجات يحبون بعضهم البعض. هنا أريد أن أشيد بمدير المنتج لهذه الوظيفة؟
إذا كان هناك أي مشاكل في الكود، أو إذا كان لديك أي أسئلة، يمكنك أن تعطيني ملاحظات وسوف أتعامل معها في أقرب وقت ممكن. إذا أعجبك عنوان جيثب، فانقر عليه ❤️