Interfaces de usuario de iOS: Guiones gráficos vs. puntas vs. Código personalizado

A menudo escucho a los desarrolladores de iOS hacer alguna variante de la misma pregunta clave:

¿Cuál es la mejor manera de desarrollar una interfaz de usuario en iOS: a través de guiones gráficos, NIBs o código?

Las respuestas a esta pregunta, explícita o implícitamente, tienden a asumir que hay que tomar una decisión mutuamente excluyente, una que a menudo se aborda por adelantado, antes del desarrollo.

Soy de la opinión de que la respuesta en su lugar debe tomar la forma de una o más preguntas de respuesta.

¿Cuál es el mejor coche?

Permítanme explicar con un ejemplo fuera de tema. Digamos que quiero comprar un coche y le hago una simple pregunta: «¿Cuál es la mejor opción?»

¿Realmente puedes responder sugiriendo un modelo, o incluso una marca? No es probable, a menos que sugieras un Ferrari. En su lugar, probablemente responderías con algunas otras preguntas, como:

  • ¿Cuál es tu presupuesto?
  • ¿Cuántos asientos necesita?
  • ¿Le importa el consumo de combustible?
  • ¿Cómo te sientes con los autos deportivos?

Es obvio que no hay tal cosa como un auto bueno o malo a menos que se coloque en un contexto adecuado, solo hay un auto bueno o malo basado en necesidades específicas.

Volver al diseño de la interfaz de usuario de iOS

Al igual que con nuestra consulta sobre automóviles, la pregunta «Cuál es la mejor manera de desarrollar una interfaz de usuario de iOS» carece de contexto. Y, sorprendentemente, la respuesta no tiene por qué ser un caso general.

En términos generales, hay tres tipos de enfoques de diseño de interfaz de usuario que puede tomar, cada uno con sus pros y contras, sus fanáticos y odiadores:

  • Storyboards iOS: Una herramienta visual para diseñar múltiples vistas de aplicaciones y las transiciones entre ellas.
  • NIBs (o XIBs): Cada archivo NIB corresponde a un único elemento de vista y se puede diseñar en el Creador de interfaces, lo que también lo convierte en una herramienta visual. Tenga en cuenta que el nombre «NIB» se deriva de la extensión de archivo (anteriormente .plumín y ahora .xib, aunque la antigua pronunciación ha persistido).
  • Código personalizado: es decir, sin herramientas GUI, sino más bien, manejando todo el posicionamiento personalizado, animación, etc. programáticamente.

Ninguna de estas opciones es universalmente mejor que ninguna otra (a pesar de lo que pueda oír).

Los guiones gráficos, por ejemplo, son la última adición al kit de herramientas de interfaz de usuario de iOS. Me han dicho que son el futuro, que reemplazarán las puntas y las interfaces de usuario de código personalizado. Veo los guiones gráficos como una herramienta útil, pero no tanto como un reemplazo como un complemento para las puntas y el código personalizado. Los guiones gráficos son la opción correcta en algunas, pero no en todas las situaciones.

Este tutorial de desarrollo de iOS busca explorar la diferencia entre 3 enfoques para el diseño de la interfaz de usuario de iOS.

Además, ¿por qué debería atenerse estáticamente a una sola opción cuando puede usarlas todas (en el mismo proyecto), eligiendo el mecanismo que mejor se adapte al problema específico en cuestión?

Esta es una pregunta que, en mi opinión, puede generalizarse a un nivel superior, y cuya respuesta ocupa un lugar destacado en mi lista de principios de desarrollo de software: No hay un lenguaje, marco o tecnología universales que sea la mejor opción universal para cada problema de desarrollo de software. Lo mismo es cierto para el diseño de la interfaz de usuario de iOS.

En este tutorial de desarrollo de iOS, vamos a explorar cada uno de estos métodos e introducir casos de uso en los que deben y no deben emplearse, así como formas en las que se pueden combinar.

Guiones gráficos iOS

Un error clásico de principiante es crear un guion gráfico iOS masivo para todo el proyecto. Yo también cometí este error cuando empecé a trabajar con guiones gráficos (probablemente porque es una ruta tentadora).

