Actualmente estoy creando una aplicación que tendrá varios temporizadores, que son básicamente todos iguales.
Quiero crear una clase personalizada que use todo el código para los temporizadores, así como el diseño / animaciones, de modo que pueda tener 5 temporizadores idénticos que funcionen de forma independiente entre sí.
Creé el diseño usando IB (xcode 4.2) y todo el código para los temporizadores está actualmente solo en la clase viewcontroller.
Estoy teniendo dificultades para entender cómo encapsular todo en una clase personalizada y luego agregarlo al controlador de vista, cualquier ayuda sería muy apreciada.
UITableViewCell
oUICollectionViewCell
. En mi caso, necesito una vista pequeña pero bastante compleja que pueda usar muchas veces en controladores y vistas de colección. Y los diseñadores siguen modificándolo, así que quiero un solo lugar donde se defina el diseño. Por lo tanto, una plumilla.Respuestas:
Bueno, para responder conceptualmente, su temporizador probablemente debería ser una subclase de en
UIView
lugar deNSObject
.Para crear una instancia de su temporizador en IB, simplemente arrastre una
UIView
gota en la vista de su controlador de vista y configure su clase con el nombre de la clase de su temporizador.Recuerda
#import
su clase de temporizador en su controlador de vista.Editar: para diseño IB (para instanciación de código, consulte el historial de revisiones)
No estoy muy familiarizado con el guión gráfico, pero sé que puede construir su interfaz en IB usando un
.xib
archivo que es casi idéntico al uso de la versión del guión gráfico; Incluso debería poder copiar y pegar sus vistas como un todo desde su interfaz existente al.xib
archivo.Para probar esto, creé un nuevo vacío
.xib
llamado "MyCustomTimerView.xib". Luego agregué una vista, y a eso agregué una etiqueta y dos botones. Al igual que:UIView
Creé una nueva subclase de clase de objetivo-C llamada "MyCustomTimer". En mi.xib
, configuré la clase Propietario de mi archivo como MyCustomTimer . Ahora soy libre de conectar acciones y salidas como cualquier otra vista / controlador. El.h
archivo resultante se ve así:El único obstáculo que queda por superar es conseguir esto
.xib
en miUIView
subclase. El uso de un.xib
reduce drásticamente la configuración requerida. Y dado que está utilizando guiones gráficos para cargar los temporizadores, sabemos que-(id)initWithCoder:
es el único inicializador que se llamará. Así que así es como se ve el archivo de implementación:El método llamado
loadNibNamed:owner:options:
hace exactamente lo que parece. Carga el Nib y establece la propiedad "Propietario del archivo" en uno mismo. Extraemos el primer objeto de la matriz y esa es la vista raíz del Nib. Agregamos la vista como una subvista y listo, está en la pantalla.Obviamente, esto solo cambia el color de fondo de la etiqueta cuando se presionan los botones, pero este ejemplo debería ayudarlo a avanzar.
Notas basadas en comentarios:
Vale la pena señalar que si tiene problemas de recursividad infinita, probablemente se haya perdido el truco sutil de esta solución. No está haciendo lo que crees que está haciendo. La vista que se coloca en el guión gráfico no se ve, sino que carga otra vista como una subvista. Esa vista que carga es la vista que se define en el nib. El "propietario del archivo" en la plumilla es esa vista invisible. Lo bueno es que esta vista invisible sigue siendo una clase Objective-C que se puede usar como una especie de controlador de vista para la vista que trae desde el nib. Por ejemplo, los
IBAction
métodos de laMyCustomTimer
clase son algo que esperaría más en un controlador de vista que en una vista.Como nota al margen, algunos pueden argumentar que esto se rompe
MVC
y estoy algo de acuerdo. Desde mi punto de vista, está más relacionado con una costumbreUITableViewCell
, que a veces también tiene que ser parte del controlador.También vale la pena señalar que esta respuesta fue para proporcionar una solución muy específica; cree una plumilla que se pueda instanciar varias veces en la misma vista que se presenta en un guión gráfico. Por ejemplo, podría imaginarse fácilmente seis de estos temporizadores en la pantalla de un iPad a la vez. Si solo necesita especificar una vista para un controlador de vista que se usará varias veces en su aplicación, entonces la solución proporcionada por jyavenard a esta pregunta es casi con certeza una mejor solución para usted.
fuente
userInfo
propiedad en la notificación@property(nonatomic,copy) NSDictionary *userInfo;
File's Owner
esté configurado con el nombre de tu clase resolvió mi problema de recursividad infinita.[self addSubview:[[[NSBundle mainBundle] loadNibNamed:@"MyCustomTimerView" owner:self options:nil] objectAtIndex:0]];
Agregar la segunda UIView ... ¿Esto parece extraño para mí, nadie más siente lo mismo? Si es así, ¿es algo que Apple hizo por diseño? ¿O alguien encontró la solución al hacer esto?Ejemplo rápido
Actualizado para Xcode 10 y Swift 4
Aquí hay un recorrido básico. Originalmente aprendí mucho de esto viendo esta serie de videos de Youtube . Más tarde actualicé mi respuesta basada en este artículo .
Agregar archivos de vista personalizados
Los siguientes dos archivos formarán su vista personalizada:
UIView
subclaseLos detalles para agregarlos se encuentran a continuación.
Archivo Xib
Agregue un archivo .xib a su proyecto (Archivo> Nuevo> Archivo ...> Interfaz de usuario> Ver) . Estoy llamando mía
ReusableCustomView.xib
.Cree el diseño que desea que tenga su vista personalizada. A modo de ejemplo, voy a hacer un diseño con una
UILabel
y unaUIButton
. Es una buena idea usar el diseño automático para que las cosas cambien de tamaño automáticamente sin importar el tamaño que establezca más adelante. ( Usé Freeform para el tamaño de xib en el inspector de atributos para poder ajustar las métricas simuladas, pero esto no es necesario).Archivo rápido
Agregue un archivo .swift a su proyecto (Archivo> Nuevo> Archivo ...> Fuente> Archivo Swift) . Es una subclase de
UIView
y yo llamo míaReusableCustomView.swift
.Hacer que el archivo Swift sea el propietario
Vuelva a su archivo .xib y haga clic en "Propietario del archivo" en el esquema del documento. En el Inspector de identidad, escriba el nombre de su archivo .swift como el nombre de la clase personalizada.
Agregar código de vista personalizado
Reemplace el
ReusableCustomView.swift
contenido del archivo con el siguiente código:Asegúrese de escribir correctamente el nombre de su archivo .xib.
Conecta los puntos de venta y las acciones
Conecte los puntos de venta y las acciones controlando el arrastre desde la etiqueta y el botón en el diseño xib hasta el código de vista personalizada rápida.
Usa tu vista personalizada
Su vista personalizada está terminada ahora. Todo lo que tiene que hacer es agregar un
UIView
lugar donde lo desee en su guión gráfico principal. Establezca el nombre de clase de la vista enReusableCustomView
en el Inspector de identidad.fuente
Bundle.main
aBundle(for: ...)
funciona. Aparentemente,Bundle.main
no está disponible en tiempo de diseño.init(frame:)
. Una vez que agrega esto (y extrae todo el código de inicialización en algunacommonInit()
función), funciona bien y se muestra en IB. Vea más información aquí: stackoverflow.com/questions/31265906/…Respuesta para controladores de vista, no vistas :
Existe una forma más fácil de cargar un xib desde un guión gráfico. Digamos que su controlador es del tipo MyClassController que hereda de
UIViewController
.Agrega un
UIViewController
IB usando en su guión gráfico; cambie el tipo de clase para que sea MyClassController. Elimine la vista que se había agregado automáticamente en el guión gráfico.Asegúrese de que el XIB al que desea llamar se llame MyClassController.xib.
Cuando la clase se instanciará durante la carga del guión gráfico, el xib se cargará automáticamente. La razón de esto se debe a la implementación predeterminada de la
UIViewController
cual llama al XIB nombrado con el nombre de la clase.fuente
'Could not load NIB in bundle: 'NSBundle </Users/me/.../MyAppName.app> (loaded)' with name 'uB0-aR-WjG-view-4OA-9v-tyV''
. Tenga en cuenta el whacko nibName. Estoy usando el nombre de clase correcto para el en la plumilla.Esto no es realmente una respuesta, pero creo que es útil compartir este enfoque.
C objetivo
Rápido
Opcional :
Es todo, ahora puede agregar su vista personalizada en su guión gráfico y se mostrará :)
CustomViewWithXib.h :
CustomViewWithXib.m :
CustomViewWithXib.swift :
Puedes encontrar algunos ejemplos aquí .
Espero que ayude.
fuente