La pregunta es simple: ¿cómo se carga personalizado UITableViewCell
desde archivos Xib? Hacerlo le permite usar Interface Builder para diseñar sus celdas. La respuesta aparentemente no es simple debido a problemas de administración de memoria. Este hilo menciona el problema y sugiere una solución, pero es anterior al lanzamiento de NDA y carece de código. Aquí hay un largo hilo que discute el problema sin proporcionar una respuesta definitiva.
Aquí hay un código que he usado:
static NSString *CellIdentifier = @"MyCellIdentifier";
MyCell *cell = (MyCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil];
cell = (MyCell *)[nib objectAtIndex:0];
}
Para usar este código, cree MyCell.m / .h, una nueva subclase de UITableViewCell
y agregue IBOutlets
los componentes que desee. Luego cree un nuevo archivo "XIB vacío". Abra el archivo Xib en IB, agregue un UITableViewCell
objeto, establezca su identificador en "MyCellIdentifier", y establezca su clase en MyCell y agregue sus componentes. Finalmente, conecte el IBOutlets
a los componentes. Tenga en cuenta que no configuramos el propietario del archivo en IB.
Otros métodos recomiendan configurar el propietario del archivo y advertir sobre pérdidas de memoria si el Xib no se carga a través de una clase de fábrica adicional. Probé lo anterior en Instrumentos / Fugas y no vi pérdidas de memoria.
Entonces, ¿cuál es la forma canónica de cargar celdas desde Xibs? ¿Configuramos el propietario del archivo? ¿Necesitamos una fábrica? Si es así, ¿cómo se ve el código para la fábrica? Si hay varias soluciones, aclaremos los pros y los contras de cada una de ellas ...
fuente
Respuestas:
Aquí hay dos métodos que, según el autor original, fueron recomendados por un ingeniero de IB .
Vea la publicación real para más detalles. Prefiero el método # 2 ya que parece más simple.
Método 1:
Método 2:
Actualización (2014): el Método # 2 sigue siendo válido pero ya no hay documentación para ello. Solía estar en los documentos oficiales, pero ahora se elimina a favor de los guiones gráficos.
Publiqué un ejemplo de trabajo en Github:
https://github.com/bentford/NibTableCellExample
editar para Swift 4.2
fuente
La solución correcta es esta:
fuente
Registrarse
Después de iOS 7, este proceso se ha simplificado a ( swift 3.0 ):
Dequeue
Y más tarde, se dejó de usar ( swift 3.0 ):
La diferencia es que este nuevo método no solo quita la celula, sino que también crea si no existe (eso significa que no tiene que hacer
if (cell == nil)
travesuras), y la celda está lista para usar como en el ejemplo anterior.Y, por supuesto, el tipo de la clase asociada de la celda es el que usted definió en el archivo .xib para la
UITableViewCell
subclase, o alternativamente, utilizando el otro método de registro.Configuración
Idealmente, sus celdas ya se han configurado en términos de apariencia y posicionamiento del contenido (como etiquetas y vistas de imágenes) cuando las registró, y en el
cellForRowAtIndexPath
método simplemente las completa.Todos juntos
Y, por supuesto, todo esto está disponible en ObjC con los mismos nombres.
fuente
[self.tableView registerNib:[UINib nibWithNibName:@"BlaBlaTableViewCell" bundle:nil] forCellReuseIdentifier:kCellIdentifier];
Tomó la respuesta de Shawn Craver y la limpió un poco.
BBCell.h:
BBCell.m:
Hago todas las subclases de BBCableViewCell de BBCell, y luego reemplazo el estándar
con:
fuente
Usé el Método # 2 de Bentford :
Funciona, pero ten cuidado con las conexiones con el propietario del archivo en tu archivo UITableViewCell .xib personalizado.
Al pasar
owner:self
suloadNibNamed
estado de cuenta, establece elUITableViewController
como propietario del archivo de suUITableViewCell
.Si arrastra y suelta el archivo de encabezado en IB para configurar acciones y puntos de venta, los configurará como Propietario del archivo de forma predeterminada.
En
loadNibNamed:owner:options
, el código de Apple intentará establecer propiedades en suUITableViewController
, ya que ese es el propietario. Pero no tiene esas propiedades definidas allí, por lo que obtiene un error acerca de ser compatible con la codificación de valores clave :Si se activa un Evento en su lugar, obtendrá una NSInvalidArgumentException:
Una solución fácil es apuntar las conexiones de Interface Builder hacia el
UITableViewCell
propietario del archivo en lugar del:fuente
He decidido publicar porque no me gusta ninguna de estas respuestas: las cosas siempre pueden ser más simples y esta es, con mucho, la forma más concisa que he encontrado.
1. Construye tu Xib en Interface Builder como quieras
2. En su subclase UIViewController o UITableViewController
3. En su MyTableViewCellSubclass
fuente
Si usa Interface Builder para crear celdas, verifique que haya configurado el Identificador en el Inspector. Luego verifique que sea lo mismo cuando llame a dequeueReusableCellWithIdentifier.
Accidentalmente olvidé establecer algunos identificadores en un proyecto pesado, y el cambio de rendimiento fue como la noche y el día.
fuente
Cargar UITableViewCells desde XIB ahorra mucho código, pero generalmente resulta en una velocidad de desplazamiento horrible (en realidad, no es el XIB sino el uso excesivo de UIViews lo que causa esto).
Le sugiero que eche un vistazo a esto: Referencia de enlace
fuente
Este es el método de clase que he estado usando para crear celdas personalizadas a partir de XIB:
Luego, en el XIB, configuro el nombre de la clase y reutilizo el identificador. Después de eso, puedo llamar a ese método en mi controlador de vista en lugar de
Es lo suficientemente rápido y se usa en dos de mis aplicaciones de envío. Es más confiable que llamar
[nib objectAtIndex:0]
, y en mi opinión al menos, más confiable que el ejemplo de Stephan Burlot porque está garantizado que solo obtendrá una vista de un XIB que es el tipo correcto.fuente
La solución correcta es esta
fuente
Recargar la NIB es costoso. Es mejor cargarlo una vez, luego instanciar los objetos cuando necesite una celda. Tenga en cuenta que puede agregar UIImageViews, etc. a la plumilla, incluso varias celdas, utilizando este método (el "registerNIB" de Apple iOS5 solo permite un objeto de nivel superior: error 10580062 "iOS5 tableView registerNib: demasiado restrictivo"
Entonces, mi código está debajo: lees en la NIB una vez (en inicializar como lo hice o en viewDidload, lo que sea. A partir de entonces, instancias la punta en objetos y luego eliges la que necesitas. Esto es mucho más eficiente que cargar la punta una y otra vez.
fuente
Verifique esto - http://eppz.eu/blog/custom-uitableview-cell/ - forma realmente conveniente utilizando una clase pequeña que termina una línea en la implementación del controlador:
fuente
La forma correcta de hacerlo es crear una implementación, encabezado y XIB de la subclase UITableViewCell. En el XIB, elimine cualquier vista y simplemente agregue una celda de tabla. Establezca la clase como el nombre de la subclase UITableViewCell. Para el propietario del archivo, conviértalo en el nombre de clase de subclase UITableViewController. Conecte el propietario del archivo a la celda utilizando la salida tableViewCell.
En el archivo de encabezado:
En el archivo de implementación:
fuente
Lo que hago para esto es declarar un
IBOutlet UITableViewCell *cell
en su clase de controlador. Luego invoque elNSBundle loadNibNamed
método de clase, que alimentaráUITableViewCell
a la celda declarada anteriormente.Para el xib, crearé un xib vacío y agregaré el
UITableViewCell
objeto en IB donde se puede configurar según sea necesario. Esta vista se conecta a la celdaIBOutlet
en la clase de controlador.NSBundle adiciones loadNibNamed (inicio de sesión ADC)
Artículo de cocoawithlove.com de donde obtuve el concepto
fuente
Cree su propia
AbcViewCell
subclase de clase personalizada a partir deUITableViewCell
(Asegúrese de que el nombre del archivo de clase y el nombre del archivo de punta sean los mismos)Cree este método de clase de extensión.
Úsalo.
let cell: AbcViewCell = UITableViewCell.fromNib()
fuente
Primero importe su archivo de celda personalizado
#import "CustomCell.h"
y luego cambie el método de delegado como se menciona a continuación:fuente
En Swift 4.2 y Xcode 10
Tengo tres archivos de celda XIB
en ViewDidLoad registre sus archivos XIB como este ...
Este es el primer acercamiento
El segundo enfoque registra directamente los archivos XIB en cellForRowAt indexPath:
Estas son mis funciones delegadas de tableview
fuente
Aquí está mi método para eso: cargar UITableViewCells personalizadas desde archivos XIB ... Otro método más
La idea es crear una subclase SampleCell de
UITableViewCell
con unaIBOutlet UIView *content
propiedad y una propiedad para cada subvista personalizada que necesita configurar desde el código. Luego, para crear un archivo SampleCell.xib. En este archivo plumín, cambie el propietario del archivo a SampleCell. Agregue un contenidoUIView
dimensionado para satisfacer sus necesidades. Agregue y configure todas las subvistas (etiquetas, vistas de imágenes, botones, etc.) que desee. Finalmente, vincule la vista de contenido y las subvistas al propietario del archivo.fuente
Aquí hay un enfoque universal para registrar células en
UITableView
:Explicación:
Reusable
El protocolo genera ID de celda a partir de su nombre de clase. Asegúrese de seguir la convención:cell ID == class name == nib name
.UITableViewCell
se ajusta alReusable
protocoloUITableView
la extensión abstrae la diferencia en el registro de celdas a través de nib o class.Ejemplo de uso:
fuente
No sé si hay una forma canónica, pero aquí está mi método:
Y usa este código:
En su ejemplo, usando
puede romperse si Apple cambia el orden de los elementos en el xib.
fuente
fuente
Esta extensión requiere Xcode7 beta6
Cree un archivo Xib que contenga solo 1 UITableViewCell personalizado.
Cárgalo.
fuente
fuente