مرحبا بالجميع! نشارك اليوم معكم المواد المعرفية ، التي تم إعداد ترجمة لها خصيصًا لطلاب الدورة التدريبية "ReactJS / React Native-developer" .
لذلك دعونا نبدأ.
لقد رأينا جميعًا مجالات الإدخال هذه:

التسمية التوضيحية كبيرة وتبدو وكأنها عنصر نائب حتى تركز على المدخلات. سوف تصبح أصغر وترتفع.
يبدو رائعا. على نحو سلس. لا تشوبه شائبة.
يبدو أيضًا أن مطورًا ذو خبرة فقط يمكنه القيام بذلك ، أليس كذلك؟
حسنًا ، ربما كان الأمر كذلك حتى ظهور React Native ، في تلك الأيام التي عاش فيها الناس في الكهوف وخلقوا جميع أنواع الألعاب. لكن هذا شيء من الماضي.
يمكنك مشاهدة الفيديو أو مواصلة القراءة. كل هذا يتوقف على ما تفضله.
ما نحاول تحقيقه؟
هناك خياران لما نتعامل معه.
الأول هو عندما لا يكون هناك تركيز على حقل الإدخال.

يظهر نقش داخل حقل الإدخال ، وحجمه يساوي حجم حقل النص. اللون ممل. هذا مشابه جدا لخاصية
placeholder
.
والخيار الثاني ، عندما يكون هناك التركيز على حقل الإدخال.

يظهر النقش أعلى حقل الإدخال ، وحجمه أصغر ، ويختلف اللون عن لون النص الذي تم إدخاله.
أبسط التنفيذ
أخيرا يمكننا الحصول على العمل. حتى الآن دون أي الرسوم المتحركة.
كما اتضح ، لدينا دولتان:
- لا يوجد تركيز على الحقل والنقش داخل الحقل.
- هناك تركيز على الحقل ، نقش فوق حقل الإدخال.

