الفرق بين المراجعتين لصفحة: «ReactNative/handling touches»

من موسوعة حسوب
طلا ملخص تعديل
 
(4 مراجعات متوسطة بواسطة 3 مستخدمين غير معروضة)
سطر 1: سطر 1:
<noinclude>{{DISPLAYTITLE:التعامل مع اللمسات في React Native}}</noinclude>
<noinclude>{{DISPLAYTITLE:التعامل مع اللمسات في React Native}}</noinclude>يتفاعل المستخدمون مع تطبيقات الجوال من خلال اللمس، كما يمكنهم استخدام مزيجٍ من الإيماءات (gestures)، مثل الضغط على زرٍّ أو تصفّح قائمةٍ عبر التمرير (scrolling) أو تكبير خريطةٍ وما إلى ذلك. يوفر React Native مكوّناتٍ للتعامل مع مختلف أنواع الإيماءات الشائعة، بالإضافة إلى [[ReactNative/gesture responder system|نظامِ مجيبِ إيماءاتٍ]] (gesture responder system) شاملٍ يسمح بالتعرف على إيماءاتٍ أكثر تقدمًا، ولكن الزرّ البسيطَ هو الأهمّ في البداية.
==التعامل مع اللمسات (Touches)==
يتفاعل المستخدمون مع تطبيقات الجوال من خلال اللمس. يمكنهم استخدام مزيج من الإيماءات (gestures)، كالضغط على زرٍّ أو تصفّح قائمة عبر التمرير (scrolling) أو تكبير خريطةٍ وما إلى ذلك. يوفر React Native مكوّناتٍ للتعامل مع مختلف أنواع الإيماءات الشائعة، بالإضافة إلى [[ReactNative/gesture responder system|نظامِ مجيبِ إيماءاتٍ]] (gesture responder system) شاملٍ للسماح بالتعرف على إيماءات أكثر تقدمًا، ولكن الزرّ البسيطَ هو الأهمّ في البداية.


==عرض زر بسيط==
==عرض زر بسيط==
المُكوّنُ <code>[[ReactNative/button|Button]]</code> مكوّنُ زرٍّ أساسي يُعرَض بشكل جميل على جميع المنصّات. هذا مثال لزر بسيط:
المُكوّنُ <code>[[ReactNative/button|Button]]</code> مكوّنُ زرٍّ أساسيٌّ يُعرَض بشكل جميل على جميع المنصّات. هذا مثالٌ لزرٍّ بسيطٍ:
<syntaxhighlight lang="javascript">
<syntaxhighlight lang="javascript">
<Button
<Button
   onPress={() => {
   onPress={() => {
     Alert.alert('لقد ضغطت على الزر');
     alert('لقد ضغطت على الزر');
   }}
   }}
   title="اضغط هنا"
   title="اضغط هنا"
/>
/>
</syntaxhighlight>
</syntaxhighlight>
سيعرض المثال أعلاه لافتةً زرقاء (label) على نظام iOS، ومستطيلًا أزرقًا مستديرًا مع نص أبيض على Android. سيستدعي الضغط على الزر الدّالةَ ‎<code>onPress</code>‎، والتي تعرض في هذه الحالة نافذة تنبيه منبثقة. إن أردت تغيير لون الزر فيمكنك ذلك عبر تمرير لونٍ إلى الخاصيّة ‎<code>color</code>‎.
سيعرض المثال أعلاه لافتةً زرقاء (label) على نظام iOS، ومستطيلًا أزرقَ مستديرًا مع نصٍّ أبيضَ على Android. سيستدعي الضغط على الزر الدّالةَ ‎"onPress"‎، والتي تعرض في هذه الحالة نافذة تنبيهٍ منبثقة. إن أردت تغيير لون الزر فيمكنك ذلك عبر تمرير لونٍ إلى الخاصيّة ‎<code>color</code>‎.
[[ملف:Button.png|مركز|لاإطار]]
[[ملف:Button.png|مركز|لاإطار]]
 