El error de un principiante clásico es crear un guion gráfico masivo para todo el proyecto. Un guion gráfico es un tablero con una historia que contar. No debería usarse para mezclar historias no relacionadas en un gran volumen.

Como su nombre lo indica, un guion gráfico es un tablero con una historia que contar. No debería usarse para mezclar historias no relacionadas en un gran volumen. Un guion gráfico debe contener controladores de vista que estén relacionados lógicamente entre sí, lo que no significa todos los controladores de vista.

Por ejemplo, tiene sentido usar guiones gráficos al manejar:

  • Un conjunto de vistas para autenticación y registro.
  • Un flujo de entrada de órdenes de varios pasos.
  • Un flujo tipo asistente (es decir, tutorial).
  • Un conjunto de vistas con detalles maestros (por ejemplo, listas de perfiles, detalles de perfil).

Mientras tanto, se deben evitar los guiones gráficos grandes, incluidos los guiones gráficos individuales para toda la aplicación (a menos que la aplicación sea relativamente simple). Antes de profundizar, veamos por qué.

La locura de los Storyboards iOS grandes

Los Storyboards grandes, aparte de ser difíciles de navegar y mantener, agregan una capa de complejidad a un entorno de equipo: cuando varios desarrolladores trabajan en el mismo archivo de storyboard al mismo tiempo, los conflictos de control de código fuente son inevitables. Y mientras que un guion gráfico se representa internamente como un archivo de texto (un archivo XML, en realidad), la fusión generalmente no es trivial.

Cuando los desarrolladores ven el código fuente, le atribuyen un significado semántico. Por lo tanto, al fusionarse manualmente, pueden leer y comprender ambos lados de un conflicto y actuar en consecuencia. Un guion gráfico, en cambio, es un archivo XML administrado por Xcode, y el significado de cada línea de código no siempre es fácil de entender.

Tomemos un ejemplo muy simple: digamos que dos desarrolladores diferentes cambian la posición de un UILabel (usando diseño automático), y este último empuja su cambio, produciendo un conflicto como este (observe los atributos id en conflicto):

<layoutGuides> <viewControllerLayoutGuide type="top"/> <viewControllerLayoutGuide type="bottom"/></layoutGuides><layoutGuides> <viewControllerLayoutGuide type="top"/> <viewControllerLayoutGuide type="bottom"/></layoutGuides>

El id en sí mismo no proporciona ninguna indicación en cuanto a su verdadero significado, por lo que no tiene nada con qué trabajar. La única solución significativa es elegir una de las dos partes del conflicto y descartar la otra. ¿Habrá efectos secundarios? Quién sabe? Tú no.

Para aliviar estos problemas de diseño de la interfaz de iOS, el enfoque recomendado es usar varios guiones gráficos en el mismo proyecto.

Cuándo usar guiones gráficos

Los guiones gráficos se utilizan mejor con varios controladores de vista interconectados, ya que su principal simplificación es la transición entre controladores de vista. Hasta cierto punto, se pueden considerar como una composición de puntas con flujos visuales y funcionales entre controladores de vista.

Los guiones gráficos se utilizan mejor con varios controladores de vista interconectados, ya que su principal simplificación es la transición entre controladores de vista.

Además de facilitar el flujo de navegación, otra ventaja distintiva es que eliminan el código repetitivo necesario para hacer estallar, empujar, presentar y descartar controladores de vista. Además, los controladores de vista se asignan automáticamente, por lo que no es necesario manualmente alloc y init.

Finalmente, si bien los guiones gráficos se utilizan mejor para escenarios que involucran varios controladores de vista, también es defendible usar un guion gráfico cuando se trabaja con un solo controlador de vista de tabla por tres razones:

  • La capacidad de diseñar prototipos de celdas de mesa en el lugar ayuda a mantener unidas las piezas.
  • Se pueden diseñar plantillas de celdas múltiples dentro del controlador de vista de tabla principal.
  • Es posible crear vistas de tabla estáticas (una adición muy esperada que desafortunadamente solo está disponible en guiones gráficos).

