Soy consciente de que esta pregunta se ha hecho antes, pero las respuestas son contradictorias y estoy confundido, así que no me llames.
Quiero tener una UIView
subclase reutilizable en toda mi aplicación. Quiero describir la interfaz usando un archivo nib.
Ahora digamos que es una vista de indicador de carga con un indicador de actividad. Me gustaría en algún evento crear una instancia de esta vista y animarla en la vista de un controlador de vista. Podría describir la interfaz de la vista sin problemas mediante programación, creando los elementos mediante programación y estableciendo su marco dentro de un método de inicio, etc.
Sin embargo, ¿cómo puedo hacer esto usando una punta? Mantener el tamaño dado en el generador de interfaces sin tener que establecer un marco.
Me las arreglé para hacerlo así, pero estoy seguro de que está mal (es solo una vista con un selector):
- (id)initWithDataSource:(NSDictionary *)dataSource {
self = [super init];
if (self){
self = [[[NSBundle mainBundle] loadNibNamed:[NSString stringWithFormat:@"%@", [self class]] owner:self options:nil] objectAtIndex:0];
self.pickerViewData = dataSource;
[self configurePickerView];
}
return self;
}
Pero me estoy sobrescribiendo a mí mismo, y cuando lo instancia:
FSASelectView *selectView = [[FSASelectView alloc] initWithDataSource:selectViewDictionary];
selectView.delegate = self;
selectView.frame = CGRectMake(0, self.view.bottom + 50, [FSASelectView width], [FSASelectView height]);
Tengo que configurar manualmente el marco en lugar de que lo recojan de IB.
EDITAR: Quiero crear esta vista personalizada en un controlador de vista y tener acceso para controlar los elementos de la vista. No quiero un nuevo controlador de vista.
Gracias
EDITAR: No sé si esta es la mejor práctica, estoy seguro de que no lo es, pero así es como lo hice:
FSASelectView *selectView = [[[NSBundle mainBundle] loadNibNamed:[NSString stringWithFormat:@"%@",[FSASelectView class]] owner:self options:nil] objectAtIndex:0];
selectView.delegate = self;
[selectView configurePickerViewWithData:ds];
selectView.frame = CGRectMake(0, self.view.bottom + 50, selectView.width, selectView.height);
selectView.alpha = 0.9;
[self.view addSubview:selectView];
[UIView animateWithDuration: 0.25 delay: 0 options:UIViewAnimationOptionAllowUserInteraction |UIViewAnimationOptionCurveEaseInOut animations:^{
selectView.frame = CGRectMake(0, self.view.bottom - selectView.height, selectView.width, selectView.height);
selectView.alpha = 1;
} completion:^(BOOL finished) {
}];
Todavía se quiere la práctica correcta
¿Debería haberse hecho esto usando un controlador de vista e init con el nombre de nib? ¿Debería haber configurado la punta en algún método de inicialización de UIView en el código? ¿O está bien lo que he hecho?
initWithDataSource
? De todos modos, esto funcionará incluso si le da propietario como 'Nil'.Respuestas:
Estoy usando esto para inicializar las vistas personalizadas reutilizables que tengo.
Tenga en cuenta que puede usar "firstObject" al final, es un poco más limpio. "firstObject" es un método útil para NSArray y NSMutableArray.
Aquí hay un ejemplo típico de cargar un xib para usarlo como encabezado de tabla. En su archivo YourClass.m
Normalmente, en el
TopArea.xib
, haría clic en Propietario del archivo y establecería el propietario del archivo en YourClass . Entonces, en realidad, en YourClass.h tendrías propiedades IBOutlet. EnTopArea.xib
, puede arrastrar los controles a esos puntos de venta.No olvides que en
TopArea.xib
, es posible que tengas que hacer clic en la Vista y arrastrarla a alguna salida, para que tengas el control de ella, si es necesario. (Un consejo que vale la pena es que cuando está haciendo esto para las filas de celdas de la tabla, es absolutamente necesario que lo haga: debe conectar la vista a la propiedad relevante en su código).fuente
Si desea mantener su
CustomView
y suxib
independienteFile's Owner
, siga estos pasosFile's Owner
campo vacío.xib
archivoCustomView
y establezca suCustom Class
comoCustomView
(nombre de su clase de vista personalizada)IBOutlet
en el.h
archivo de la vista personalizada..xib
archivo de su vista personalizada, haga clic en Ver y accedaConnection Inspector
. Aquí tendrás todos tus IBOutlets que definas en.h
archivoen el
.m
archivo de suCustomView
clase, anule elinit
método de la siguiente maneraAhora, cuando quieras cargar tu
CustomView
, usa la siguiente línea de código[[CustomView alloc] init];
fuente
-init
. En su lugar, llamaráinitWithFrame:
y-awakeFromNib
. Si escribe el mismo código para cargar su vista que en el-init
método, ingresará un bucle infinito.Siga los siguientes pasos
UIView
.MyView.xib
.UIViewController
fromNSObject
in xib. Ver la imagen de abajoConecte la vista del propietario del archivo a su vista. Ver la imagen de abajo
Cambie la clase de su Vista a
MyView
. Igual que 3.Aquí está el código para cargar la Vista:
Espero eso ayude.
Aclaración :
UIViewController
se usa para cargar su xib y la vista queUIViewController
tiene es realmente laMyView
que ha asignado en el xib de MyView.Demostración he hecho un robo de demostración aquí
fuente
Respondiendo a mi propia pregunta acerca de 2 años más tarde aquí, pero ...
Utiliza una extensión de protocolo para que pueda hacerlo sin ningún código adicional para todas las clases.
fuente
En Swift:
Por ejemplo, el nombre de su clase personalizada es
InfoView
Al principio, creas archivos
InfoView.xib
yInfoView.swift
así:A continuación, establezca
File's Owner
aUIViewController
desea:Cambie el nombre de su
View
aInfoView
:Haga clic derecho
File's Owner
y conecte suview
campo con suInfoView
:Asegúrese de que el nombre de la clase sea
InfoView
:Y después de esto, puede agregar la acción al botón en su clase personalizada sin ningún problema:
Y el uso de esta clase personalizada en su
MainViewController
:fuente
Bueno, podría inicializar el xib usando un controlador de vista y usar viewController.view. o hazlo de la forma en que lo hiciste. Hacer solo una
UIView
subclase como controladorUIView
es una mala idea.Si no tiene salidas desde su vista personalizada, puede usar directamente una
UIViewController
clase para inicializarla.Actualización: En su caso:
De lo contrario, tiene que hacer un personalizado
UIViewController
(para convertirlo en el propietario del archivo para que las salidas estén correctamente conectadas).Donde quiera que desee agregar la vista, puede usarla.
Sin embargo, pasar el otro controlador de vista (que ya se está utilizando para otra vista) como propietario mientras se carga el xib no es una buena idea, ya que la propiedad de vista del controlador cambiará y cuando desee acceder a la vista original, no lo hará. tener una referencia a él.
EDITAR: Se enfrentará a este problema si ha configurado su nuevo xib con el propietario del archivo como la misma
UIViewController
clase principal y ha vinculado la propiedad de la vista a la nueva vista xib.es decir;
El siguiente código causará confusión más adelante, si lo escribe dentro de la vista se cargó
YourMainViewController
. Eso se debe a que aself.view
partir de este punto se referirá a su vista personalizadafuente