La belleza de React Native: creación de su primera aplicación para iOS con JavaScript (Parte 2)

 

 

 

  • SmashingConf UX y diseño, Amberes 2024
  • Clase magistral de diseño para una interfaz de usuario compleja, con Vitaly Friedman
  • En esta parte del tutorial, Nash Vail comenzará reemplazando el nombre del fotógrafo con la imagen de fondo de pantalla real junto con los créditos correspondientes. Durante este proceso, aprenderá cómo vincular una biblioteca en Xcode, así como más información sobre el estilo general y el posicionamiento de los elementos de la interfaz de usuario. Aprenderá cómo guardar imágenes en Camera Roll y también cómo ejecutar su aplicación en un dispositivo físico. Para aplicar todas las habilidades de React Native recién aprendidas, hay un desafío esperándote al final. Al igual que la primera parte, este artículo consta de cinco secciones. Completar cada sección nos acerca un paso más a terminar nuestra aplicación.

     

    En la parte 1 de este tutorial , comenzamos a crear nuestra aplicación para iOS desde cero. Comenzamos configurando un proyecto React Native en blanco. Luego extrajimos datos de la API Unsplash.it.

    Debido a que la descarga de datos lleva tiempo, creamos una pantalla de carga. En el proceso repasamos el posicionamiento de los elementos de la interfaz de usuario con flexbox y les aplicamos estilo usando propiedades similares a CSS. Hacia el final de la parte 1, descargamos e incluimos un componente de terceros Swiperde GitHub, que nos permitió mostrar datos del fondo de pantalla en un contenedor deslizable.

    No hace mucho todavía, pero todo eso está a punto de cambiar. En esta parte del tutorial comenzaremos reemplazando el nombre del fotógrafo con la imagen de fondo de pantalla real junto con los créditos correspondientes. Durante este proceso, aprenderá cómo vincular una biblioteca en Xcode, así como más información sobre el estilo general y el posicionamiento de los elementos de la interfaz de usuario. Luego, repasaremos la creación de un detector de doble toque personalizado utilizando la API PanResponder y un poco de matemáticas. Hacia el final, aprenderá cómo guardar imágenes en Camera Roll y también cómo ejecutar su aplicación en un dispositivo físico. Para aplicar todas las habilidades de React Native recién aprendidas, hay un desafío esperándote al final.

    Al igual que la primera parte, este artículo consta de cinco secciones. Completar cada sección nos acerca un paso más a terminar nuestra aplicación.

    1. Visualización de fondos de pantalla y créditos

    Echemos un vistazo a los datos que contiene cada objeto de fondo de pantalla. Considere los siguientes datos de muestra.

    { author: "Patryk Sobczak" author_url: "https://unsplash.com/patryksobczak" filename: "0611_bS92UkQY8xI.jpeg" format: "jpeg" height: 1280 id: 611 post_url: "https://unsplash.com/photos/bS92UkQY8xI" width: 1920}

    Para ver el fondo de pantalla, puede señalar en su navegador lo https://unsplash.it/{width}/{height}?image={id}que se traduce en este caso. Ese es un fondo de pantalla de alta calidad.https://unsplash.it/1920/1280?image=611

     

    Como podemos construir una URL para la imagen, podemos agregar un Imagecomponente con el sourceatributo adecuado.

    Pero no nos adelantemos. Los fondos de pantalla que obtenemos de Unsplash son de alta calidad y pueden tardar en cargarse. Si simplemente usamos Imageel componente de React Native, dejaremos a nuestros usuarios mirando una pantalla en blanco mientras se carga el fondo de pantalla. Aquí necesitamos un componente similar a una barra de progreso; afortunadamente, existe un componente precisamente para eso.

    Los dos componentes que utilizaremos para lograr nuestro objetivo son reaccionar-native-image-progress y reaccionar-native-progress .

    Dirígete al directorio del proyecto desde la terminal y ejecuta los siguientes dos comandos:

    npm install --save react-native-image-progress
    npm install --save react-native-progress

    Importémoslos a nuestro archivo index.ios.js . Agregue las siguientes dos líneas justo debajo de la use strict;declaración:

    var NetworkImage = require('react-native-image-progress');var Progress = require('react-native-progress');

    Dado que nuestras imágenes de fondo de pantalla cubren toda la ventana gráfica, necesitaremos saber el ancho y el alto de la ventana gráfica. Para hacer eso agregue:

    var {width, height} = React.Dimensions.get('window’);

    fuera de la declaración de clase y justo debajo de las declaraciones de importación. Si ha seguido atentamente, por supuesto sabrá que podemos sustituirlo React.Dimensionsagregando Dimensionsuna nueva línea al bloque de código de importación de React.

    var { AppRegistry, StyleSheet, Text, View, Component, ActivityIndicatorIOS,/***/ Dimensions // Add this line/***/} = React;

    Sólo ahorrando un par de pulsaciones de teclas, ya sabes.

    Ahora usaremos el NetworkImagecomponente en renderResults.

    Swiper ... {wallsJSON.map((wallpaper, index) = { return( /***/ View key={index} NetworkImage source={{uri: `https://unsplash.it/${wallpaper.width}/${wallpaper.height}?image=${wallpaper.id}`}} indicator={Progress.Circle} style={styles.wallpaperImage} /NetworkImage /View /***/ ); })}/Swiper

    Observe el valor que urise contiene dentro NetworkImagedel sourceatributo. Esta es una de las nuevas características de ES2015 llamada cadenas de plantilla . Las cadenas de plantilla le permiten incluir variables dentro de la cadena usando ${variableName}en lugar de concatenarlas una y otra vez usando +.

    Te lo diré de nuevo. ¡ ES2015 es genial!

    Agregue la siguiente definición de estilo a la stylesvariable:

    wallpaperImage: { flex: 1, width: width, height: height, backgroundColor: ‘#000’}

    Actualice el simulador y debería terminar con un montón de errores. No te preocupes, no rompimos nada. El compilador simplemente se queja de una biblioteca que necesita y no puede encontrar. Ayudemos al compilador.

     

    Al observar más de cerca el código que acabamos de agregar, observe que una de las NetworkImagepropiedades de es indicatory contiene el valor de Progress.Circle. Como se menciona en los documentos del componente en GitHub (no me digas que no leíste los documentos ), Progress.Circlerequiere ReactART, que es una biblioteca para dibujar gráficos vectoriales usando React. No necesitamos descargar nada nuevo aquí, solo incluirlo en nuestro proyecto, esta vez a través de Xcode.

    Al hacer clic en cualquiera de las imágenes a continuación, accederá a una versión más grande de esa imagen, lo que le dará una mejor idea de lo que está sucediendo.

    Concéntrate y presta mucha atención aquí.

    Dirígete a la siguiente ruta desde la raíz del proyecto: node_modules/react-native/Libraries/ART/

    ¿ Ves el archivo ART.xcodeproj ? Arrástrelo a Xcode en SplashWalls/Libraries .Bibliotecas." /A continuación, haga clic en Fases de compilación ubicadas en la parte superior junto con General , Capacidades y otros.Luego, arrastre libART.a desde ART.xcodeproj/Products a Link Binary With Libraries .(Nota al margen: generalmente dentro de la carpeta Productos de las bibliotecas nativas de React encontrará un único archivo .a . Para las bibliotecas que vincularemos en el futuro, asegúrese de arrastrar el único archivo .a dentro de la carpeta Productos a Vincular binario con Bibliotecas .) Eso es todo. Vincular bibliotecas es una lata (Pun Counter: 1). Ahora, actualiza el simulador. ¡Fresco! Ya tenemos los fondos de pantalla que aparecen con indicadores de carga y puedes deslizarte por ellos. ¿Tienes ganas de descargar uno? Mantengan sus caballos, estamos llegando. Actualmente, el indicador de progreso sigue la combinación de colores y la estética predeterminados. Cambiemos eso. Esto se hace agregando una nueva propiedad indicatorPropsal NetworkImagecomponente.

    NetworkImage source={{uri: `https://unsplash.it/${wallpaper.width}/${wallpaper.height}?image=${wallpaper.id}`}} indicator={Progress.Circle} style={styles.wallpaperImage} /***/ indicatorProps={{ color: 'rgba(255, 255, 255)', size: 60, thickness: 7 }} /***//NetworkImage

    Esto hará que el indicador de carga se vea así:Siéntete libre de jugar con los valores. Lo que te haga feliz lo que quieras. (10 puntos de Internet si obtienes la referencia 🙂 ) Ahora agreguemos los créditos de las imágenes. Inserte dos componentes de texto entre las etiquetas de apertura y cierre de ``como se muestra a continuación.

    NetworkImage.../***/ Text style={styles.label}Photo by/Text Text style={styles.label_authorName}{wallpaper.author}/Text/***//NetworkImage

    y agregue los siguientes estilos a la stylesvariable también:

    label: { position: 'absolute', color: '#fff', fontSize: 13, backgroundColor: 'rgba(0, 0, 0, 0.8)', padding: 2, paddingLeft: 5, top: 20, left: 20, width: width/2},label_authorName: { position: 'absolute', color: '#fff', fontSize: 15, backgroundColor: 'rgba(0, 0, 0, 0.8)', padding: 2, paddingLeft: 5, top: 41, left: 20, fontWeight: 'bold', width: width/2}

    Actualiza el simulador y ¡Bam! Tenemos los créditos de las fotos.Todo lo que hicimos para agregar los créditos de las fotografías es muy sencillo. No creo que haya nada que explicar aquí, ¿verdad? Con eso, hemos terminado con esta sección. Ahora es el momento de repasar lo que creo que es la sección más difícil de todo el tutorial. ## 2. Detección de dobles toques En esta sección nos aventuraremos en las tierras de PanResponder API. Esta API nos ayudará a hacer algunas cosas realmente interesantes, como detectar un doble toque. Si hubiéramos querido, podríamos haber puesto un botón de descarga sobre el fondo de pantalla: toque el botón de descarga y descargue el fondo de pantalla. Pero eso no es lo que hacen los adultos. Diseñaremos nuestro oyente de doble toque personalizado, escucharemos los dobles toques y luego descargaremos la imagen. Antes de comenzar, puede leer sobre la API PanResponder . Aunque no lo encontré muy útil. Todo tendrá sentido una vez que comencemos a usar la API. Mientras estamos en eso, debes saber que React Native nos proporciona dos API para manejar el tacto y los gestos: GestureResponder y PanResponder. PanResponder es la API de nivel superior y más cómoda de usar, por lo que nos quedaremos con ella. Basta de hablar, ensuciémonos las manos. Dentro del SplashWallconstructor declararemos un objeto literal en blanco. Escriba la siguiente línea justo después de this.statela llave de cierre de ':

     

    this.imagePanResponder = {};

    Luego agregue PanResponderel bloque de importaciones.

    var { AppRegistry, StyleSheet, Text, View, Component, ActivityIndicatorIOS, Dimensions,/***/ PanResponder/***/} = React;

    A partir de ahora, nuestro imagePanResponderes solo un objeto literal vacío, no tiene nada de especial. Lo que debemos hacer es convertirlo a PanRespondery luego conectarlo a nuestro ``componente, ya que ese es el componente en el que nos gustaría detectar dobles toques. Primero, hagamos que nuestro literal de objeto vacío sea especial. Para eso, escribiremos un nuevo método de ciclo de vida componentWillMount. Este método se activa automáticamente justo antes de que se produzca el renderizado inicial.

    componentWillMount() { this.imagePanResponder = PanResponder.create({ onStartShouldSetPanResponder: this.handleStartShouldSetPanResponder, onPanResponderGrant: this.handlePanResponderGrant, onPanResponderRelease: this.handlePanResponderEnd, onPanResponderTerminate: this.handlePanResponderEnd }); }

    Luego conectamos nuestro imagePanResponderal NetworkImagecomponente de esta manera:

    NetworkImage . . . {...this.imagePanResponder.panHandlers}

    Los tres puntos anteriores this.imagePanResponder.panHandlersson lo que se llama operador de extensión . Si aún no está familiarizado con él, puede leer más sobre él en Mozilla Developer Network. Para entender lo que está pasando necesitaremos profundizar un poco más en la API PanResponder. Cualquier evento táctil tiene tres etapas: inicio , movimiento y liberación ; y una Vista/Componente puede pretender ser el que responde a un evento táctil particular. Observe la primera clave dentro PanResponder.create({...que dice onStartShouldSetPanResponder. Como sugiere el nombre, esto es como si React Native preguntara si debería configurar PanResponder en esta vista cuando se registra o inicia un toque en ella. En otras palabras, ¿esta vista debería intentar reclamar el estado de respuesta táctil ? Establecemos el valor de esta clave en this.handleOnStartShouldSetPanResponder, que es un método que devolverá verdadero si queremos que la Vista reclame el estado de respondedor y falso en caso contrario. En nuestro caso, por supuesto, lo haremos realidad.

     

    handleStartShouldSetPanResponder(e, gestureState) { return true;}

    La siguiente clave es onPanResponderGrant, que contendrá una función que se activará una vez que a nuestra vista se le otorgue el estado de respondedor. Llamemos a esta función handlePanResponderGrant. Por ahora, simplemente hagamos que registre un mensaje en la consola.

    handlePanResponderGrant(e, gestureState) { console.log('Finger touched the image');}

    Las dos últimas teclas, que se explican por sí mismas, tienen el mismo valor handlePanResponderEnd, que es lo que sucede cuando se levanta un dedo del componente de respuesta. Por ahora, hagamos que registre un mensaje en la consola.

    handlePanResponderEnd(e, gestureState) { console.log('Finger pulled up from the image');}

    Actualiza el simulador. Una vez cargado un fondo de pantalla, haga clic en él y debería ver lo siguiente en la consola:¡Excelente! Ahora sabemos que nuestra configuración inicial está funcionando correctamente. Intentemos detectar un doble toque. Siempre que se registra un toque, es posible que el toque concluya un doble toque. Para comprobar si un toque finaliza un doble toque, necesitaremos tener acceso a la información del toque anterior: su ubicación ( coordenadas x e y ) y la marca de tiempo para ser precisos. Declare un nuevo objeto literal prevTouchInfojusto debajo del imagePanHandlerobjeto en el constructor. Películas en excelente calidad Full HD

    this.prevTouchInfo = { prevTouchX: 0, prevTouchY: 0, prevTouchTimeStamp: 0};

    Luego actualice handlePanResponderGrantpara parecerse a lo siguiente:

    handlePanResponderGrant(e, gestureState) {/***/ var currentTouchTimeStamp = Date.now(); if( this.isDoubleTap(currentTouchTimeStamp, gestureState) ) console.log('Double tap detected'); this.prevTouchInfo = { prevTouchX: gestureState.x0, prevTouchY: gestureState.y0, prevTouchTimeStamp: currentTouchTimeStamp };/***/}

    handlePanResponderGrantse activa cada vez que nuestro NetworkImagecomponente reclama con éxito el estado de respuesta o, en palabras más simples, cada vez que se toca. Nos estamos dirigiendo thisal interior handlePanResponderGrant, pero thisdentro de este método no está nuestra SplashWallsclase; más bien lo es PanResponder. Para solucionar esto, antes de la llave de cierre de constructoragregue la siguiente línea:

    this.handlePanResponderGrant = this.handlePanResponderGrant.bind(this);

    Ahora es un buen momento para arrojar algo de luz sobre una pequeña diferencia entre los dos patrones de declaración de clases de React que analizamos en la parte 1. En este tutorial hemos elegido utilizar la sintaxis de clase ES2015; La otra opción era usar React.createClass({ ... }). Si hubiéramos optado por la otra opción, no tendríamos que vincularnos thisal método en el archivo constructor. La vinculación automática se habría solucionado por nosotros . Una vez más, cuando tomas una decisión, pierdes algo y ganas algo. Lo primero que hacemos dentro handlePandResponderGrantes tomar la marca de tiempo del grifo al currentTouchTimeStampusarlo Date.now(). Luego comprobamos si este toque concluye un doble toque, usando el isDoubleTapmétodo:

     

    isDoubleTap(currentTouchTimeStamp, {x0, y0}) { var {prevTouchX, prevTouchY, prevTouchTimeStamp} = this.prevTouchInfo; var dt = currentTouchTimeStamp - prevTouchTimeStamp; return (dt DOUBLE_TAP_DELAY Utils.distance(prevTouchX, prevTouchY, x0, y0) DOUBLE_TAP_RADIUS);}

    Notarás un par de cosas nuevas aquí. Primero hay dos constantes DOUBLE_TAP_DELAY y DOUBLE_TAP_RADIUS . Defínelos con NUM_WALLPAPERS .

    const DOUBLE_TAP_DELAY = 300; // millisecondsconst DOUBLE_TAP_RADIUS = 20;

    A continuación, definí un nuevo módulo, Utils.js , y lo incluí en el archivo index.ios.js . Utils.js exporta un único método: distance.

    distance(x0, y0, x1, y1) { return Math.sqrt( Math.pow(( x1 - x0 ), 2) + Math.pow(( y1 - y0 ), 2) );}

    distancesimplemente calcula y devuelve la distancia entre dos puntos usando la siguiente fórmula de geometríaFinalmente, isDoubleTapen la declaración de devolución se comprueba si la diferencia de tiempo entre el toque anterior y el actual es inferior a 300 milisegundos ( DOUBLE_TAP_DELAY ) y si la distancia entre los dos toques consecutivos es inferior a 20 px ( DOUBLE_TAP_RADIUS ). Si se cumplen ambas condiciones, la función devuelve verdadero; en caso contrario, falso. ¿Suena bien? Excelente. Para un último paso handlePanResponderGrant, actualizamos prevTouchInfocon la información del grifo que acaba de registrarse. Probemos nuestro oyente de doble toque en el simulador. Una vez que se carga un fondo de pantalla, intente hacer doble clic en cualquier parte del fondo de pantalla. Deberías poder leer "Se detectó doble toque" en la consola. ¡Buen trabajo!## 3. Guardar el fondo de pantalla en el carrete Al detectar un doble toque en este momento, todo lo que estamos haciendo es registrar "Doble toque detectado" en la consola. Reemplace esa línea con la siguiente llamada al método:

    if( isDoubleTap(currentTouchTimeStamp, gestureState) ) this.saveCurrentWallpaperToCameraRoll();

    Llegaremos a declarar saveCurrentWallpperToCameralRollmás adelante, pero primero declaramos la siguiente variable dentro del constructor:

    this.currentWallIndex = 0;

    currentWallIndexcontiene el índice del fondo de pantalla que está actualmente visible en la pantalla. El primer fondo de pantalla tiene un índice de 0, el siguiente tiene un índice de 1, y así sucesivamente. En cada deslizamiento, debemos actualizar el valor de currentWallIndex. Esta es una tarea muy sencilla gracias a la API de reaccionar-nativo-swiper. ¿Recuerda la función onMomentumScrollEndque mencionamos hacia el final de la última sección de la parte 1? Ahora es el momento de declararlo finalmente.

     

    onMomentumScrollEnd(e, state, context) { this.currentWallIndex = state.index;}

    También necesitaremos unirnos thisa este método. En el constructor, justo debajo de donde nos unimos this, handlePanResponderGrantagregue la siguiente línea:

    this.onMomentumScrollEnd = this.onMomentumScrollEnd.bind(this);

    Para poder acceder a Camera Roll en nuestra aplicación, necesitaremos vincular la biblioteca Camera Roll a nuestra aplicación. ¿Recuerdas vincular ReactART en la parte 1? Tendremos que seguir exactamente el mismo procedimiento con el archivo RCTCameraRoll.xcodeproj , que se puede encontrar en node_modules/react-native/Libraries/CameraRoll .Una vez que haya vinculado CameraRoll, agregue dos líneas nuevas a las importaciones:

    var { AppRegistry, StyleSheet, Text, View, Component, ActivityIndicatorIOS, Dimensions, PanResponder,/***/ CameraRoll, // Add this AlertIOS // and this/***/} = React;

    Una vez que el fondo de pantalla se haya guardado en Camera Roll, le mostraremos al usuario una alerta con un mensaje de éxito. Tendremos que AlertIOShacer eso. Ahora podemos definir saveCurrentWallpaperToCameraRoll.

    saveCurrentWallpaperToCameraRoll() { var {wallsJSON} = this.state; var currentWall = wallsJSON[this.currentWallIndex]; var currentWallURL = `https://unsplash.it/${currentWall.width}/${currentWall.height}?image=${currentWall.id}`; CameraRoll.saveImageWithTag(currentWallURL, (data) = { AlertIOS.alert( 'Saved', 'Wallpaper successfully saved to Camera Roll', [ {text: 'High 5!', onPress: () = console.log('OK Pressed!')} ] ); },(err) ={ console.log('Error saving to camera roll', err); });}

    Todo saveCurrentWallpaperToCameraRolles muy sencillo. Si tienes curiosidad o te sientes estancado, puedes leer más sobre CameraRoll y AlertIOS . Actualice el simulador y, una vez que se cargue el fondo de pantalla, haga doble clic en él. Después de un pequeño retraso, se le solicitará que proporcione permiso a SplashWalls para acceder al Camera Roll. Una vez hecho esto, debería ver una alerta como la que se muestra a continuación.Observe que hay un retraso entre el doble toque y la aparición del modal de alerta. No podemos hacer nada con respecto al retraso, pero no tenemos que dejar al usuario colgado, pensando que el doble toque no funcionó. Nos ocuparemos de esto en la siguiente sección. ## 4. Creación de un componente HUD de progreso En esta sección crearemos nuestro primer componente, que será una pantalla de visualización de progreso (HUD). Todo lo que incluye es una ruleta sobre un fondo negro translúcido con el texto "Espere, por favor..." debajo. Mostraremos este componente durante el retraso que ocurre entre el doble toque y la aparición del modo de alerta, para que el usuario sepa que su acción funcionó y la aplicación responde. Cree un nuevo archivo, ProgressHUD.js , en el directorio raíz de la aplicación. Complete el archivo con las siguientes líneas:

     

    'use strict';var React = require('react-native');var { View, Text, Component, ActivityIndicatorIOS,} = React;class ProgressHUD extends Component { constructor(props) { super(props); } render() { var {width, height, isVisible} = this.props; if( isVisible ) { return( View style={{ flex: 1, flexDirection: 'row', justifyContent: 'center', alignItems: 'center', width: width, height: height, position: 'absolute', top: 0, left: 0, backgroundColor: 'rgba(0, 0, 0, 0.5)' }} ActivityIndicatorIOS animating={true} color={'#fff'} size={'large'} style={{margin: 15}} / Text style={{color:’#fff’}}Please wait.../Text /View ); } else { return(View/View); } }};module.exports = ProgressHUD;

    Observe la primera línea en el interior render. Estamos creando tres nuevas variables y recuperando sus valores de this.props. Los accesorios en React son cosas que se pasan a un componente desde dentro de otro componente, como el ancho, el alto y isVisiblese pasarán a ProgressHUD:

    ProgressHUD width={width} height={height} isVisible={isHudVisible}/

    Incluya ProgressHUD.js en el archivo index.ios.js como se muestra.

    // Componentsvar ProgressHUD = require('./ProgressHUD.js');

    Para controlar la visibilidad del HUD de progreso, agregaremos una nueva variable de estado:

    this.state = { wallsJSON: [], isLoading: true,/***/ isHudVisible: false // add this/***/};

    Ahora agrega el `` componente justo después de `` en el renderResultsmétodo. Hacerlo generará un error porque devolveremos más de un componente, lo cual no está permitido en React Native. Para solucionar esto, simplemente envuelva todo lo que hay dentro return()(el deslizador y el componente HUD de progreso), en un simple ``.

    renderResults() { var {wallsJSON, isHudVisible} = this.state; return ( /***/ View /***/ Swiper ...... /Swiper /***/ ProgressHUD width={width} height={height} isVisible={isHudVisible}/ /View /***/ );}

    Estamos pasando tres accesorios a ProgressHUD: los dos primeros son las dimensiones de la pantalla; el tercero es un valor booleano que determina si ProgressHUDdevuelve una ruleta con "Espere..." sobre un fondo translúcido o simplemente nada. Controlaremos la ocultación y visualización del HUD de progreso desde el interior saveCurrentWallpaperToCameraRoll. Actualice el método para que se parezca al siguiente:

    saveCurrentWallpaperToCameraRoll() {/***/ // Make Progress HUD visible this.setState({isHudVisible: true});/***/ var {wallsJSON} = this.state; var currentWall = wallsJSON[this.currentWallIndex]; var currentWallURL = `https://unsplash.it/${currentWall.width}/${currentWall.height}?image=${currentWall.id}`; CameraRoll.saveImageWithTag(currentWallURL, (data) = {/***/ // Hide Progress HUD this.setState({isHudVisible: false});/***/ AlertIOS.alert( 'Saved', 'Wallpaper successfully saved to Camera Roll', [ {text: 'High 5!', onPress: () = console.log('OK Pressed!')} ] ); },(err) ={ console.log('Error saving to camera roll', err); });}

    Hacemos visible el HUD tan pronto como ingresamos al método y lo ocultamos una vez que saveImageWithTagse activa. Actualiza el simulador y haz doble clic en un fondo de pantalla. Notará que el HUD de progreso se vuelve visible y desaparece tan pronto como aparece el cuadro de diálogo de alerta. Pero aquí está sucediendo algo extraño: volvemos a la primera imagen después del doble toque. Esto se debe a que estamos modificando una variable de estado ( isHudVisible) dentro saveWallpaperToCameraRolldel uso this.setState(), lo que resulta en una nueva representación y hace que el deslizador recargue los datos y comience desde la primera imagen. Para evitar que eso suceda, simplemente agregue un nuevo atributo indexa Swiper.

     

    Swiper ... index={this.currentWallIndex}

    Esto asegura que cuando se vuelva a renderizar se nos muestre el mismo fondo de pantalla que estaba visible antes. Actualice el simulador y todo debería funcionar según lo previsto.With that, we’ve almost finished building our cute little app. Right now we’re simply fetching five wallpapers on launch. Wouldn’t it be cool if we could just shake our iPhone and it fetched five new random wallpapers automagically?## 5. Running The App On An iPhone And Detecting Shake GestureEven if you don’t have a physical device you can still detect a shake gesture in the simulator by pressing Cmd + Ctrl + Z with the simulator window in focus.Let's make our app fetch five new random wallpapers every time we shake the device. Like rolling a die!To enable our app to detect shakes we will need to install an npm module called react-native-shake-event-ios.Head to the root of the project and run the following command from the terminal:

    npm install --save react-native-shake-event-ios

    One more thing we need to do is to link a library. As this is the third (and last) time we'll link a library in this tutorial, you should be acquainted with the process already.Find the RNShakeEvent.xcodeproj inside node_modules/react-native-shake-event-ios/ and link that through Xcode.Like any other library, we import it in our main file like so:

    var ShakeEvent = require('react-native-shake-event-ios');

    Then, head over to the componentWillMount method. This is where we will wire our shake event listener. After doing that, our componentWillMount method should look like this:

    componentWillMount() { this.imagePanResponder = PanResponder.create({ onStartShouldSetPanResponder: this.handleStartShouldSet 




    Tal vez te puede interesar:

    1. Creación de su propia biblioteca de validación de React: la experiencia del desarrollador (Parte 3)
    2. Introducción a Quasar Framework: creación de aplicaciones multiplataforma
    3. Creación de un componente web retro que se puede arrastrar con iluminación
    4. Creación y acoplamiento de una aplicación Node.js con arquitectura sin estado con la ayuda de Kinsta

    La belleza de React Native: creación de su primera aplicación para iOS con JavaScript (Parte 2)

    La belleza de React Native: creación de su primera aplicación para iOS con JavaScript (Parte 2)

    SmashingConf UX y diseño, Amberes 2024 Clase magistral de diseño para una interfaz de usuario compleja, con Vitaly Friedman

    programar

    es

    https://aprendeprogramando.es/static/images/programar-la-belleza-de-react-native-creacion-de-su-primera-aplicacion-para-ios-con-javascript-parte-2-890-0.jpg

    2024-05-20

     

    La belleza de React Native: creación de su primera aplicación para iOS con JavaScript (Parte 2)
    La belleza de React Native: creación de su primera aplicación para iOS con JavaScript (Parte 2)

    Si crees que alguno de los contenidos (texto, imagenes o multimedia) en esta página infringe tus derechos relativos a propiedad intelectual, marcas registradas o cualquier otro de tus derechos, por favor ponte en contacto con nosotros en el mail [email protected] y retiraremos este contenido inmediatamente

     

     

    Top 20