impossibile rimuovere dalla coda una cella con identificatore Cella: è necessario registrare un pennino o una classe per l'identificatore o collegare una cella prototipo in uno storyboard


114

Sono abbastanza nuovo nella codifica in generale e davvero nuovo in Xcode (Swift). Capisco che devo registrare un pennino o una classe ma non capisco "dove o come?".

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
Fai attenzione al confuso "ID restauro" - che non è niente! Fare clic sulla QUARTA scheda in alto a destra, NON sulla TERZA scheda !!
Fattie

Risposte:


82

Hai impostato l' identificatore della cella della tabella su "Cella" nel tuo storyboard?

O hai impostato la classe per la UITableViewControllertua classe in quella scena?


102

Puoi registrare un corso per il tuo UITableViewCellcome questo:

Con Swift 3+:

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

Con Swift 2.2:

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

Assicurati che lo stesso identificatore " cell" sia copiato anche nello storyboard UITableViewCell.

" self" serve per far sì che la classe utilizzi il nome della classe seguito da .self.


1
Dove lo metti?
RJB

7
a viewDidLoad()
Mette

18
Se stai usando un xib nella tua cella personalizzata, dovrai registrarlo in questo modo:tableView.register(UINib.init(nibName: "CustomCell", bundle: nil), forCellReuseIdentifier: "CustomCellIdentifier")
atulkhatri

la soluzione rapida 3+ sopra ha funzionato per me in swift 5
Mike Volmar

38

Questo ha funzionato per me, può aiutare anche te:

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

Dobbiamo impostare la proprietà Identifier su Table View Cell come da immagine sotto,

inserisci qui la descrizione dell'immagine


1
Semplicemente così semplice :-)
Luc-Olivier

1
ha funzionato! Stavo impostando l'ID nell'ispettore di identità, ma incollarlo nell'ispettore degli attributi ha funzionato per me
Fato

1
Dio ti benedica! Mi ha salvato un paio della vita
Ragen Dazs il

26

Oggi ho riscontrato questo problema che è stato risolto selezionando Prodotto -> Pulisci. Ero così confuso poiché il mio codice era corretto. Il problema è iniziato usando il comando-Z troppe volte :)


1
Seriamente ho trascorso più di un'ora cercando di eseguire il debug di questo. Grazie :)
risvegliato il

Ovviamente funziona in combinazione con la definizione dell'identificatore nello storyboard (vedi risposta successiva)
Nech

21

Nel mio caso ho risolto questo problema nominandolo nella proprietà "Identifier" di Table View Cell:

inserisci qui la descrizione dell'immagine

Non dimenticare: per dichiarare nella tua classe: UITableViewDataSource

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

questa immagine non corrisponde ma ha dato qualche suggerimento.
Martian 2049

è un po 'datato solo
Martian2049

13

Basta trascinare una cella (come hai fatto per TableViewController) e aggiungerla semplicemente rilasciando la cella su TableViewController. Fare clic sulla cella e. Vai al suo ispettore attributi e impostare il suo identificatore come "Cella". Spero che funzioni.


Non dimenticare che vuoi Identifier nell'ispettore degli attributi .

( NON l '"ID restauro" su "Ispettore identità"!)


6
Fai attenzione al confuso "ID restauro" - che non è niente! Fare clic sulla QUARTA scheda in alto a destra, NON sulla TERZA scheda !!!
Fattie

9

Un altro motivo per cui questo problema si verifica è un problema precedente. Quando si mostra un nuovo ViewController, istanziare direttamente il ViewController di destinazione ovviamente non caricherà le celle del prototipo dallo StoryBoard. La soluzione corretta dovrebbe sempre essere quella di istanziare il controller di visualizzazione attraverso lo storyboard in questo modo:

storyboard?.instantiateViewController(withIdentifier: "some_identifier")

Sì!! È vero!! Questo è successo a me perché sono passato al ViewController che si trova in uno Storyboard diverso solo con: self.present (MyViewController, animated: false, completamento: nil). E sembra che non scarichi davvero il prototipo! Ho provato a iniziare direttamente con MyViewController e funziona bene! Funziona anche quando registro NIB per la mia cella in viewDidLoad del ViewController di destinazione.
Vitya Shurapov

7

Abbina il nome dell'identificatore in entrambi i punti

Questo errore si verifica quando il nome dell'identificatore del Tablecell è diverso nel file Swift e nello Storyboard.

Ad esempio, l'identificatore è placecellIdentifier nel mio caso.

1) Il file Swift

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

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

    // Your code 

    return cell
}

2) Lo Storyboard

inserisci qui la descrizione dell'immagine


5

In Swift 3.0, registra una classe per UITableViewCell come questa:

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

2

Ho avuto lo stesso problema. Questo problema ha funzionato per me. Nello storyboard seleziona la visualizzazione della tabella e modificala da celle statiche a celle dinamiche.


2

Se hai definito la tua cella tramite Interface Builder, inserendo una cella all'interno del tuo UICollectionView, o UITableView:

Assicurati di aver associato la cella a una classe effettiva che hai creato e, molto importante, di aver selezionato "Eredita modulo dalla destinazione"


2

Prima funzionava su swift 3 e swift 4 ma ora non funziona.

piace

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

Quindi ho provato la maggior parte delle soluzioni sopra menzionate in swift 5 ma non ho avuto fortuna.

Alla fine ho provato questa soluzione e ha funzionato per me.

override func viewDidLoad() 
{

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

2

Il mio problema era che stavo registrando la cella di visualizzazione della tabella all'interno della coda di invio in modo asincrono. Se hai registrato l'origine della vista tabella e il riferimento del delegato nello storyboard, la coda di invio ritarderebbe la registrazione della cella poiché il nome suggerisce che avverrà in modo asincrono e la tua vista tabella sta cercando le celle.

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

O non dovresti usare la coda di invio per la registrazione OPPURE fai questo:

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

1

Ho appena incontrato lo stesso problema e vedo questo post. Per me è perché ho dimenticato di impostare l'identificatore di cella, anche come detto in altre risposte. Quello che voglio dire è che se stai usando lo storyboard per caricare la cella personalizzata non abbiamo bisogno di registrare la cella della vista tabella nel codice, il che può causare altri problemi.

Vedi questo post per i dettagli:

Cella di visualizzazione tabella personalizzata: l'etichetta IBOutlet è nulla


0

Solo per i nuovi amici di iOS (come me) che hanno deciso di avere più celle e in un file xib diverso, la soluzione non è avere un identificatore ma fare questo:

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

qui newsDetails è il nome del file xib .


0

Swift 5

è necessario utilizzare il metodo UINib per registrare la cella in 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

Nel campo "Sottoclasse di", seleziona UITableViewController.

Il titolo della classe cambia in xxxxTableViewController. Lascialo così com'è.

Assicurati che l'opzione "Crea anche file XIB" sia selezionata.


0

Mi sono imbattuto in questo messaggio quando UITableView nell'IB è stato spostato in un'altra sottoview con Cmd-C - Cmd-V.

Tutti gli identificatori, i metodi delegati, i collegamenti nell'IB ecc. Rimangono intatti, ma viene sollevata un'eccezione in fase di esecuzione.

L'unica soluzione è cancellare tutti gli inchiostri, relativi a tableview nell'IB (outlet, datasource, delegate) e rifarli.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.