2010-10-15 13 views
25

Estoy haciendo un widget personalizado que me gustaría usar en múltiples plumillas. Así que hago una nueva vista en la pantalla Screen3, agrego algunos botones y ahora quiero mi widget UIAwesomeSauce.¿Cómo obtengo una vista en Interface Builder para cargar una vista personalizada en otro plumín?

Si solo agrego una vista y luego cambio la Identidad de clase, no recibe los subelementos de la plumilla UIAwesomeSauce. Lo mismo si voy a la Biblioteca y cambio a Clases. Parece que solo un UIViewController tiene el campo para "Cargar desde la punta", lo que sería hermoso.

Sé que puedo cargar la semilla UIAwesomeSauce del código, obtener los objetos de nivel superior y colocarla a mano. Pero el objetivo de IB es que no tenga que colocar las cosas en el código. Aún mejor sería si pudiera conseguir que UIAwesomeSauce apareciera en la lista de la Biblioteca.

SOLUCIONADO - por Nimrod - Siga leyendo para EXPLICACIÓN Y CÓDIGO

De todos modos, Dood, que es grande. Puedo hacer mis propias clases de widgets ahora para tonterías. Haz que FileOwner de tu UI finge tu clase, y en ella solo tienes una UIView normal con todas tus cosas. (La vista única en el plumín del artilugio no puede ser la clase en sí, o se obtiene recursivo en initWithCoder.) Luego, en el plumín que desea usar, haga un UIView vainilla y cambie su clase. No podrás ver realmente el widget dentro de ese cuadrado, pero trata.

El uno mismo es ahora una vista en blanco, y tMyActualSelf es la única vista en la que hizo el trabajo en el otro plumín. ¡Hurra!

- (id)initWithCoder:(NSCoder*)coder 
{ 
    if ((self = [super initWithCoder:coder])) 
    { 
     UIView *tMyActualSelf = nil; 
     // Initialization code 
     NSArray *tNibItems = [[NSBundle mainBundle] loadNibNamed:@"UIAwesomeSauce" owner:self options:nil]; 
     for (id object in tNibItems) 
     { 
      if ([object isKindOfClass:[UIView class]]) 
       tMyActualSelf = (UIView *)[object retain]; 
     } 
     if(tMyActualSelf) 
     { 
      tMyActualSelf.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height); 
      [self addSubview:tMyActualSelf]; 
     } 
    } 
    return self; 
} 

Respuesta

14

me siento su dolor cuando se trata de la UIViewController ser el único que se puede especificar una carga punta con, pero yo creo que es porque no tiene que ser propietario de un archivo que es un controlador, o algo por el estilo, aunque no estoy seguro de por qué un UIView no puede ser el propietario de un archivo.

Creo que puedes poner objetos en la biblioteca en Objetos personalizados, pero creo que estarías limitado a poner una UIView allí con la clase que acaba de configurar en una subclase personalizada de UIView. De hecho, busqué extender el constructor de interfaz y parece que puedes hacerlo para cosas de OS X, pero no para iPhone. Implica compilar el código para el nuevo widget en el constructor de interfaz para decirle cómo dibujar el widget solo dentro de IB. Creo que en realidad hay una plantilla OS X para esto.

Creo que lo que probablemente haría es crear una vista principal en un archivo de punta que contenga todas las subvistas, luego en initWithCoder: en la cosa UIAwesomeSauce abra el archivo nib, cargue la vista principal, y simplemente colóquelo dentro auto para que tenga una vista "innecesaria" entre la vista UIAwesomeSauce y las subvistas (o sub subvistas según sea el caso). No estoy seguro de lo ineficiente que es, pero al jugar con algunas cosas parece que algunas vistas como UIWebView parece tener una de estas vistas intermedias aparentemente innecesarias (IIRC).

Si se te ocurre una solución mejor, dímelo porque me gustaría saberlo también.

EDITAR

Ahora que lo miro, creo que el UIView PUEDE ser el propietario del archivo, que simplemente no puede configurarlo en IB. Básicamente lo que podríamos llamar la carga punta de algo como esto en la subclase UIView:

[lote loadNibNamed: "@" UISpecialSauce propietario: opciones de asistencia: ...]

Creo que si se crea o puntos de venta en UISpecialSauce lo que sea, deberían asignarse correctamente debido al propietario: self.

+1

Eso es tan brillante que quiero hornear un pastel. – CBGraham

+0

¡Yay! Finalmente obtuve suficientes puntos para votar en las publicaciones, así que ya está. (Debería poder votar en publicaciones sobre sus propias preguntas, al igual que puede comentar las publicaciones de sus propias preguntas.) – CBGraham

+0

Para cualquier persona (como yo) que escaneó la pregunta y leyó la respuesta en detalle, el asker puso su "SOLUCIONADO" "código como una edición en su pregunta original. –

1

Hay un cocoapod que en realidad podría ayudar con eso: https://github.com/mobilejazz/NibWrapper

Proporciona una vista de contenedor que carga un niño, vista desde otra SEMILLA. Puede especificar el nombre de ese constructor de interfaz NIB dentro de un atributo de tiempo de ejecución.

+0

Gracias, lo he usado después de encontrar tu referencia. Fue una gran ayuda después de días de lectura. La única vergüenza es que hay un nivel de direccionamiento indirecto, ya que tienes que establecer un marcador de posición UIView (de la clase UINibWraper), y de ahí puedes obtener una referencia a tu UIView personalizado. Hay otro cocoapod que adopta un enfoque diferente que, en teoría, elimina esta capa adicional (UIView + NibLoading), pero el uso de restricciones de autolayout en la vista personalizada me falló. –

Cuestiones relacionadas