مدیریت کیبورد در React Native: راهنمای کامل
خلاصهٔ کاملتر
وقتی کیبورد روی موبایل باز میشه، iOS و اندروید دو مدل کاملاً متفاوت دارن. iOS یه نوتیفیکیشن میفرسته که شامل مدت زمان و منحنی انیمیشن کیبورده — تو فقط انیمیشن خودت رو با همون پارامترها برنامهریزی میکنی و UIKit هر دو رو همزمان اجرا میکنه. اندروید اما یه سیستم کاملاً متفاوت داره: بهجای یه snapshot واحد، هر فریم مقدار inset فعلی کیبورد رو از طریق WindowInsetsAnimationCallback بهت میده.
مشکل اصلی از اندروید ۱۵ شروع میشه. قبلاً میشد با تنظیم adjustResize در AndroidManifest.xml به سیستمعامل گفت که موقع باز شدن کیبورد، پنجره رو ریسایز کنه. ولی از اندروید ۱۵ (API 35) به بعد، edge-to-edge اجباری شده — یعنی اپ شما زیر نوار وضعیت و کیبورد رندر میشه و سیستم دیگه خودش پنجره رو ریسایز نمیکنه. حالا مدیریت layout کاملاً بر عهده خود توسعهدهندهست.
KeyboardAvoidingView بومی React Native روی iOS قابلقبوله چون از LayoutAnimation با duration و curve درست استفاده میکنه. ولی روی اندروید چند مشکل داره: اول اینکه از keyboardDidShow استفاده میکنه که بعد از پایان انیمیشن کیبورد فایر میشه، نه حین اون. دوم اینکه LayoutAnimation روی اندروید با منحنی کیبورد همخوانی نداره. سوم اینکه edge-to-edge رو اصلاً نمیفهمه و با فعال بودنش محتوا زیر کیبورد پنهان میمونه.
کتابخانه react-native-keyboard-controller این مشکلات رو با یه رویکرد معماری درست حل میکنه: هر دو مدل iOS و اندروید رو به یه Animated Value واحد نگاشت میکنه. روی اندروید این مقدار هر فریم از WindowInsetsAnimationCallback آپدیت میشه، روی iOS هم UIKit خودش انیمیشنش رو انجام میده. نتیجه: کیبورد و محتوای اپ کاملاً همزمان حرکت میکنن. مهاجرت هم فقط یه خط تغییره:
- import { KeyboardAvoidingView } from "react-native"
+ import { KeyboardAvoidingView } from "react-native-keyboard-controller"برای فرمهای اسکرولپذیر با چند اینپوت، KeyboardAvoidingView کافی نیست. مثلاً وقتی کاربر از فیلد ۳ به فیلد ۹ میره، کیبورد تکون نمیخوره و keyboardWillShow فایر نمیشه — پس KeyboardAvoidingView هیچ کاری نمیکنه. اینجاست که KeyboardAwareScrollView از همون کتابخانه به کار میاد. این کامپوننت علاوه بر کیبورد، موقعیت اینپوت فوکوسشده و حتی موقعیت کرسر داخلش رو هم ردیابی میکنه و وقتی لازم باشه، اسکرول میکنه تا اینپوت فعال همیشه بالای کیبورد باشه.
<KeyboardAwareScrollView bottomOffset={50} style={styles.container}>
<TextInput placeholder="First name" />
<TextInput placeholder="Last name" />
<TextInput placeholder="Email" />
<Button title="Submit" />
</KeyboardAwareScrollView>نکات کلیدی:
- iOS و اندروید مدلهای کاملاً متفاوتی برای کیبورد دارن: snapshot در iOS در مقابل per-frame inset در اندروید
- از اندروید ۱۵ به بعد edge-to-edge اجباریه و adjustResize دیگه کار نمیکنه
- KeyboardAvoidingView بومی React Native روی اندروید ساختاراً شکستهست
- جایگزین کردن با نسخه react-native-keyboard-controller یه خط تغییره و همه مشکلات رو حل میکنه
- برای فرمهای چند فیلدی اسکرولپذیر از KeyboardAwareScrollView استفاده کن که کرسر رو هم ردیابی میکنه