Se podría argumentar que las plantillas de celdas múltiples también se pueden diseñar usando NIBs. En realidad, esto es solo una cuestión de preferencia: algunos desarrolladores prefieren tener todo en un solo lugar, mientras que a otros no les importa.

Cuándo no usar Guiones gráficos iOS

Algunos casos:

  • La vista tiene un diseño complicado o dinámico, mejor implementado con código.
  • La vista ya está implementada con NIBs o código.

En esos casos, podemos dejar la vista de Guión gráfico o incrustarlo en un controlador de vista. El primero rompe el flujo visual del guion gráfico, pero no tiene implicaciones funcionales o de desarrollo negativas. Este último retiene este flujo visual, pero requiere esfuerzos de desarrollo adicionales, ya que la vista no está integrada en el controlador de vista: solo está incrustada como un componente, por lo que el controlador de vista debe interactuar con la vista en lugar de implementarla.

Pros y contras generales

Ahora que tenemos una idea de cuándo los guiones gráficos son útiles en el diseño de la interfaz de usuario de iOS, y antes de pasar a las puntas en este tutorial, repasemos sus ventajas y desventajas generales.

Pro: Rendimiento

Intuitivamente, puede asumir que cuando se carga un guion gráfico, todos sus controladores de vista se instancian de inmediato. Afortunadamente, esto es solo una abstracción y no es cierto de la implementación real: en su lugar, solo se crea el controlador de vista inicial, si lo hay. Los otros controladores de vista se crean instancias dinámicamente, ya sea cuando se realiza un segue o manualmente desde el código.

Pro: Prototipos

Los guiones gráficos simplifican la creación de prototipos y la simulación de interfaces de usuario y flujo. En realidad, una aplicación prototipo de trabajo completa con vistas y navegación se puede implementar fácilmente utilizando guiones gráficos y solo unas pocas líneas de código.

Con: Reutilización

Cuando se trata de mover o copiar, los guiones gráficos de iOS están mal posicionados. Un guion gráfico debe moverse junto con todos sus controladores de vista dependientes. En otras palabras, un controlador de vista única no se puede extraer individualmente y reutilizar en otro lugar como una sola entidad independiente; depende del resto del guion gráfico para funcionar.

Con: Flujo de datos

Los datos a menudo deben pasarse entre controladores de vista cuando una aplicación hace una transición. Sin embargo, el flujo visual del guion gráfico se rompe en este caso, ya que no hay rastro de que esto suceda en el Creador de interfaces. Los guiones gráficos se encargan de manejar el flujo entre los controladores de vista, pero no el flujo de datos. Por lo tanto, el controlador de destino debe configurarse con código, anulando la experiencia visual.

Los storyboards se encargan de manejar el flujo entre controladores de vista, pero no el flujo de datos.

En tales casos, tenemos que confiar en un prepareForSegue:sender, con un esqueleto if/else-if como este:

- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { NSString *identifier = ; if ("segue_name_1"]) { MyViewController *vc = (MyViewController *) ; ; } else if ("segue_name_2"]) { ... } else if ...}

Encuentro que este enfoque es propenso a errores e innecesariamente detallado.

Puntas

Las puntas son la forma antigua(er) de realizar el diseño de la interfaz de iOS.

En este caso, » antiguo «no significa» malo»,» obsoleto «o»obsoleto». De hecho, es importante entender que los guiones gráficos de iOS no son un reemplazo universal para NIBs; solo simplifican la implementación de la interfaz de usuario en algunos casos.

Con las puntas, se puede diseñar cualquier vista arbitraria, que el desarrollador puede adjuntar a un controlador de vista según sea necesario.

Si aplicamos diseño orientado a objetos a nuestras UIs, entonces tiene sentido dividir la vista de un controlador de vista en módulos separados, cada uno implementado como una vista con su propio archivo NIB (o con varios módulos agrupados en el mismo archivo). La clara ventaja de este enfoque es que cada componente es más fácil de desarrollar, probar y depurar.

Los NIB comparten los problemas de conflicto de fusión que vimos con los guiones gráficos, pero en menor medida, ya que los archivos NIB operan a una escala más pequeña.

