TabBar animé de Coinbase dans React Native
Présentation de l’expérience utilisateur «TabBar»
Vous avez probablement utilisé cette interaction d’innombrables fois dans votre vie quotidienne et vous n’avez pas passé beaucoup de temps à y penser. Vous le voyez sur des éléments tels que Instagram, Twitter, Apple Music ET, plus récemment, sur l’écran des prix de Coinbase.
Il s’agit d’un élément d’onglet simple, avec un en-tête déroulant et une barre d’onglets qui s’épinglent en haut de l’écran. Il vous permet de faire défiler les différents TabViews et traite intelligemment la position de défilement globale (c’est-à-dire que si vous faites défiler l’en-tête sur un TabView, le changement d’onglet maintient l’en-tête global dans la même position, quel que soit le défilement de l’onglet).
Cependant, malgré le fait que cette expérience UX soit devenue universelle, dans les coulisses, elle nécessite encore une grande quantité de gestes complexes et de gestion des états pour que cela se sente et fonctionne «parfaitement» pour l’utilisateur final.
ainsi que le code nécessaire pour y arriver.
Glossaire des termes UX
Nous avons également extrait un exemple de projet compagnon simple – que vous pouvez utiliser pour suivre ou aider à créer votre propre version de travail de cette expérience.
/li>/li>
Guide des interactions
Il existe une poignée d’interactions clés qui permettent de donner à TabView une apparence et une sensation organiques. Un grand nombre de ces comportements ont été identifiés grâce à l’étude d’implémentations externes telles que Twitter et Instagram, ainsi que d’applications et de spécifications spécifiques à des plates-formes telles que HIG d’Apple et Material Design de Google.
Voici une liste d’interactions clés (que vous trouverez toutes dans notre exemple de projet sur github). Étudiez le gif ci-dessus pour voir si vous pouvez choisir chacun de ces comportements subtils.
Cette transformation donne l’apparence visuelle du défilement de l’en-tête avec TabBar et TabViews vers le haut et hors de la page, sans réellement faire défiler la page (plus d’informations sur la gestion de la position de défilement et la complexité qui en découle dans les détails de mise en œuvre ci-dessous)
pour donner l’effet que les onglets sont épinglés sous la NavBar
/li>
Mise en œuvre
visant à maintenir les interactions clés telles que la navigation, les gestes, etc. à 60 ips. Pour ce faire dans React Native, il est impératif à la fois de limiter le trafic des ponts (en réduisant les animations pilotées par JS) et de réduire les cycles de rendu (mettre à jour au minimum l’API d’état / de contexte).
en ajoutant l’extrait ci-dessous à TabView onScroll un événement.
com/media//hrefRemarque : nous mettons à jour l’événement scrollY ici en fonction de l’activation ou non d’un onglet donné. Cela garantit qu’il n’y a jamais qu’un seul TabView mettant à jour les positions de défilement à un moment donné.
Lorsque cette valeur change Étant donné que notre barre de navigation est fixée en haut de l’écran
com/media//href2. L’en-tête doit glisser vers le haut et hors de l’écran (sous la NavBar) lors du défilement.
Value mise à jour à 0.3 et exécutions l’interpolation ci-dessous, la sortie interpolée serait 30.
com/media//hrefDans cet esprit, considérons notre interpolation d’en-tête.
com/media//hrefIci
Cependant, il y a un peu de nuance ici en raison de la façon dont iOS traite 3 scénarios: tirer pour actualiser, bande élastique et défilement excessif.
Cela permet à notre spinner «tirer pour actualiser» de se dérouler correctement sous notre en-tête (visuellement en haut de TabView).
Nous pouvons nous en sortir sur Android, car il n’y a pas de défilement excessif.
com/media//hrefEn revenant à notre interpolation d’en-tête, le inputRange utilisé doit être différent pour iOS (pour tenir compte du contentOffset). Spécifiquement:
com/media//hrefLa dernière chose à noter ici est que nous interpolons ces valeurs d’entrée (ScrollOffset à ScrollOffset + Header) à une plage de sortie de (0 à une hauteur d’en-tête négative)
Le résultat est que lorsque vous faites défiler TabView, l’en-tête sera transformé vers le haut et hors de l’écran jusqu’à ce qu’il soit complètement masqué (en-tête négatif), et pas plus.
com/media//href3. Le TabBar doit glisser vers le haut, puis épingler sur le bord inférieur de la NavBar.
haut: 0}
puis c’est la position de rendu naturelle (contrairement à ce que nous avons fait avec notre composant Header) C’est pourquoi notre plage de sortie dans l’invocation ci-dessous définit une transformation initiale de la hauteur de l’en-tête et la convertit en sa position épinglée finale épinglée de 0.
com/media//href4. Une fois que la TabBar est épinglée, une bordure inférieure doit être estompée pour ajouter de la profondeur aux TabViews glissant en dessous.
Cela garantit que la bordure ne commence pas à s’effacer tant que l’en-tête n’a pas été défilé hors de la vue, et qu’elle est complètement estompée au moment où les enfants TabView défilent en dessous.
Nous interpolons ensuite la valeur en une outputRange de 0 à 1, qui est la plage de valeurs de la propriété opacity dans React Native.
com/media//href5. TabView doit glisser vers le haut et épingler directement sous la TabBar, garantissant que chaque fois que vous glissez ou naviguez entre les TabViews, la hauteur de l’en-tête est toujours correctement maintenue
C’est sans doute la pièce la plus difficile de toute cette architecture. S’appuyer sur une seule valeur ScrollY simplifie grandement les interpolations ci-dessus, mais cela devient problématique dès que vous commencez à prendre en compte les TabViews inactives. Si vous ne faites rien pour synchroniser de manière proactive les vues de défilement inactives, la navigation entre les TabViews affichera des positions de défilement à des emplacements incorrects (car les TabViews inactives n’auront pas compensé l’affichage ou le masquage de l’en-tête).
com/media//href2. La touche TABL’identifiant de l’onglet, fourni par notre bibliothèque d’onglets réaction-native-tab-view et transmis aux composants TabView individuels.
com/media//href3. Il s’agit d’une carte d’identifiants d’onglets en références de composants à défilement (TabViews). Il sera utilisé plus tard pour mettre à jour passivement tous les décalages de défilement TabView inactifs.
com/media//href4. Il s’agit d’une carte des identificateurs d’onglets avec leur position de défilement locale. Il sera utilisé pour comparer les scrollPositions mises en cache aux décalages d’en-tête pour déterminer si les décalages de défilement TabViews inactifs doivent être ajustés.
com/media//hrefPour commencer à synchroniser les décalages de défilement Lorsque vous transmettez une méthode à la prop ref dans React, la méthode entrante est appelée avec une référence au composant. Nous prenons ensuite cette référence, ainsi qu’une table locale de TabView La touche TAB référence (transmise par réaction-native-tab-view ), et appelez notre trackRefméthode.
com/media//hrefEnsuite Cela nous permet de savoir où tous nos onglets défilent (même les onglets inactifs) à un moment donné.
com/media//hrefLa dernière étape pour synchroniser les décalages de défilement consiste à utiliser onMomentumScrollEndet onScrollEndDragévénements pour invoquer une méthode personnalisée que nous appelons syncScrollOffset.
SyncScrollOffset parcourt les TabKeys inactifs et met à jour leurs décalages de défilement selon que l’en-tête défile dans ou hors de la vue. Cela garantira que chaque fois que vous glissez ou naviguez entre les TabViews, la hauteur de l’en-tête est toujours correctement maintenue.
com/media//href
Résumé
Une partie importante de notre transition des technologies natives vers React Native a été non seulement de maintenir notre barre de qualité, mais aussi de l’augmenter. Cela se produit grâce à des investissements UX profonds, à notre système de conception multiplateforme, etc.
nous recrutons !
tels que l’intégration de milliers d’utilisateurs avec React Native et l’optimisation de React Native.
Les sites tiers ne sont pas sous le contrôle de Coinbase, Inc. et de ses affiliés («Coinbase»), et Coinbase n’est pas responsable du contenu de tout site tiers, y compris, sans s’y limiter, tout lien contenu dans un tiers. Site de partie, ou toute modification ou mise à jour d’un site tiers. Coinbase n’est pas responsable de la diffusion sur le Web ou de toute autre forme de transmission reçue d’un site tiers. Coinbase ne vous fournit ces liens qu’à titre de commodité, et l’inclusion de tout lien n’implique pas l’approbation, l’approbation ou la recommandation par Coinbase du site ou de toute association avec ses opérateurs.
Toutes les images fournies ici sont de Coinbase.
La TabBar animée de Coinbase dans React Native a été publiée à l’origine dans The Coinbase Blog on Medium, où les gens poursuivent la conversation en mettant en évidence et en répondant à cette histoire.