¿Cuál es la mejor manera de crear controles que respondan a las notificaciones sin interferir con los mecanismos de mensajería existentes? En este artículo, demuestro una clase de proxy de notificación que lo ayuda a agregar funcionalidad a los controles de la interfaz de usuario de iOS existentes mediante un ejemplo práctico: Agregar texto de marcador de posición al control de vista de texto.
Índice de contenido
El problema: falta de marcadores de posición
El texto de marcador de posición es una excelente manera de que sus usuarios conozcan el tipo de contenido que desea que ingresen en un control en particular. El control UITextField de UIKit tiene un atributo de marcador de posición que le permite hacer esto. Por ejemplo, la Figura 1 muestra el texto del marcador de posición en la pantalla de configuración de Twitter. El texto del marcador de posición en el Nombre de usuario El campo indica que debe ingresar su nombre de usuario de Twitter, incluido el signo @. El texto del marcador de posición en el Contraseña campo indica que es obligatorio.
![]() |
Figura 1 – Texto de marcador de posición en la aplicación de configuración. |
Aunque el campo de texto tiene un atributo de marcador de posición, su primo, el control de vista de texto, no lo tiene.
Resolviendo el problema
Aquí está el panorama general de cómo planeé resolver este problema:
- Cree una extensión que agregue una propiedad calculada llamada marcador de posición al UITextView clase
- En la extensión, muestre la etiqueta cuando no haya texto en la vista de texto y ocúltela cuando haya texto.
Como mencioné en mi publicación anterior, prefiero usar extensiones en lugar de subclases porque me permite usar los controles UIKit listos para usar en mis aplicaciones. Todo lo que tengo que hacer es agregar el archivo de código de extensión a mi proyecto y todas mis clases obtienen automáticamente la nueva funcionalidad.
Solución 1: UITextViewDelegate
Hay algunas formas en que iOS puede notificarle cuando el usuario escribe texto en un UITextView controlar. Uno de ellos es adoptar el UITextViewDelegate protocolo en la extensión y almacenar una referencia a la vista de texto en su propio delegar propiedad. Cuando el usuario escribe o elimina caracteres en la vista de texto en tiempo de ejecución, se llama automáticamente al método delegado de la vista de texto. Luego, puede agregar código al método delegado que oculta o muestra la etiqueta del marcador de posición. El problema con este enfoque es que ata la vista de texto delegar propiedad, ya que solo puede registrar un único objeto delegado con un control de IU. Si necesita agregar otros delegados a la vista de texto en el futuro, tiene las manos atadas.
Solución 2: NSNotificationCenter
NSNotificationCenter tiene un UITextViewTextDidChangeNotification que le avisa cuando el usuario escribe o elimina caracteres en una vista de texto. Esta es una mejor opción porque no ata la vista de texto delegar propiedad. La desventaja de este enfoque es anular el registro de NSNotificationCenter. Normalmente, anula el registro de un objeto de NSNotificationCenter agregando código a su deinit. Sin embargo, en Swift no puede agregar un deinit a una extensión. ¿Cómo podemos sortear esta limitación?
Creación de un proxy de notificación
Podemos sortear las limitaciones de las extensiones Swift creando un objeto proxy ligero que esté registrado con NSNotificationCenter en lugar de la vista de texto. He creado un UITextView extensión junto con una clase de proxy y la incluyó en un proyecto que puede descargar desde este enlace. Puede abrir el proyecto en Xcode haciendo doble clic en el archivo .xcodeproj. Para ver la clase de proxy de notificación, seleccione el mmTextViewExtensions.swift class en el Project Navigator (como puede ver, incluí el mmDynamicTypeExtensions clase de mi artículo anterior). Aquí está la clase de proxy de notificación ubicada en la parte superior del archivo de código:
Como puede ver, es una subclase de UIView. Esto nos permite agregarlo como una subvista al control de vista de texto. los addObserverForName: usingBlock: El método tiene la misma firma (nombre, número y tipo de parámetros) que NSNotificationCenter’s método. Solo hay una línea de código en este método que registra la vista de texto con NSNotificationCenter y pasa a través de los parámetros, incluido el bloque de la vista de texto, que se ejecutará cuando se produzca una notificación. NSNotificationCenter devuelve un NSObjectProtocol objeto que se puede usar más tarde para cancelar el registro de las notificaciones. los deinit tiene una sola línea de código que simplemente anula el registro del objeto de protocolo de NSNotificationCenter. La clase Notification Proxy es reutilizable. Puede usarlo para cualquier notificación y con cualquier clase que desee recibir notificaciones. Debajo del proxy de notificación en el archivo de código está el UITextView extensión. Tiene un placeholderLabel propiedad que, como puede adivinar, se usa para contener una referencia a la etiqueta del marcador de posición. También tiene un marcador de posición Propiedad de cadena. Como verá en la siguiente sección, toda la magia ocurre cuando la propiedad del marcador de posición se establece en tiempo de ejecución y se ejecuta el código de la propiedad calculada. Ahora seleccione el Main.storyboard archivo en el Navegador de proyectos. Como se muestra en Figura 2, hay una sola escena en el guión gráfico con una vista de texto ubicada cerca de la parte superior de la escena.
![]() |
Figura 2: la escena principal contiene una vista de texto |
Si selecciona la vista de texto y va al Inspector de atributos, puede ver la Marcador de posición atributo, que es agregado por la extensión y su valor se establece en “¡Ingrese su texto aquí!”. El texto del marcador de posición no aparece en la superficie de diseño (necesitaríamos tomar una serie de pasos adicionales para que esto suceda, y ese es un tema para otro artículo) pero aparece en tiempo de ejecución.
El proxy de notificación en tiempo de ejecución
El diagrama de secuencia UML en figura 3 muestra el orden de los mensajes que se pasan entre todos los objetos involucrados en esta arquitectura.
![]() |
Figura 3: el orden de los mensajes que se pasan entre todos los objetos en tiempo de ejecución |
Aquí hay una explicación de cada paso:
- Cuando el UITextView el texto del marcador de posición se establece en tiempo de ejecución, activa la extensión marcador de posición código de propiedad calculado.
- los UITextView extensiones addPlaceholderLabel se llama al método.
- los addPlaceholderLabel El método crea una etiqueta de marcador de posición y establece su texto.
- La etiqueta de marcador de posición se agrega al UITextView.
- Se crea un objeto de proxy de notificación.
- los UITextView extensión llama al proxy de notificación addObserverForName: withBlock: método, especificando UITextViewTextDidChangeNotification como el nombre de la notificación que desea observar. También pasa un bloque de código que se ejecutará cuando se produzca la notificación.
- El objeto Notification Proxy registra el UITextView con NSNotificationCenter, pasando también por el evento de notificación a ser observado y el UITextView bloque que se ejecutará cuando se produzca la notificación.
- los UITextView El objeto agrega el proxy de notificación a sí mismo como una subvista.
- Cuando una UITextViewTextDidChangeNotification ocurre, NSNotificationCenter llama al bloque en el UITextView extensión.
- los UITextView extensión establece el marcador de posición etiquetas oculto propiedad a verdadero o falso, dependiendo de si hay texto ingresado o no en la vista de texto.
- Cuando el UITextView se desasigna en tiempo de ejecución, la etiqueta del marcador de posición y el objeto de proxy de notificación se desasignan.
- Cuando se desasigna el objeto de proxy de notificación, anula el registro del UITextView desde NSNotificationCenter.
¡Vamos a probarlo!
- En el control Scheme de Xcode, seleccione uno de los simuladores como el iPhone 6.
- Haga clic en Xcode correr botón.
- Cuando la aplicación aparece en el simulador, puede ver el texto del marcador de posición (Figura 4).
![]() |
Figura 4: el texto del marcador de posición en tiempo de ejecución |
4. Ahora escriba un código en la vista de texto. Tan pronto como empiece a escribir, la etiqueta del marcador de posición desaparece (Figura 5).
![]() |
Figura 5: el marcador de posición desaparece |
- Si elimina todos los caracteres que escribió, el marcador de posición vuelve a aparecer.
Conclusión
Hay muchas formas de resolver un problema de codificación. Lo mejor es analizar bien sus opciones desde el principio y pensar en los pros y los contras de cada una. Espero que a través de estos artículos también estés aprendiendo la belleza de los diagramas de secuencia. Le permiten documentar y comprender las interacciones de objetos que ocurren en tiempo de ejecución. No solo los uso para mis artículos. Los uso para mis diseños de codificación del mundo real. Descubrirá que pueden ayudarlo a identificar problemas potenciales, así como a visualizar soluciones nuevas y más eficientes para sus desafíos de codificación.