Cuándo usar plumines para el diseño de interfaz de usuario de iOS

Un subconjunto de todos los casos de uso sería:

  • Vistas modales
  • Vistas simples de inicio de sesión y registro
  • Configuración
  • Ventanas emergentes
  • Plantillas de vista reutilizables
  • Plantillas de celdas de tabla reutilizables

Mientras tanto Meanwhile

Cuándo no usar puntas

Debe evitar usar puntas para:

  • Vistas con contenido dinámico, donde el diseño cambia significativamente en función del contenido.
  • Vistas que, por naturaleza, no se pueden diseñar fácilmente en el Creador de interfaces.
  • Controladores de visualización con transiciones complicadas que podrían simplificarse con el guion gráfico.

Pros y contras generales

Más en general, pasemos por los pros y contras de usar puntas.

Pro: Reutilización

Las puntas son útiles cuando se comparte el mismo diseño en varias clases.

Como un caso de uso simple, se podría implementar una plantilla de vista que contenga un campo de texto de nombre de usuario y contraseña con las vistas hipotéticas TTLoginView y TTSignupView, las cuales podrían originarse desde el mismo PLUMÍN. El TTLoginView tendría que ocultar el campo de contraseña, y ambos tendrían que especificar las etiquetas estáticas correspondientes (como’ Ingrese su nombre de usuario ‘ vs ‘Ingrese su contraseña’), pero las etiquetas tendrían la misma funcionalidad básica y diseños similares.

Pro & Con: Rendimiento

Las puntas se cargan perezosamente, por lo que no usan memoria hasta que tienen que hacerlo. Si bien esto puede ser una ventaja, hay latencia en el proceso de carga lenta, lo que lo convierte en algo negativo también.

Código personalizado de iOS (UIs Programáticas)

Cualquier diseño de interfaz de iOS que se pueda hacer con guiones gráficos y NIBs también se puede implementar con código sin procesar (hubo un tiempo, por supuesto, en que los desarrolladores no tenían el lujo de un conjunto tan rico de herramientas).

Lo que no se puede hacer con NIBs y Storyboards siempre se puede implementar con código.

Quizás lo más importante es que lo que no se puede hacer con NIBs y guiones gráficos siempre se puede implementar con código, siempre que, por supuesto, sea técnicamente factible. Otra forma de verlo es que los NIB y los guiones gráficos se implementan con código, por lo que su funcionalidad naturalmente será un subconjunto. Vayamos directamente a los pros y los contras.

Pro: Bajo el capó

La mayor ventaja de crear una interfaz de usuario de iOS mediante programación: si sabe cómo codificar una interfaz de usuario, entonces sabe lo que sucede bajo el capó, mientras que lo mismo no es necesariamente cierto para las puntas y los guiones gráficos.

Para hacer una comparación: una calculadora es una herramienta útil. Pero no es malo saber cómo realizar cálculos manualmente.

Esto no se limita a iOS, sino a cualquier herramienta de visual RAD (por ejemplo, Visual Studio y Delphi, por nombrar solo algunas). Los entornos RAD HTML visuales representan un caso límite típico: se utilizan para generar código (a menudo mal escrito), alegando que no se necesitan conocimientos de HTML y que todo se puede hacer visualmente. Pero ningún desarrollador web implementaría una página web sin ensuciarse las manos: saben que manejar manualmente el HTML y CSS sin procesar conducirá a un código más modular y eficiente.

Por lo tanto, dominar la codificación de las interfaces de usuario de iOS le brinda más control y una mayor conciencia de cómo encajan estas piezas, lo que eleva su límite superior como desarrollador.

Pro: Cuando el código es la única Opción

También hay casos en los que el código iOS personalizado es la única opción para el diseño de la interfaz de usuario. Los diseños dinámicos, en los que los elementos de vista se mueven y el flujo o el diseño se ajusta significativamente en función del contenido, son ejemplos típicos.

Pro: Conflictos de fusión

Mientras que las puntas y los guiones gráficos sufrieron significativamente los conflictos de fusión, el código no tiene el mismo error. Todo el código tiene un significado semántico, por lo que resolver conflictos no es más difícil de lo habitual.

