no se puede quitar la cola de una celda con el identificador Celda: debe registrar una plumilla o una clase para el identificador o conectar una celda prototipo en un guión gráfico


114

Soy bastante nuevo en la codificación en general y realmente nuevo en Xcode (Swift). Entiendo que necesito registrar un plumín o una clase pero no entiendo '¿dónde o cómo?'.

import UIKit

class NotesListViewController: UITableViewController {

    @IBOutlet weak var menuButton: UIBarButtonItem!

  override func viewDidLoad() {
    super.viewDidLoad()
    NSNotificationCenter.defaultCenter().addObserver(self,
      selector: "preferredContentSizeChanged:",
      name: UIContentSizeCategoryDidChangeNotification,
      object: nil)

    // Side Menu

    if self.revealViewController() != nil {
        menuButton.target = self.revealViewController()
        menuButton.action = "revealToggle:"
        self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
    }

  }

  override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)
    // whenever this view controller appears, reload the table. This allows it to reflect any changes
    // made whilst editing notes
    tableView.reloadData()
  }

  func preferredContentSizeChanged(notification: NSNotification) {
    tableView.reloadData()
  }

  // #pragma mark - Table view data source

  override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
  }

  override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return notes.count
  }

  override func tableView(tableView: UITableView, cellForRowAtIndexPath   indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell

    let note = notes[indexPath.row]
    let font = UIFont.preferredFontForTextStyle(UIFontTextStyleHeadline)
    let textColor = UIColor(red: 0.175, green: 0.458, blue: 0.831, alpha: 1)
    let attributes = [
      NSForegroundColorAttributeName : textColor,
      NSFontAttributeName : font,
      NSTextEffectAttributeName : NSTextEffectLetterpressStyle
    ]
    let attributedString = NSAttributedString(string: note.title, attributes: attributes)

    cell.textLabel?.font = UIFont.preferredFontForTextStyle(UIFontTextStyleHeadline)

    cell.textLabel?.attributedText = attributedString

    return cell
  }

  let label: UILabel = {
    let temporaryLabel = UILabel(frame: CGRect(x: 0, y: 0, width: Int.max, height: Int.max))
    temporaryLabel.text = "test"
    return temporaryLabel
    }()

  override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    label.font = UIFont.preferredFontForTextStyle(UIFontTextStyleHeadline)
    label.sizeToFit()
    return label.frame.height * 1.7
  }

  override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
    if editingStyle == .Delete {
      notes.removeAtIndex(indexPath.row)
      tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
    }
  }

  // #pragma mark - Navigation

  // In a storyboard-based application, you will often want to do a little preparation before navigation
  override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
    if let editorVC = segue.destinationViewController as? NoteEditorViewController {

      if "CellSelected" == segue.identifier {
        if let path = tableView.indexPathForSelectedRow() {
          editorVC.note = notes[path.row]
        }
      } else if "AddNewNote" == segue.identifier {
        let note = Note(text: " ")
        editorVC.note = note
        notes.append(note)
      }
    }
  }

}

11
Tenga cuidado con el confuso "ID de restauración", ¡que no es nada! Haga clic en la CUARTA pestaña en la parte superior derecha, ¡NO en la TERCERA pestaña!
Fattie

Respuestas:


82

¿Ha configurado el identificador de celda de tabla en "celda" en su guión gráfico?

¿O ha configurado la clase para UITableViewControllersu clase en esa escena?


102

Puedes registrar una clase para tu UITableViewCellasí:

Con Swift 3+:

self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")

Con Swift 2.2:

self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")

Asegúrese de que el mismo identificador " cell" también se copie en su guión gráfico UITableViewCell.

" self" es para que la clase use el nombre de clase seguido de .self.


1
¿Dónde pones esto?
RJB

7
en viewDidLoad()
Mette

18
Si está utilizando un xib en su celda personalizada, tendrá que registrarlo así:tableView.register(UINib.init(nibName: "CustomCell", bundle: nil), forCellReuseIdentifier: "CustomCellIdentifier")
atulkhatri

la solución Swift 3+ anterior funcionó para mí en Swift 5
Mike Volmar

38

Esto funcionó para mí, puede ayudarte también:

Swift 4+:

self.tableView.register(UITableViewCell.self, forCellWithReuseIdentifier: "cell")

Swift 3 :

self.tableView.register(UITableViewCell.classForKeyedArchiver(), forCellReuseIdentifier: "Cell")

Swift 2.2 :

self.tableView.registerClass(UITableViewCell.classForKeyedArchiver(), forCellReuseIdentifier: "Cell")

Tenemos que establecer la propiedad del identificador en la celda de vista de tabla según la imagen de abajo,

ingrese la descripción de la imagen aquí


1
Tan simple :-)
Luc-Olivier

1
¡funcionó! Estaba configurando la identificación en el inspector de identidad, pero pegarla en el inspector de atributos funcionó para mí
Fato

1
¡Dios te bendiga! Salvé un par de mi vida
Ragen Dazs

26

Hoy tuve este problema que se resolvió seleccionando Producto -> Limpiar. Estaba tan confundido porque mi código era correcto. El problema comenzó por usar command-Z demasiadas veces :)


1
En serio, pasó más de una hora tratando de depurar esto. Gracias :)
despertó el

Por supuesto, funciona en combinación con la definición del identificador en el guión gráfico (consulte la siguiente respuesta)
Nech

21

En mi caso, resolví esto nombrándolo en la propiedad "Identificador" de la celda de vista de tabla:

ingrese la descripción de la imagen aquí

No olvide: declarar en su clase: UITableViewDataSource

 let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as UITableViewCell

esta imagen no coincide, pero dio alguna pista.
Martian2049

