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)
      }
    }
  }

}
ShizukaNaHaji
fuente
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?

Carrera B
fuente
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.

Aks
fuente
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í

Jaywant Khedkar
fuente
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 :)

MacInnis
fuente
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
xhinoda
fuente
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"!)

Anish Parajuli 웃
fuente
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")
Peter Honeder
fuente
¡¡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í

Rohit Singh
fuente
5

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

tableView.register(UINib(nibName: "YourCellXibName", bundle: nil), forCellReuseIdentifier: "Cell")
Ak_ninan
fuente
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.

Reza Dehnavi
fuente
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".

Scaraux
fuente
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")
}
abdominales
fuente
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()
}
Noor ali a tope
fuente
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

María Chen
fuente
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.

androCoder-BD
fuente
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")
}
SwiftBoy
fuente
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.

Kai Lean
fuente
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.

Vladimir Vodolazkiy
fuente