يُمكنك استكشاف المكوّن ‎<code>Button</code>‎ باستخدام المثال أدناه، ويمكنك تحديد المنصّة التي ستعاين فيها التطبيق عبر مفتاح التبديل في الجزء السفليّ الأيمن، ثم النقر على "Tap to Play" لمعاينة التطبيق، انظر المثال التالي ([https://snack.expo.dev/@hsoubwiki/button-basics---handling-touches تجربة حية]):
[Button.png]
 
يُمكنك استكشاف المكوّن ‎<code>Button</code>‎ باستخدام المثال أدناه. يمكنك في [https://facebook.github.io/react-native/docs/handling-touches هذه الصفحة] تحديد المنصّة عبر مفتاح التبديل بجوار (Platform) في الجزء السفلي الأيمن، ثم النقر على "Tap to Play" لمعاينة التطبيق.


<syntaxhighlight lang="javascript">
<syntaxhighlight lang="javascript">
import React, { Component } from 'react';
import React, { Component } from 'react';
import { Alert, AppRegistry, Button, StyleSheet, View } from 'react-native';
import { Button, StyleSheet, View } from 'react-native';


export default class ButtonBasics extends Component {
export default class ButtonBasics extends Component {
   _onPressButton() {
   _onPressButton() {
     Alert.alert('You tapped the button!')
     alert('You tapped the button!')
   }
   }


سطر 75: سطر 71:
   }
   }
});
});
// تخطّ هذا السطر إن كنت تستعمل أداة
// Create React Native App
AppRegistry.registerComponent('AwesomeProject', () => ButtonBasics);
</syntaxhighlight>
</syntaxhighlight>


==المكونات القابلة لللمس (Touchables)==
==المكونات القابلة للمس (Touchables)==
إذا لم يُلائم الزر الأساسي أعلاه تطبيقك، فيمكنك إنشاء زرّ خاص بك باستخدام أي من المكونات القابلة لللمس التي يوفرها React Native. توفر المكونات القابلة لللمس القدرة على التقاط اللمسات والإيماءات، ويمكنها عرض استجابة أو ردّة فعل (feedback) عند التعرف على إيماءة معيّنة. لكنّ هذه المكونات لا تأتي مع تنسيقٍ افتراضيًّا، لذا ستحتاج إلى بذل بعض الجهد لتنسيقها وتجميلها في تطبيقك.
إذا لم يُلائم الزر الأساسي أعلاه تطبيقك يمكنك إنشاء زرٍّ خاصٍّ بك باستخدام أيٍّ من المكونات القابلة للّمس التي يوفرها React Native، والتي توفر القدرة على التقاط اللمسات والإيماءات، ويمكنها عرض استجابةٍ أو ردّة فعل (feedback) عند التعرف على إيماءةٍ معيّنةٍ. لكنّ هذه المكونات لا تأتي مع تنسيقٍ افتراضيٍّ، لذا ستحتاج إلى بذل بعض الجهد لتنسيقها وتجميلها في تطبيقك.


يعتمد المكوّن القابل لللمس الذي ستستخدمه على نوع الاستجابة التي تريد تقديمها للمستخدم:
يعتمد المكوّن القابل للّمس الذي ستستخدمه على نوع الاستجابة التي تريد تقديمها للمستخدم:


* عمومًا، يمكنك استخدام المكوّن <code>[[ReactNative/touchablehighlight|TouchableHighlight]]</code> في أي مكان تستخدم فيه زرًا أو رابطًا على الويب. سيتم تعتيم خلفية العرض (view) عندما يضغط المستخدم على الزر.
* عمومًا، يمكنك استخدام المكوّن <code>[[ReactNative/touchablehighlight|TouchableHighlight]]</code> في أي مكان تستخدم فيه زرًا أو رابطًا على الويب، سيتم تعتيم خلفية الواجهة (view) عندما يضغط المستخدم على الزر.
* يمكنك استخدام [[ReactNative/touchablenativefeedback|<code>TouchableNativeFeedback</code>]] على Android لعرض تموجات تستجيب للمسة المستخدم.
* يمكنك استخدام [[ReactNative/touchablenativefeedback|<code>TouchableNativeFeedback</code>]] على Android لعرض تموّجات تستجيب للمسة المستخدم.
* يمكنك استخدام <code>[[ReactNative/touchableopacity|TouchableOpacity]]</code> لتوفير استجابة عبر تخفيض تعتيم الزر وزيادة شفافيّته، ما يسمح برؤية الخلفية أثناء ضغط المستخدم على الزرّ.
* يمكنك استخدام <code>[[ReactNative/touchableopacity|TouchableOpacity]]</code> لتخفيض تعتيم الزر وزيادة شفافيّته، مما يسمح برؤية الخلفية أثناء ضغط المستخدم على الزرّ.
* إن أردت التعامل مع لمسة دون عرض استجابة أو ردّة فعل للمستخدم، فاستخدم <code>[[ReactNative/touchablewithoutfeedback|TouchableWithoutFeedback]]</code>.
* إن أردت التعامل مع لمسة دون عرض استجابة أو ردّة فعل للمستخدم، فاستخدم <code>[[ReactNative/touchablewithoutfeedback|TouchableWithoutFeedback]]</code>.
قد ترغب في بعض الحالات باكتشاف ما إذا ضغطَ المستخدم على عرضٍ وأبقى إِصْبَعَهُ لفترة محددة من الوقت (أي ضغطة مُطوَّلة [long press]). يمكن التعامل مع هذه الضغطات المطوّلة بتمرير دالّة إلى الخاصيّة ‎<code>onLongPress</code>‎ لأي من المكونات القابلة لللمس.
قد ترغب في بعض الحالات باكتشاف ضغط المستخدم على واجهةٍ مع إبقائه إِصْبَعَهُ لفترةٍ محدّدةٍ من الوقت (أي ضغطة مُطوَّلة [long press]). يمكن التعامل مع هذه الضغطات المطوّلة بتمرير دالّة إلى الخاصيّة ‎<code>onLongPress</code>‎ لأي من المكونات القابلة للمس.