es un poco anticuado solo
Martian2049

13

Simplemente arrastre una celda (como lo hizo para TableViewController) y agréguela simplemente liberando la celda en TableViewController. Haga clic en la celda y vaya a su inspector de atributos y establezca su identificador como "Celda". Espero que funcione.


No olvide que quiere un identificador en el inspector de atributos .

NO el "ID de restauración" en el "Inspector de identidad"!)


6
Tenga cuidado con el confuso "ID de restauración", ¡que no es nada! Haga clic en la CUARTA pestaña en la parte superior derecha, NO en la TERCERA pestaña !!!
Fattie

9

Una razón más para que ocurra este problema es un problema anterior. Al mostrar un nuevo ViewController, la instanciación del ViewController de destino directamente, por supuesto, no cargará las celdas prototipo del StoryBoard. La solución correcta siempre debe ser crear una instancia del controlador de vista a través del guión gráfico como este:

storyboard?.instantiateViewController(withIdentifier: "some_identifier")

¡¡Si!! ¡¡Es verdad!! Esto me sucedió porque hice la transición al ViewController que se encuentra en un Storyboard diferente solo con: self.present (MyViewController, animado: falso, finalización: nulo). ¡Y parece que realmente no descarga el prototipo! ¡Intenté comenzar con MyViewController directamente y funciona bien! También funciona cuando estoy registrando NIB para mi celda en viewDidLoad de ViewController de destino.
Vitya Shurapov

7

Haga coincidir el nombre del identificador en ambos lugares

Este error ocurre cuando el nombre del identificador de Tablecell es diferente en el archivo Swift y The Storyboard.

Por ejemplo, el identificador es placecellIdentifier en mi caso.

1) El archivo Swift

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "placecellIdentifier", for: indexPath)

    // Your code 

    return cell
}

2) El guión gráfico

ingrese la descripción de la imagen aquí


5

En Swift 3.0, registre una clase para su UITableViewCell como esta:

tableView.register(UINib(nibName: "YourCellXibName", bundle: nil), forCellReuseIdentifier: "Cell")

2

Yo tuve el mismo problema. Este problema funcionó para mí. En el guión gráfico, seleccione la vista de su tabla y cámbiela de celdas estáticas a celdas dinámicas.


2

Si definió su celda a través de Interface Builder, colocando una celda dentro de su UICollectionView, o UITableView:

Asegúrate de vincular la celda con una clase real que creaste y, muy importante, de haber marcado "Heredar módulo del destino".


2

Solía ​​funcionar en swift 3 y swift 4, pero ahora no funciona.

me gusta

self.tableView.register(MyTestTableViewCell.self, forCellReuseIdentifier: "cell")

Así que probé la mayoría de las soluciones mencionadas anteriormente en Swift 5 pero no tuve suerte.

Finalmente probé esta solución y funcionó para mí.

override func viewDidLoad() 
{

    tableView.register(UINib.init(nibName: "MyTestTableViewCell", bundle: nil), forCellReuseIdentifier: "myTestTableViewCell")
}

2

Mi problema era que estaba registrando la celda de vista de tabla dentro de la cola de despacho de forma asincrónica. Si ha registrado el origen de la vista de tabla y la referencia delegada en el guión gráfico, la cola de envío retrasaría el registro de la celda, ya que el nombre sugiere que sucederá de forma asincrónica y su vista de tabla está buscando las celdas.

DispatchQueue.main.async {
    self.tableView.register(CampaignTableViewCell.self, forCellReuseIdentifier: CampaignTableViewCell.identifier())
    self.tableView.reloadData()
}

O no debe usar la cola de envío para el registro O haga esto:

DispatchQueue.main.async {
    self.tableView.dataSource = self
    self.tableView.delegate = self
    self.tableView.register(CampaignTableViewCell.self, forCellReuseIdentifier: CampaignTableViewCell.identifier())
    self.tableView.reloadData()
}

1

Me acabo de encontrar con el mismo problema y veo esta publicación. Para mí, es porque olvidé establecer el identificador de la celda, también como se menciona en otras respuestas. Lo que quiero decir es que si está utilizando el guión gráfico para cargar una celda personalizada, no es necesario que registre la celda de la vista de tabla en el código, lo que puede causar otros problemas.

Vea esta publicación para más detalles:

Celda de vista de tabla personalizada: la etiqueta IBOutlet es nula


0

Solo para aquellos nuevos amigos de iOS (como yo) que decidieron tener varias celdas y en un archivo xib diferente, la solución no es tener un identificador, sino hacer esto:

let cell = Bundle.main.loadNibNamed("newsDetails", owner: self, options: nil)?.first as! newsDetailsTableViewCell

aquí newsDetails es el nombre del archivo xib.


0

Rápido 5

necesita usar el método UINib para registrar la celda en viewDidLoad

override func viewDidLoad() 
{
    super.viewDidLoad()
    // Do any additional setup after loading the view.

    //register table view cell        
    tableView.register(UINib.init(nibName: "CustomTableViewCell", bundle: nil), forCellReuseIdentifier: "CustomTableViewCell")
}

0

En el campo "Subclase de", seleccione UITableViewController.

El título de la clase cambia a xxxxTableViewController. Déjalo como está.

Asegúrese de que la opción "Crear también archivo XIB" esté seleccionada.


0

Me encontré con este mensaje cuando UITableView en el IB se movió a otra subvista con Cmd-C - Cmd-V.

Todos los identificadores, métodos delegados, enlaces en el IB, etc. permanecen intactos, pero se genera una excepción en el tiempo de ejecución.

La única solución es borrar todas las tintas relacionadas con la vista de tabla en el IB (salida, fuente de datos, delegado) y volver a crearlas.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.