مستخدم iPhone لا يقول «هذا التطبيق ليس أصلياً». يقول «فيه شيء غريب» ويحذفه. الشيء الغريب هو عادةً واحد من خمسة تفاصيل يمكن قياسها — وكلّها قابلة للإصلاح في Flutter إن عرفت أين تنظر.
1. منحنيات الحركة
الانتقالات بين الشاشات في iOS تستخدم منحنى نابضاً (spring) بتخميد محدّد، والقوائم تُفتح بمنحنى مختلف عن الأزرار. أما Flutter فيستخدم في أغلب حركاته الافتراضية منحنيات Material، وهذا أول ما يبدو غريباً لمستخدم iPhone.
// للانتقال بين الشاشات: CupertinoPageRoute لا MaterialPageRoute
Navigator.of(context).push(
CupertinoPageRoute(builder: (_) => const DetailsScreen()),
);
// وللحركات داخل الشاشة: تباطؤ ناعم بدل easeInOut المتماثل
AnimatedContainer(
duration: const Duration(milliseconds: 350),
curve: Curves.easeOutCubic,
// ...
);
2. ارتداد التمرير
القوائم في iOS ترتدّ عند الحافة وتُبطئ بمعامل احتكاك محدّد. Flutter يطبّق BouncingScrollPhysics تلقائياً على iOS — المشكلة تظهر حين يفرض أحدهم ClampingScrollPhysics على قائمة بعينها، أو حين تُبنى القائمة على منصّة واحدة ثم يُفترض أن السلوك نفسه سيظهر على الأخرى. اترك الفيزياء للمنصّة، ولا تفرضها على قائمة إلا لسبب مكتوب.
3. توقيت اللمس
الزر في iOS يُعطي تغذيته البصرية بتعتيم خفيف لا بموجة، ويُلغى الضغط إن تحرّك الإصبع خارجه قبل الرفع. CupertinoButton يفعل هذا؛ ElevatedButton يرسم موجة Material — وكلاهما يُنفّذ عند الرفع، لكن الإحساس مختلف تماماً، والفرق يُلاحَظ في أول ثانية استخدام.
4. الطباعة والحروف العربية
SF Pro هو خط النظام، وFlutter لا يستطيع شحنه. لكن استخدام .SF Pro Text عبر عائلة الخط الافتراضية للمنصّة يعمل على iOS. أما العربية فتحتاج خطاً تشحنه أنت — ونستخدم IBM Plex Sans Arabic بأوزانه الحقيقية، لا وزناً واحداً مُصنَّعاً بالسماكة.
- لا
letterSpacingعلى النصّ العربي أبداً — يقطع اتّصال الحروف - ارتفاع سطر أعلى للعربية (1.6 فما فوق) لأن التشكيل والامتدادات تحتاج مساحة
- أرقام جدولية (
tabularFigures) في أي عمود أرقام
5. المناطق الآمنة والاتجاه
الشاشة العربية تنعكس: الرجوع يميناً، والقوائم تُسحب من اليمين. Flutter يعكس تلقائياً إن استخدمت EdgeInsetsDirectional وAlignmentDirectional — ويكسر التطبيق إن استخدمت left/right الصريحة. القاعدة: لا كلمة left أو right في الكود إلا لسبب مكتوب.
التطبيق الأصلي ليس الذي يستخدم أدوات النظام، بل الذي يتصرّف كما يتوقّع مستخدم النظام — في أول لمسة، وأول تمرير، وأول انتقال.
الخلاصة
Flutter قادر على تجربة بمستوى iOS الرسمي، لكنه لا يعطيها افتراضياً. خمسة قرارات — المنحنى، الفيزياء، اللمس، الطباعة، الاتجاه — تُتّخذ مرّة في جذر التطبيق، ويرث كل شيء بعدها الإحساس الصحيح.