===أمثلة===
لنعاين كل ما سبق في المثال التالي ([https://snack.expo.dev/@hsoubwiki/touchables-handling-touches تجربة حية]):<syntaxhighlight lang="javascript">
<syntaxhighlight lang="javascript">
import React, { Component } from 'react';
import React, { Component } from 'react';
import { Alert, AppRegistry, Platform, StyleSheet, Text, TouchableHighlight, TouchableOpacity, TouchableNativeFeedback, TouchableWithoutFeedback, View } from 'react-native';
import { Platform, StyleSheet, Text, TouchableHighlight, TouchableOpacity, TouchableNativeFeedback, TouchableWithoutFeedback, View } from 'react-native';


export default class Touchables extends Component {
export default class Touchables extends Component {
   _onPressButton() {
   _onPressButton() {
     Alert.alert('You tapped the button!')
     alert('You tapped the button!')
   }
   }


   _onLongPressButton() {
   _onLongPressButton() {
     Alert.alert('You long-pressed the button!')
     alert('You long-pressed the button!')
   }
   }


سطر 124: سطر 115:
             background={Platform.OS === 'android' ? TouchableNativeFeedback.SelectableBackground() : ''}>
             background={Platform.OS === 'android' ? TouchableNativeFeedback.SelectableBackground() : ''}>
           <View style={styles.button}>
           <View style={styles.button}>
             <Text style={styles.buttonText}>TouchableNativeFeedback</Text>
             <Text style={styles.buttonText}>TouchableNativeFeedback {Platform.OS !== 'android' ? '(Android only)' : ''}</Text>
           </View>
           </View>
         </TouchableNativeFeedback>
         </TouchableNativeFeedback>
سطر 156: سطر 147:
   },
   },
   buttonText: {
   buttonText: {
    textAlign: 'center',
     padding: 20,
     padding: 20,
     color: 'white'
     color: 'white'
   }
   }
});
});
</syntaxhighlight>
==التمرير (Scrolling) والسحب (swiping)==
السحب (swipe) أو المسح (pan) إيماءةٌ أخرى شائعة الاستخدام في الأجهزة ذات الشاشات القابلة للمس، تسمح هذه الإيماءة للمستخدم بالتمرير (scroll) عبر قائمةٍ تحوي عدّة عناصر، أو التمرير للتنقّل بين الصفحات، لذلك لنتعرّف على [[ReactNative/using a scrollview|كيفية استخدام المكوّن ‎<code>ScrollView</code>‎]].
== مشكلات شائعة ==
* المشكلة [https://github.com/facebook/react-native/issues/29308#issuecomment-792864162 react-native#29308]: لا تمتد منطقة اللمس خارج حدود الواجهة الأب، كما لا تُقبل قيمة سالبة للهوامش في نظام Android.


// تخطّ هذا السطر إن كنت تستعمل أداة
// Create React Native App
AppRegistry.registerComponent('AwesomeProject', () => Touchables);
</syntaxhighlight>
==قوائم التمرير (Scrolling lists)، سحب الصفحات (swiping pages)، والتكبير عبر القرص (pinch-to-zoom)==
السحب (swipe) أو المسح (pan) إيماءةٌ أخرى شائعة الاستخدام في تطبيقات الجوّال. تسمح هذه الإيماءة للمستخدم بالتمرير (scroll) عبر قائمةٍ تحتوي على عدّة عناصر، أو التمرير للتنقّل بين الصفحات. للتعامل مع هذه الإيماءات وغيرها، لنتعرّف على [[ReactNative/using a scrollview|كيفية استخدام المكوّن ‎<code>ScrollView</code>‎]].
== مصادر ==
== مصادر ==
* [Handling Touches صفحة https://facebook.github.io/react-native/docs/handling-touches في توثيق React Native الرسمي.]
* [https://facebook.github.io/react-native/docs/handling-touches صفحة Handling Touches في توثيق React Native الرسمي]
[[تصنيف:ReactNative]]
[[تصنيف:ReactNative]]
[[تصنيف:React Native Docs]]

المراجعة الحالية بتاريخ 13:43، 9 أكتوبر 2021

يتفاعل المستخدمون مع تطبيقات الجوال من خلال اللمس، كما يمكنهم استخدام مزيجٍ من الإيماءات (gestures)، مثل الضغط على زرٍّ أو تصفّح قائمةٍ عبر التمرير (scrolling) أو تكبير خريطةٍ وما إلى ذلك. يوفر React Native مكوّناتٍ للتعامل مع مختلف أنواع الإيماءات الشائعة، بالإضافة إلى نظامِ مجيبِ إيماءاتٍ (gesture responder system) شاملٍ يسمح بالتعرف على إيماءاتٍ أكثر تقدمًا، ولكن الزرّ البسيطَ هو الأهمّ في البداية.

عرض زر بسيط

المُكوّنُ Button مكوّنُ زرٍّ أساسيٌّ يُعرَض بشكل جميل على جميع المنصّات. هذا مثالٌ لزرٍّ بسيطٍ:

<Button
  onPress={() => {
    alert('لقد ضغطت على الزر');
  }}
  title="اضغط هنا"
/>

سيعرض المثال أعلاه لافتةً زرقاء (label) على نظام iOS، ومستطيلًا أزرقَ مستديرًا مع نصٍّ أبيضَ على Android. سيستدعي الضغط على الزر الدّالةَ ‎"onPress"‎، والتي تعرض في هذه الحالة نافذة تنبيهٍ منبثقة. إن أردت تغيير لون الزر فيمكنك ذلك عبر تمرير لونٍ إلى الخاصيّة ‎color‎.

يُمكنك استكشاف المكوّن ‎Button‎ باستخدام المثال أدناه، ويمكنك تحديد المنصّة التي ستعاين فيها التطبيق عبر مفتاح التبديل في الجزء السفليّ الأيمن، ثم النقر على "Tap to Play" لمعاينة التطبيق، انظر المثال التالي (تجربة حية):

import React, { Component } from 'react';
import { Button, StyleSheet, View } from 'react-native';

export default class ButtonBasics extends Component {
  _onPressButton() {
    alert('You tapped the button!')
  }

  render() {
    return (
      <View style={styles.container}>
        <View style={styles.buttonContainer}>
          <Button
            onPress={this._onPressButton}
            title="Press Me"
          />
        </View>
        <View style={styles.buttonContainer}>
          <Button
            onPress={this._onPressButton}
            title="Press Me"
            color="#841584"
          />
        </View>
        <View style={styles.alternativeLayoutButtonContainer}>
          <Button
            onPress={this._onPressButton}
            title="This looks great!"
          />
          <Button
            onPress={this._onPressButton}
            title="OK!"
            color="#841584"
          />
        </View>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
   flex: 1,
   justifyContent: 'center',
  },
  buttonContainer: {
    margin: 20
  },
  alternativeLayoutButtonContainer: {
    margin: 20,
    flexDirection: 'row',
    justifyContent: 'space-between'
  }
});

المكونات القابلة للمس (Touchables)

إذا لم يُلائم الزر الأساسي أعلاه تطبيقك يمكنك إنشاء زرٍّ خاصٍّ بك باستخدام أيٍّ من المكونات القابلة للّمس التي يوفرها React Native، والتي توفر القدرة على التقاط اللمسات والإيماءات، ويمكنها عرض استجابةٍ أو ردّة فعل (feedback) عند التعرف على إيماءةٍ معيّنةٍ. لكنّ هذه المكونات لا تأتي مع تنسيقٍ افتراضيٍّ، لذا ستحتاج إلى بذل بعض الجهد لتنسيقها وتجميلها في تطبيقك.

يعتمد المكوّن القابل للّمس الذي ستستخدمه على نوع الاستجابة التي تريد تقديمها للمستخدم:

  • عمومًا، يمكنك استخدام المكوّن TouchableHighlight في أي مكان تستخدم فيه زرًا أو رابطًا على الويب، سيتم تعتيم خلفية الواجهة (view) عندما يضغط المستخدم على الزر.
  • يمكنك استخدام TouchableNativeFeedback على Android لعرض تموّجات تستجيب للمسة المستخدم.
  • يمكنك استخدام TouchableOpacity لتخفيض تعتيم الزر وزيادة شفافيّته، مما يسمح برؤية الخلفية أثناء ضغط المستخدم على الزرّ.
  • إن أردت التعامل مع لمسة دون عرض استجابة أو ردّة فعل للمستخدم، فاستخدم TouchableWithoutFeedback.

قد ترغب في بعض الحالات باكتشاف ضغط المستخدم على واجهةٍ مع إبقائه إِصْبَعَهُ لفترةٍ محدّدةٍ من الوقت (أي ضغطة مُطوَّلة [long press]). يمكن التعامل مع هذه الضغطات المطوّلة بتمرير دالّة إلى الخاصيّة ‎onLongPress‎ لأي من المكونات القابلة للمس.

لنعاين كل ما سبق في المثال التالي (تجربة حية):

import React, { Component } from 'react';
import { Platform, StyleSheet, Text, TouchableHighlight, TouchableOpacity, TouchableNativeFeedback, TouchableWithoutFeedback, View } from 'react-native';

export default class Touchables extends Component {
  _onPressButton() {
    alert('You tapped the button!')
  }

  _onLongPressButton() {
    alert('You long-pressed the button!')
  }


  render() {
    return (
      <View style={styles.container}>
        <TouchableHighlight onPress={this._onPressButton} underlayColor="white">
          <View style={styles.button}>
            <Text style={styles.buttonText}>TouchableHighlight</Text>
          </View>
        </TouchableHighlight>
        <TouchableOpacity onPress={this._onPressButton}>
          <View style={styles.button}>
            <Text style={styles.buttonText}>TouchableOpacity</Text>
          </View>
        </TouchableOpacity>
        <TouchableNativeFeedback
            onPress={this._onPressButton}
            background={Platform.OS === 'android' ? TouchableNativeFeedback.SelectableBackground() : ''}>
          <View style={styles.button}>
            <Text style={styles.buttonText}>TouchableNativeFeedback {Platform.OS !== 'android' ? '(Android only)' : ''}</Text>
          </View>
        </TouchableNativeFeedback>
        <TouchableWithoutFeedback
            onPress={this._onPressButton}
            >
          <View style={styles.button}>
            <Text style={styles.buttonText}>TouchableWithoutFeedback</Text>
          </View>
        </TouchableWithoutFeedback>
        <TouchableHighlight onPress={this._onPressButton} onLongPress={this._onLongPressButton} underlayColor="white">
          <View style={styles.button}>
            <Text style={styles.buttonText}>Touchable with Long Press</Text>
          </View>
        </TouchableHighlight>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    paddingTop: 60,
    alignItems: 'center'
  },
  button: {
    marginBottom: 30,
    width: 260,
    alignItems: 'center',
    backgroundColor: '#2196F3'
  },
  buttonText: {
    textAlign: 'center',
    padding: 20,
    color: 'white'
  }
});

التمرير (Scrolling) والسحب (swiping)

السحب (swipe) أو المسح (pan) إيماءةٌ أخرى شائعة الاستخدام في الأجهزة ذات الشاشات القابلة للمس، تسمح هذه الإيماءة للمستخدم بالتمرير (scroll) عبر قائمةٍ تحوي عدّة عناصر، أو التمرير للتنقّل بين الصفحات، لذلك لنتعرّف على كيفية استخدام المكوّن ‎ScrollView.

مشكلات شائعة

  • المشكلة react-native#29308: لا تمتد منطقة اللمس خارج حدود الواجهة الأب، كما لا تُقبل قيمة سالبة للهوامش في نظام Android.

مصادر