Estoy tratando de utilizar guiones gráficos en una aplicación que estoy trabajando. En la app hay Listas y Usuarios y cada uno contiene una colección de los otros (los miembros de una lista, las listas de propiedad de un usuario). Así que, en consecuencia, he ListCell y UserCell clases. El objetivo es re-utilizable en toda la aplicación (es decir, en ninguna de mis formato tableview controladores).

Que es donde me estoy quedando en un problema.

¿Cómo puedo crear un personalizado en formato tableview de células en el guión gráfico que puede ser re-utilizado en cualquier controlador de vista?

Aquí son las cosas específicas que he probado hasta ahora.

  • En el Controlador #1, agregado de un prototipo de celda, conjunto de la clase a mi UITableViewCell subclase, establecer la reutilización de identificación, se añaden las etiquetas y por cable a la clase de los establecimientos. En el Controlador #2, añadió vacío de un prototipo de celda, establece a la misma clase y reutilización de identificación como antes. Cuando se ejecuta, las etiquetas nunca aparecen cuando las células se muestran en el Controlador #2. Funciona bien en el Controlador #1.

  • Diseñado cada tipo de célula en otro PLUMILLA y conectado a la celda apropiada de la clase. En el guión gráfico, agregó vacío de un prototipo de celda y establece su clase y la reutilización de identificación para referirse a mi clase de células. En los controladores de viewDidLoad métodos, registrado a los NIB para la reutilización de identificación. Cuando se muestra, las células en ambos controladores estaban vacías como el prototipo.

  • Mantenido prototipos en los dos controladores de vacío y el conjunto de la clase y la reutilización id a mi clase de células. Construido de las células de interfaz de usuario completamente en código. Las células funcionan perfectamente en todos los controladores.

En el segundo caso, sospecho que el prototipo es siempre primordial de la PUNTA y si se me muere el prototipo de las células, el registro de mi PUNTA para la reutilización de id de trabajo. Pero entonces yo no sería capaz de configuración permite una transición de las células a otros cuadros, que es realmente el punto de uso de storyboards.

Al final del día, quiero dos cosas: el cable de seguridad en formato tableview los flujos basados en el guión gráfico y definir la celda diseños visualmente más bien que en el código. Yo no puedo ver cómo llegar tanto de los hasta ahora.

InformationsquelleAutor Cliff W | 2012-02-12