Con: Creación de prototipos

Es difícil averiguar cómo se verá un diseño hasta que lo vea en acción. Además, no puede posicionar visualmente las vistas y los controles, por lo que traducir las especificaciones de diseño en una vista tangible puede llevar mucho más tiempo, en comparación con las puntas y los guiones gráficos que le brindan una vista previa inmediata de cómo se renderizarán las cosas.

Con: Refactorización

Refactorización de código que fue escrito hace mucho tiempo o por otra persona también se vuelve mucho más complicado: cuando se colocan y animan elementos con métodos personalizados y números mágicos, las sesiones de depuración pueden volverse arduas.

Pro: Rendimiento

En términos de rendimiento, los guiones gráficos y las puntas están sujetos a la sobrecarga de carga y análisis; y al final, se traducen indirectamente en código. No hace falta decir que esto no sucede con las interfaces de usuario creadas por código.

Pro: Reutilización

Cualquier vista implementada mediante programación se puede diseñar de forma reutilizable. Veamos algunos casos de uso:

  • Dos o más vistas comparten un comportamiento común, pero son ligeramente diferentes. Una clase base y dos subclases resuelven el problema con elegancia.
  • Un proyecto tiene que ser bifurcado, con el objetivo de crear una base de código única, pero generando dos (o más) aplicaciones diferentes, cada una con personalizaciones específicas.

El mismo proceso de diseño de interfaz de usuario sería mucho más complicado con plumines y guiones gráficos. Los archivos de plantilla no permiten la herencia, y las posibles soluciones se limitan a lo siguiente:

  • Duplique los archivos de plumín y guion gráfico. Después de eso, tienen vidas separadas y no tienen relación con el archivo original.
  • Anula el aspecto y el comportamiento con código, lo que puede funcionar en casos simples, pero puede provocar complicaciones significativas en otros. Las sobreescrituras pesadas con código también pueden hacer que el diseño visual sea inútil y evolucionar hasta convertirse en una fuente constante de dolores de cabeza, p.ej., cuando un cierto control se muestra de una manera en el Creador de interfaces, pero se ve completamente diferente cuando la aplicación se está ejecutando.

Cuándo usar el código

A menudo es una buena llamada para usar usar código personalizado para el diseño de la interfaz de usuario de iOS cuando tiene:

  • Diseños dinámicos.
  • Vistas con efectos, como esquinas redondeadas, sombras, etc.
  • Cualquier caso en el que el uso de plumines y guiones gráficos sea complicado o inviable.

Cuándo no usar Código

En general, siempre se pueden usar IU hechas con código. Rara vez son una mala idea, así que lo pondría aquí.

Aunque las puntas y los guiones gráficos traen algunas ventajas a la mesa, siento que no hay ningún inconveniente razonable que ponga en una lista para desalentar el uso de código (excepto, quizás, la pereza).

Un proyecto, varias herramientas

Los guiones gráficos, las puntas y el código son tres herramientas diferentes para crear la interfaz de usuario de iOS. Tenemos suerte de tenerlos. Los fanáticos de las interfaces de usuario programáticas probablemente no tendrán en cuenta las otras dos opciones: el código le permite hacer todo lo que es técnicamente posible, mientras que las alternativas tienen sus limitaciones. Para el resto de desarrolladores, la navaja Xcode proporciona tres herramientas que se pueden usar de una sola vez, en el mismo proyecto, de manera efectiva.

¿Cómo, preguntas? Como quieras. Estos son algunos enfoques posibles:

  • Agrupa todas las pantallas relacionadas en grupos separados e implementa cada grupo con su propio guion gráfico distinto.
  • Diseñe celdas de mesa no reutilizables en su lugar con un guion gráfico, dentro del controlador de vista de mesa.
  • Diseñe celdas de tabla reutilizables en puntas para fomentar la reutilización y evitar la repetición, pero cargue estas puntas a través de código personalizado.
  • Diseñe vistas, controles y objetos intermedios personalizados con puntas.
  • Use código para vistas altamente dinámicas y, en general, para vistas que no se pueden implementar fácilmente a través de guiones gráficos y plumines, mientras aloja transiciones de vistas en un guion gráfico.

