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.

UITableViewCelloUICollectionViewCell. 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
UIViewlugar deNSObject.Para crear una instancia de su temporizador en IB, simplemente arrastre una
UIViewgota en la vista de su controlador de vista y configure su clase con el nombre de la clase de su temporizador.Recuerda
#importsu 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
.xibarchivo 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.xibarchivo.Para probar esto, creé un nuevo vacío
.xibllamado "MyCustomTimerView.xib". Luego agregué una vista, y a eso agregué una etiqueta y dos botones. Al igual que:UIViewCreé 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.harchivo resultante se ve así:El único obstáculo que queda por superar es conseguir esto
.xiben miUIViewsubclase. El uso de un.xibreduce 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
IBActionmétodos de laMyCustomTimerclase 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
MVCy 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
userInfopropiedad en la notificación@property(nonatomic,copy) NSDictionary *userInfo;File's Owneresté 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:
UIViewsubclaseLos 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
UILabely 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
UIViewy 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.swiftcontenido 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
UIViewlugar donde lo desee en su guión gráfico principal. Establezca el nombre de clase de la vista enReusableCustomViewen el Inspector de identidad.fuente
Bundle.mainaBundle(for: ...)funciona. Aparentemente,Bundle.mainno 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
UIViewControllerIB 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
UIViewControllercual 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