6 Comentarios

  1. 205

    Como yo lo entiendo, usted desea:

    1. Diseño de una celda de IB que puede ser utilizado en múltiples guión de escenas.
    2. Configurar único guión segues de esa célula, dependiendo de la escena de la celda.

    Lamentablemente, actualmente no hay manera de hacer esto. Para entender por qué sus intentos anteriores no funcionan, usted necesita entender más acerca de cómo los storyboards y prototipo de la vista de tabla de trabajo de las células. (Si usted no se preocupan por por qué estos otros intentos no funcionan, siéntase libre de dejar ahora. No tengo soluciones mágicas para usted, aparte de lo que sugiere que presentar un error.)

    Un storyboard es, en esencia, no es más que una colección de .xib archivos. Cuando se carga una tabla de controlador de vista de que tiene algún prototipo de las células de un storyboard, he aquí lo que sucede:

    • Cada prototipo de células es en realidad su propio integrados mini-one. Así que cuando la vista de la tabla es el controlador de carga, se ejecuta a través de cada uno de los prototipos de la célula puntas y llamadas -[UITableView registerNib:forCellReuseIdentifier:].
    • La vista de la mesa pide el controlador para las células.
    • Probablemente llame -[UITableView dequeueReusableCellWithIdentifier:]
    • Cuando usted solicita una celda con un determinado reutilización identificador, se comprueba si tiene una punta registrado. Si lo hace, se crea una instancia de esa celda. Este se compone de los siguientes pasos:

      1. Vistazo a la clase de la célula, tal como se define en la celda de punta. Llame [[CellClass alloc] initWithCoder:].
      2. La -initWithCoder: método va a través y añade subvistas y conjuntos de propiedades que se han definido en la punta. (IBOutlets probablemente conoce aquí también, aunque yo no he probado eso; puede suceder que en -awakeFromNib)
    • De configurar su celda sin embargo que usted desea.

    Lo importante a destacar aquí es que hay una distinción entre el clase de la célula y la el aspecto visual de la de la célula. Usted podría crear dos prototipo de células de la misma clase, pero con sus subvistas establecidos de manera completamente diferente. De hecho, si se usa el valor predeterminado UITableViewCell estilos, esto es exactamente lo que está sucediendo. El estilo «Predeterminado» y el «Subtítulo» de estilo, por ejemplo, están representadas por el mismo UITableViewCell clase.

    Esto es importante: El clase de la celda no tiene un uno-a-uno correlación con un particular vista de la jerarquía de. El punto de vista de la jerarquía está determinada completamente por lo que en el prototipo de celda que fue registrado con este controlador en particular.

    Nota, además, que la célula es la reutilización de identificador no se ha registrado en algunas mundial de la célula dispensario. La reutilización identificador se utiliza solamente dentro del contexto de un único UITableView instancia.


    Dada esta información, echemos un vistazo a lo que ocurrió en sus anteriores intentos.

    En el Controlador #1, agregado de un prototipo de celda, conjunto de la clase a mi
    UITableViewCell subclase, establecer la reutilización de identificación, se añaden las etiquetas y por cable
    a la clase de los establecimientos. En el Controlador #2, añadió un vacío
    prototipo de celda, establece a la misma clase y reutilización de identificación como antes. Cuando
    se ejecuta, las etiquetas nunca aparecen cuando las células se muestran en
    El controlador #2. Funciona bien en el Controlador #1.

    Se espera. Mientras tanto las células tenían la misma clase, el punto de vista de la jerarquía que se pasó a la celda en el Controlador #2 estaba completamente desprovisto de subvistas. Así que usted tiene una celda vacía, que es exactamente lo que pone en el prototipo.

    Diseñado cada tipo de célula en otro PLUMILLA y conectado a la
    adecuado clase de células. En el guión gráfico, agregó vacío de un prototipo de celda
    y establece su clase y la reutilización de identificación para referirse a mi clase de células. En
    los controladores de viewDidLoad métodos, registrado a los NIB para la
    la reutilización de identificación. Cuando se muestra, las células en ambos controladores estaban vacías como la
    el prototipo.

    De nuevo, esto es de esperar. La reutilización de identificador no es compartida entre el guión de escenas o puntas, por lo que el hecho de que todas estas distintas células tenían la misma reutilización identificador tenía sentido. La celda se obtiene del formato tableview tendrá un aspecto que coincide con el prototipo de celda de esa escena del guión gráfico.

    Esta solución estaba cerca, sin embargo. Como se señaló, sólo podía llamar mediante programación -[UITableView registerNib:forCellReuseIdentifier:], pasando el UINib que contiene la celda, y había de volver a la misma celda. (Esto no es debido a que el prototipo fue «prioritaria» la punta; simplemente no había registrado la punta con el formato tableview, así que todavía estaba mirando el plumín incrustado en el guión gráfico.) Por desgracia, hay un error con este enfoque, no hay manera de conectar guión da paso a una celda en una independiente de punta.

    Mantenido prototipos en los dos controladores de vacío y el conjunto de la clase y la reutilización de identificación
    para mi clase de células. Construido de las células de interfaz de usuario completamente en código. Las células
    funcionan perfectamente en todos los controladores.

    De forma natural. Con suerte, esto no es sorprendente.


    Así que por eso no funcionó. Usted puede diseñar sus células independientes puntas y el uso de ellos en múltiples guión de escenas; usted simplemente no puede actualmente gancho guión lleva a esas células. Esperemos que, a pesar de que has aprendido algo en el proceso de la lectura de este.

    • Ah, entiendo. Lo habéis clavado a mi malentendido—el punto de vista de la jerarquía es completamente independiente de mi clase. Obvio en retrospectiva! Gracias por la gran respuesta.
    • No es imposible, parece: stackoverflow.com/questions/8574188/…
    • He mencionado que la solución en mi respuesta. Pero no está en el guión; es separado en una Punta. Por lo que no podía conectar desemboca o hacer otras storyboard-ish cosas. Por lo tanto, no está totalmente de dirección de la pregunta inicial.
    • Como de XCode8 la siguiente solución que parece funcionar si desea un guión única solución. Paso 1) Crear un prototipo de celda en un formato tableview en ViewController #1 y asociado con la costumbre UITableViewCell clase Paso 2) Copiar / Pegar de esa celda en ViewController #2 formato tableview. Con el tiempo usted tiene que recordar para propagar manualmente las actualizaciones, copias de la célula mediante la eliminación de las copias que has hecho en el guión gráfico y pegar de nuevo en la actualización del prototipo.
  2. 58

    A pesar de la gran respuesta por BJ Homero me siento como que tengo una solución. Tan lejos como mis pruebas va, funciona.

    Concepto: Crear una clase personalizada para el xib de la célula. No se puede esperar para dar un toque de eventos y realizar el pase mediante programación. Ahora todo lo que necesitamos es una referencia para el controlador de realizar el Pase. Mi solución es establecer de tableView:cellForRowAtIndexPath:.

    Ejemplo

    Tengo un DetailedTaskCell.xib que contiene una celda de la tabla que me gustaría utilizar en múltiples vistas de tabla:

    En un storyboard, ¿cómo puedo hacer que una celda personalizada para su uso con varios controladores?

    Hay una clase personalizada TaskGuessTableCell para que la célula:

    En un storyboard, ¿cómo puedo hacer que una celda personalizada para su uso con varios controladores?

    Aquí es donde sucede la magia.

    //TaskGuessTableCell.h
    #import <Foundation/Foundation.h>
    
    @interface TaskGuessTableCell : UITableViewCell
    @property (nonatomic, weak) UIViewController *controller;
    @end
    
    //TashGuessTableCell.m
    #import "TaskGuessTableCell.h"
    
    @implementation TaskGuessTableCell
    
    @synthesize controller;
    
    - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
    {
        NSIndexPath *path = [controller.tableView indexPathForCell:self];
        [controller.tableView selectRowAtIndexPath:path animated:NO scrollPosition:UITableViewScrollPositionNone];
        [controller performSegueWithIdentifier:@"FinishedTask" sender:controller];
        [super touchesEnded:touches withEvent:event];
    }
    
    @end

    Tengo varias Desemboca pero todos ellos tienen el mismo nombre: "FinishedTask". Si usted debe ser flexible, sugiero agregar otra propiedad.

    El ViewController se parece a esto:

    //LogbookViewController.m
    #import "LogbookViewController.h"
    #import "TaskGuessTableCell.h"
    
    @implementation LogbookViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad]
    
        //register custom nib
        [self.tableView registerNib:[UINib nibWithNibName:@"DetailedTaskCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"DetailedTaskCell"];
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        TaskGuessTableCell *cell;
    
        cell = [tableView dequeueReusableCellWithIdentifier:@"DetailedTaskCell"];
        cell.controller = self; //<-- the line that matters
        //if you added the seque property to the cell class, set that one here
        //cell.segue = @"TheSegueYouNeedToTrigger";
        cell.taskTitle.text  = [entry title];
        //set other outlet values etc. ...
    
        return cell;
    }
    
    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    {
        if([[segue identifier] isEqualToString:@"FinishedTask"])
        {
            //do what you have to do, as usual
        }
    
    }
    
    @end

    No podría ser más elegante maneras de lograr el mismo pero funciona! 🙂

    • Gracias, estoy a la aplicación de este enfoque en mi proyecto. Puede invalidar este método en lugar de modo que usted no tiene que obtener la indexPath y seleccionar la fila a sí mismo: -(void)setSelected:(BOOL)seleccionado animados:(BOOL)animadas { [super setSelected:seleccionado de animación:animación]; if(seleccionado) [auto.controlador de performSegueWithIdentifier:auto.segue remitente:auto]; } pensé super seleccione la celda cuando se llama [super touchesEnded:toques withEvent:evento];. ¿Sabes cuando es seleccionado si no hay?
    • Tenga en cuenta que con esta solución, eres la activación de la aplicación cada vez que un toque termina dentro de una celda. Esto incluye si usted es simplemente el desplazamiento de la célula, en realidad, no tratando de seleccionar. Usted podría tener mejor suerte primordial -setSelected: en la célula, y la activación de la aplicación sólo cuando la transición de NO a YES.
    • Tengo mejor suerte con setSelected:, BJ. Gracias. En efecto, es una solución poco elegante (que se siente mal), pero al mismo tiempo, funciona, así que lo estoy usando hasta que esto se solucione (o algo cambia en la Manzana de la corte).
  3. 16

    Estaba buscando esto y he encontrado esta respuesta por Richard Venable. A mí me funciona.

    iOS 5 incluye un nuevo método de UITableView: registerNib:forCellReuseIdentifier:

    A utilizar, poner un UITableViewCell en una punta. Tiene que ser la única raíz
    objeto en la punta.

    Puede registrar la punta después de cargar su formato tableview, entonces cuando
    llame dequeueReusableCellWithIdentifier: con el identificador de celda, se
    va a tirar de la punta, como si se hubiera utilizado un Guión gráfico
    prototipo de celda.

  4. 10

    BJ Homero se ha dado una excelente explicación de lo que está pasando.

    Desde un punto de vista práctico, me gustaría añadir que, dado que no se puede tener células como xibs Y conectar segues, el mejor para elegir es tener el celular como un xib – las transiciones son mucho más fáciles de mantener que las células diseños y propiedades a través de múltiples lugares, y su segues probablemente sean diferentes a las de sus diferentes controladores de todos modos. Puede definir el pase directamente de la tabla de la vista controlador a la siguiente controlador, y la realizan en el código. .

    Una mayor nota es que tener a tu celular como un independiente xib archivo impide que ser capaz de conectar cualquier tipo de acciones, etc. directamente a la tabla de la vista controlador (no he trabajado en esto, de todos modos – no se puede definir propietario del archivo como algo significativo). Estoy trabajando en torno a este concepto la definición de un protocolo que la celda de la tabla del controlador de vista se debería ajustar y añadir el controlador como un débil propiedad, similar a un delegado, en cellForRowAtIndexPath.

    • Sí, yo creo que esta es la dirección que voy a ir también. Gracias.
  5. 10

    Swift 3

    BJ Homero dio una excelente explicación, me ayuda a entender el concepto. A make a custom cell reusable in storyboard, que puede ser utilizado en cualquier TableViewController tenemos que mix the Storyboard and xib enfoque. Supongamos que tenemos una celda denominada como CustomCell que se utiliza en la TableViewControllerOne y TableViewControllerTwo. Lo estoy haciendo en los pasos.

    1. Archivo > Nuevo > haga Clic en Archivo > Seleccione Cocoa Touch Clase > haga clic en Siguiente > Nombre De la clase(por ejemplo CustomCell) > seleccione la Subclase como UITableVieCell > marcar la también crear archivo XIB casilla de verificación y pulse Siguiente.

    2. Personalizar el celular como desee y establecer el identificador de atributo inspector de la celda, aquí nos ll establecer como CellIdentifier. Este identificador será utilizado en su ViewController para identificar y reutilización de la Célula.

    3. Ahora sólo tenemos que register this cell en nuestro ViewController viewDidLoad. No hay necesidad de cualquier método de inicialización.

    4. Ahora podemos utilizar esta celda personalizada en cualquier formato tableview.

    En TableViewControllerOne

    let reuseIdentifier = "CellIdentifier"
    
    override func viewDidLoad() {
    super.viewDidLoad()
    tableView.register(UINib(nibName: "CustomCell", bundle: nil), forCellReuseIdentifier: reuseIdentifier)
    } 
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier:reuseIdentifier, for: indexPath) as! CustomCell
        return cell!
    }
  6. 5

    He encontrado una manera de cargar el celular para el mismo VC, no se han probado para la lleva. Esto podría ser una solución para la creación de la célula en un aparte de la plumilla de

    Digamos que usted tiene una VC y 2 mesas y desea diseñar una celda en el guión y el uso en ambas tablas.

    (ex: 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 solicita para la celda de hacer esto:

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString * identifier = @"CELL_ID";
    
        ContactsCell *cell = [self.YOURTABLEVIEW dequeueReusableCellWithIdentifier:identifier];
      //Ignore the "tableView" argument
    }

    Y aquí tiene su celular desde el storyboard

    • He intentado esto y parece trabajar, sin EMBARGO las células nunca se vuelven a usar. El sistema siempre crea y deallocs células nuevas cada vez.
    • Esta es la misma recomendación que se puede encontrar en la Adición de una Barra de Búsqueda a la Vista de la Tabla Con los Storyboards. Si usted está interesado, hay una explicación más a fondo de esta solución (la búsqueda de tableView:cellForRowAtIndexPath:).
    • pero esto es menos texto y contesta a la pregunta

Dejar respuesta

Please enter your comment!
Please enter your name here