Según tengo entendido, quieres:
- Diseñe una celda en IB que se pueda usar en varias escenas del guión gráfico.
- Configure segmentos únicos del guión gráfico desde esa celda, dependiendo de la escena en la que se encuentre la celda.
Desafortunadamente, actualmente no hay forma de hacer esto. Para comprender por qué sus intentos anteriores no funcionaron, debe comprender más sobre cómo funcionan los guiones gráficos y las celdas de vista de tabla prototipo. (Si no le importa por qué estos otros intentos no funcionaron, siéntase libre de irse ahora. No tengo soluciones mágicas para usted, aparte de sugerirle que presente un error).
Un guión gráfico no es, en esencia, mucho más que una colección de archivos .xib. Cuando carga un controlador de vista de tabla que tiene algunas celdas prototipo fuera de un guión gráfico, esto es lo que sucede:
- Cada celda prototipo es en realidad su propia mini punta incrustada. Entonces, cuando el controlador de vista de tabla se está cargando, se ejecuta a través de cada punta y llamada de la celda prototipo
-[UITableView registerNib:forCellReuseIdentifier:]
.
- La vista de tabla le pide al controlador las celdas.
- Probablemente llames
-[UITableView dequeueReusableCellWithIdentifier:]
Cuando solicita una celda con un identificador de reutilización determinado, comprueba si tiene una punta registrada. Si lo hace, crea una instancia de esa célula. Esto se compone de los siguientes pasos:
- Mire la clase de la celda, como se define en la punta de la celda. Llamar
[[CellClass alloc] initWithCoder:]
.
- El
-initWithCoder:
método pasa y agrega subvistas y establece propiedades que se definieron en la punta. ( IBOutlet
s probablemente también se enganche aquí, aunque no lo he probado; puede suceder en -awakeFromNib
)
Configura su celda como quiera.
Lo importante a destacar aquí es que hay una distinción entre la clase de la célula y el aspecto visual de la celda. Podría crear dos celdas prototipo separadas de la misma clase, pero con sus subvistas presentadas de manera completamente diferente. De hecho, si usa los UITableViewCell
estilos predeterminados , esto es exactamente lo que está sucediendo. El estilo "Predeterminado" y el estilo "Subtítulo", por ejemplo, están representados por la misma UITableViewCell
clase.
Esto es importante : la clase de la celda no tiene una correlación uno a uno con una jerarquía de vista particular . La jerarquía de vistas está determinada completamente por lo que hay en la celda prototipo que se registró con este controlador en particular.
Tenga en cuenta, además, que el identificador de reutilización de la celda no estaba registrado en algún dispensario global de celdas. El identificador de reutilización solo se usa dentro del contexto de una sola UITableView
instancia.
Dada esta información, veamos lo que sucedió en los intentos anteriores.
En el Controlador n. ° 1, agregué una celda prototipo, configuré la clase en mi subclase UITableViewCell, configuré el ID de reutilización, agregué las etiquetas y las conecté a las salidas de la clase. En el Controlador n. ° 2, agregó una celda prototipo vacía, configúrela en la misma clase y reutilice la identificación como antes. Cuando se ejecuta, las etiquetas nunca aparecen cuando las celdas se muestran en el Controlador # 2. Funciona bien en el controlador # 1.
Esto es de esperarse. Si bien ambas celdas tenían la misma clase, la jerarquía de vistas que se pasó a la celda en el Controlador # 2 estaba completamente desprovista de subvistas. Entonces tienes una celda vacía, que es exactamente lo que pones en el prototipo.
Diseñó cada tipo de celda en un NIB diferente y lo conectó a la clase de celda apropiada. En storyboard, agregué una celda prototipo vacía y configuré su clase y reutilicé la identificación para referirme a mi clase de celda. En los métodos viewDidLoad de los controladores, se registraron esos archivos NIB para la identificación de reutilización. Cuando se muestra, las células en ambos controladores estaban vacías como el prototipo.
De nuevo, esto se espera. El identificador de reutilización no se comparte entre las escenas o plumillas del guión gráfico, por lo que el hecho de que todas estas celdas distintas tuvieran el mismo identificador de reutilización no tenía sentido. La celda que recupere de la vista de tabla tendrá una apariencia que coincide con la celda prototipo en esa escena del guión gráfico.
Sin embargo, esta solución estaba cerca. Como notó, podría llamar programáticamente -[UITableView registerNib:forCellReuseIdentifier:]
, pasando el que UINib
contiene la celda, y volvería a esa misma celda. (Esto no se debe a que el prototipo estaba "anulando" la punta; simplemente no había registrado la punta con la vista de tabla, por lo que todavía estaba mirando la punta incrustada en el guión gráfico.) Desafortunadamente, hay un defecto con este enfoque: no hay forma de conectar los segmentos del guión gráfico a una celda en una punta independiente.
Los prototipos mantenidos en ambos controladores vacían y configuran la clase y reutilizan la identificación en mi clase de celda. Construyó la interfaz de usuario de las celdas completamente en código. Las células funcionan perfectamente en todos los controladores.
Naturalmente. Con suerte, esto no es sorprendente.
Entonces, por eso no funcionó. Puede diseñar sus celdas en puntas independientes y usarlas en múltiples escenas del guión gráfico; actualmente no puede conectar los segmentos del guión gráfico a esas celdas. Sin embargo, es de esperar que hayas aprendido algo en el proceso de leer esto.
A pesar de la gran respuesta de BJ Homer, siento que tengo una solución. En lo que respecta a mis pruebas, funciona.
Concepto: cree una clase personalizada para la celda xib. Allí puede esperar un evento táctil y realizar la segue mediante programación. Ahora todo lo que necesitamos es una referencia al controlador que realiza la Segue. Mi solución es configurarlo
tableView:cellForRowAtIndexPath:
.Ejemplo
Tengo una
DetailedTaskCell.xib
celda de tabla que me gustaría usar en varias vistas de tabla:Hay una clase personalizada
TaskGuessTableCell
para esa celda:Aquí es donde sucede la magia.
Puedo tener varias Segues pero todos tienen el mismo nombre:
"FinishedTask"
. Si necesita ser flexible aquí, le sugiero agregar otra propiedad.El ViewController se ve así:
Puede haber formas más elegantes de lograr lo mismo, ¡pero funciona! :)
fuente
-setSelected:
en la celda y desencadenando el segue solo cuando haga la transición deNO
aYES
.setSelected:
BJ. Gracias. De hecho, es una solución poco elegante (se siente mal), pero al mismo tiempo funciona, así que la estoy usando hasta que esto se arregle (o algo cambie en la corte de Apple).Estaba buscando esto y encontré esta respuesta de Richard Venable. Esto funciona para mi.
fuente
BJ Homer ha dado una excelente explicación de lo que está sucediendo.
Desde un punto de vista práctico, agregaría que, dado que no puede tener celdas como xib Y conectar segues, la mejor opción es tener la celda como xib: las transiciones son mucho más fáciles de mantener que los diseños y propiedades de la celda en múltiples lugares , y es probable que sus valores sean diferentes de sus diferentes controladores de todos modos. Puede definir el segue directamente desde su controlador de vista de tabla al siguiente controlador y realizarlo en código. .
Una nota adicional es que tener su celda como un archivo xib separado evita que pueda conectar cualquier acción, etc. directamente al controlador de vista de tabla (de todos modos, no he resuelto esto; no puede definir el propietario del archivo como algo significativo ) Estoy trabajando en esto definiendo un protocolo que se espera que el controlador de vista de tabla de la celda cumpla y agregando el controlador como una propiedad débil, similar a un delegado, en cellForRowAtIndexPath.
fuente
Swift 3
BJ Homer dio una excelente explicación, me ayuda a entender el concepto. To
make a custom cell reusable in storyboard
, que puede usarse en cualquier TableViewController, tenemos quemix the Storyboard and xib
acercarnos. Supongamos que tenemos una celda llamada comoCustomCell
que se utilizará enTableViewControllerOne
yTableViewControllerTwo
. Lo estoy haciendo en pasos.1. Archivo> Nuevo> Haga clic en Archivo> Seleccione Cocoa Touch Class> haga clic en Siguiente> Dar nombre de su clase (por ejemplo
CustomCell
)> seleccione Subclase como UITableVieCell> Marque la casilla también crear archivo XIB y presione Siguiente.2. Personalice la celda como desee y configure el identificador en el inspector de atributos para la celda, aquí lo configuraremos como
CellIdentifier
. Este identificador se usará en su ViewController para identificar y reutilizar la celda.3. Ahora solo tenemos que
register this cell
en nuestro ViewControllerviewDidLoad
. No es necesario ningún método de inicialización.4. Ahora podemos usar esta celda personalizada en cualquier tableView.
En TableViewControllerOne
fuente
Encontré una manera de cargar la celda para el mismo VC, no probé los segmentos. Esto podría ser una solución para crear la celda en una punta separada
Digamos que tiene una tabla de VC y 2 tablas y desea diseñar una celda en el guión gráfico y usarla en ambas tablas.
(por ejemplo, una tabla y un campo de búsqueda con un UISearchController con una tabla de resultados y desea utilizar la misma celda en ambos)
Cuando el controlador solicite la celda, haga esto:
Y aquí tienes tu celular del guión gráfico
fuente
tableView:cellForRowAtIndexPath:
).