في الواقع ، يمكننا تخزين حالة ما إذا كان هناك تركيز على الحقل أم لا. بعد ذلك ، بناءً على هذه الحالة ، يمكننا اختيار مكان وضع النقوش وما هي الأساليب التي يجب تطبيقها عليها.
نظرًا لأن النقش يجب أن يكون في أماكن مختلفة ، ونحن لا نريد أن يؤثر ذلك على موضع المكونات ، فإننا سنضعه تمامًا. للتأكد من أن هناك مساحة كافية لذلك ، يجب عليك إضافة مسافة بادئة من الأعلى إلى عرض الالتفاف.
class FloatingLabelInput extends Component { state = { isFocused: false, }; handleFocus = () => this.setState({ isFocused: true }); handleBlur = () => this.setState({ isFocused: false }); render() { const { label, ...props } = this.props; const { isFocused } = this.state; const labelStyle = { position: 'absolute', left: 0, top: !isFocused ? 18 : 0, fontSize: !isFocused ? 20 : 14, color: !isFocused ? '#aaa' : '#000', }; return ( <View style={{ paddingTop: 18 }}> <Text style={labelStyle}> {label} </Text> <TextInput {...props} style={{ height: 26, fontSize: 20, color: '#000', borderBottomWidth: 1, borderBottomColor: '#555' }} onFocus={this.handleFocus} onBlur={this.handleBlur} /> </View> ); } }
<FloatingLabelInput label="Email" value={this.state.value} onChange={this.handleTextChange} />
بعد الخطوات السابقة ، يمكننا تحقيق ما يلي:
https://snack.expo.io/Sk006AbdW؟session_id=snack-session-JRMksbYK3وهذه نقطة انطلاق جيدة. ليس لدينا حتى الآن رسوم متحركة ، لكن يمكننا بالفعل تغيير موقع النقش بناءً على مكان التركيز.
لماذا لا تستخدم placeholder
؟
بالطبع ، يبدو استخدام خاصية TextInput
النائب TextInput
مغريًا. ومع ذلك ، لن ينجح هذا ، لأننا نريد التحكم في كيفية ومتى وأين يتم عرض النقش.
بدلاً من ذلك ، نريد أن تكون التسمية داخل مربع النص عندما يكون التركيز عليها. ونريد أن يتحرك للأعلى عندما يظهر التركيز على حقل الإدخال ، ولا يمكن تحقيق ذلك إلا إذا عملنا مع نفس العنصر.
ماذا عن الرسوم المتحركة؟
في الواقع بقي الجزء الأسهل.
نظرًا لأن لدينا حالتين قد يكون هناك نقش فيه ، ونختار واحدة ، اعتمادًا على التركيز ، وتكون الرسوم المتحركة لهذا الانتقال بين الولايات نفسها تافهة للغاية.
من هذا
الدليل ، يمكننا تسليط الضوء على ما يلي:
Animated.Value
تعني ما إذا كان هناك تركيز على الحقل (1) أم لا (0) ؛- سنقوم بتغيير الرقم تدريجياً إلى (1) عند التركيز و (0) على خلاف ذلك ؛
- في شكل هذا الرقم ، سنعكس نمط النقش: في (0) و (1) سنحدد الأنماط ، وسيقوم React Native تلقائيًا بحساب وتطبيق الأنماط الوسيطة. وحتى الألوان.
لتنفيذ كل هذا ليس بالأمر الصعب.
Animated.Value
سنحتاج إلى التهيئة في
componentWillMount
.
componentWillMount() { this._animatedIsFocused = new Animated.Value(0); }
بعد ذلك ، نظرًا لأن قيمة هذا الرقم يجب أن تستند إلى ما إذا كان هناك تركيز على حقل الإدخال أم لا ، ولأن لدينا بالفعل معلومات الحالة هذه ، فيمكننا إضافة دالة
componentDidUpdate
، والتي ستغير هذا الرقم وفقًا
this.state
componentDidUpdate() { Animated.timing(this._animatedIsFocused, { toValue: this.state.isFocused ? 1 : 0, duration: 200, }).start(); }
الآن ، لنعكس نمط النقش في هذه الشروط ، نحتاج إلى إجراء تغييرين فقط:
التغيير إلى
Animated.Text
.
بدلاً من استخدام الشروط لتعريف الأنماط ، قم بتعريفها على النحو التالي:
const labelStyle = { position: 'absolute', left: 0, top: this._animatedIsFocused.interpolate({ inputRange: [0, 1], outputRange: [18, 0], }), fontSize: this._animatedIsFocused.interpolate({ inputRange: [0, 1], outputRange: [20, 14], }), color: this._animatedIsFocused.interpolate({ inputRange: [0, 1], outputRange: ['#aaa', '#000'], }), };
https://snack.expo.io/Hk8VCR-dZ؟session_id=snack-session-AJ4vulSVwشيء آخر
إذا حاولت في العرض التوضيحي أعلاه إدخال شيء ما ، ثم أزل التركيز من حقل الإدخال ، فسترى شيئًا غريبًا.

لحسن الحظ ، هذا سهل الإصلاح. نحن فقط بحاجة إلى تغيير سطرين في التعليمات البرمجية.
نريد التحقق مما إذا كان حقل الإدخال فارغًا وتغيير الحالة إلى
"غير مركَّزة" فقط في حالة تحقق الشرطين التاليين:
- حقل الإدخال فارغ ؛
- لا يوجد تركيز على هذا المجال.
بخلاف ذلك ، نريد تطبيق النمط
"المركّز" وأن ترتفع التسمية التوضيحية البديلة.
الآن
this.props
بتتبع حالة
حقل الإدخال ، يمكننا الوصول بسهولة إلى قيمته باستخدام
this.props
.
https://snack.expo.io/ByZBAC-dZ؟session_id=snack-session-YNZSqhqOC
هذا كل شيء. أراك في
الندوة المجانية .