Para cerrar, veamos un último ejemplo que lo une todo.

Un caso de uso simple

Digamos que queremos desarrollar una aplicación de mensajería básica con varias vistas diferentes:

  • Una lista de amigos seguidos (con una plantilla de celda reutilizable para mantener la interfaz de usuario uniforme en listas futuras).
  • Una vista de detalles de perfil, compuesta en secciones separadas (que incluyen información de perfil, estadísticas y una barra de herramientas).
  • Una lista de mensajes enviados y recibidos de un amigo.
  • Un nuevo formulario de mensaje.
  • Una vista de nube de etiquetas que muestra las diferentes etiquetas utilizadas en los mensajes de usuario, con cada etiqueta proporcional en tamaño al número de veces que se ha utilizado.

Además, queremos que las vistas fluyan de la siguiente manera:

  • Al hacer clic en un elemento de la lista de amigos seguidos, se muestran los detalles del perfil del amigo correspondiente.
  • Los detalles del perfil muestran el nombre del perfil, la dirección, las estadísticas, una breve lista de los mensajes más recientes y una barra de herramientas.

Para implementar esta aplicación iOS, las tres herramientas de interfaz de usuario serán útiles, ya que podemos usar:

  • Un guion gráfico con cuatro controladores de vista (la lista, los detalles, la lista de mensajes y el formulario de mensaje nuevo).
  • Un archivo NIB separado para la plantilla de celda de lista de perfiles reutilizable.
  • Tres archivos NIB separados para la vista de detalles de perfil, uno para cada una de las secciones separadas que la componen (detalles de perfil, estadísticas, últimos tres mensajes), para permitir un mejor mantenimiento. Estas puntas se instanciarán como vistas y luego se agregarán al controlador de vistas.
  • Código personalizado para la vista de nube de etiquetas. Esta vista es un ejemplo típico de una que no se puede diseñar en el Creador de interfaces, ni a través de guiones gráficos ni NIBs. En su lugar, está completamente implementado a través de código. Para mantener el flujo visual del guion gráfico, elegimos agregar un controlador de vista vacío al guion gráfico, implementar la vista de nube de etiquetas como una vista independiente y agregar programáticamente la vista al controlador de vista. Claramente, la vista también podría implementarse dentro del controlador de vista en lugar de como una vista independiente, pero las mantenemos separadas para una mejor reutilización.

Una maqueta realmente básica podría verse como:

Este diagrama ilustra un proyecto de diseño de interfaz de usuario de iOS que utiliza guiones gráficos, puntas y código iOS personalizado.

Con eso, hemos esbozado la construcción básica de una aplicación iOS razonablemente sofisticada cuyas vistas principales unen nuestros tres enfoques principales para el diseño de la interfaz de usuario. Recuerde: no hay una decisión binaria que tomar, ya que cada herramienta tiene sus fortalezas y debilidades.

Terminando

Como se examina en este gráfico, los guiones gráficos agregan una simplificación notable al diseño de la interfaz de usuario de iOS y al flujo visual. También eliminan el código repetitivo; pero todo esto tiene un precio, pagado en flexibilidad. Las puntas, por su parte, ofrecen más flexibilidad al enfocarse en una sola vista, pero sin flujo visual. La solución más flexible, por supuesto, es el código, que tiende a ser bastante hostil e inherentemente no visual.

Si este artículo le intrigó, le recomiendo ver el gran debate de Ray Wenderlich, 55 minutos bien invertidos en una discusión de NIBs, Guiones gráficos y IU hechas con código.

Para cerrar, quiero enfatizar una cosa: Evite usar la herramienta de diseño de interfaz de usuario de iOS inadecuada a toda costa. Si una vista no se puede diseñar con un guion gráfico, o si se puede implementar con NIBs o código de una manera más simple, no use un guion gráfico. Del mismo modo, si una vista no se puede diseñar con puntas, no utilice puntas. Estas reglas, aunque simples, te ayudarán mucho en tu educación como desarrollador.

Deja una respuesta

Tu dirección de correo electrónico no será publicada.