Zelle mit Bezeichner kann nicht aus der Warteschlange entfernt werden Zelle - muss eine Schreibfeder oder eine Klasse für den Bezeichner registrieren oder eine Prototypzelle in einem Storyboard verbinden

113

Ich bin ziemlich neu im Codieren im Allgemeinen und wirklich neu im Xcode (Swift). Ich verstehe, dass ich eine Feder oder eine Klasse registrieren muss, aber ich verstehe nicht, wo oder wie?

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
quelle
11
Achten Sie auf die verwirrende "Restoration ID" - das ist nichts! Klicken Sie oben rechts auf die VIERTE Registerkarte, NICHT auf die DRITTE Registerkarte !!
Fattie

Antworten:

81

Haben Sie in Ihrem Storyboard die Tabellenzellen-ID auf "Zelle" gesetzt?

Oder haben Sie die Klasse für UITableViewControllerIhre Klasse in dieser Szene festgelegt?

Rennen B.
quelle
102

Sie können eine Klasse für UITableViewCelldiese wie folgt anmelden :

Mit Swift 3+:

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

Mit Swift 2.2:

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

Stellen Sie sicher, dass dieselbe Kennung " cell" auch in Ihr Storyboard kopiert wird UITableViewCell.

" self" dient dazu, dass die Klasse den Klassennamen gefolgt von verwendet .self.

Aks
quelle
1
Wo legst du das hin?
RJB
7
in viewDidLoad()
Mette
18
Wenn Sie ein xib in Ihrer benutzerdefinierten Zelle verwenden, müssen Sie es wie tableView.register(UINib.init(nibName: "CustomCell", bundle: nil), forCellReuseIdentifier: "CustomCellIdentifier")
folgt
Die schnelle 3+ Lösung oben funktionierte für mich in Swift 5
Mike Volmar
38

Das hat bei mir funktioniert, kann dir auch helfen:

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

Wir müssen die Identifier- Eigenschaft gemäß dem folgenden Bild auf Table View Cell setzen.

Geben Sie hier die Bildbeschreibung ein

Jaywant Khedkar
quelle
1
Einfach so einfach :-)
Luc-Olivier
1
es funktionierte! Ich habe die ID im Identitätsinspektor festgelegt, aber das Einfügen in den Attributinspektor hat für mich funktioniert
Fato
1
Gott segne dich! Ein paar meines Lebens gerettet
Ragen Dazs
26

Ich hatte heute dieses Problem, das durch Auswahl von Produkt -> Reinigen behoben wurde. Ich war so verwirrt, da mein Code korrekt war. Das Problem begann damit, Befehl-Z zu oft zu verwenden :)

MacInnis
quelle
1
Ernsthaft über eine Stunde damit verbracht, dies zu debuggen. Vielen Dank :)
ewakened
Natürlich funktioniert es in Kombination mit der Definition der Kennung im Storyboard (siehe nächste Antwort)
Nech
21

In meinem Fall habe ich dieses Problem gelöst, indem ich es in der Eigenschaft "Identifier" von Table View Cell benannt habe:

Geben Sie hier die Bildbeschreibung ein

Vergessen Sie nicht: in Ihrer Klasse zu deklarieren: UITableViewDataSource

 let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as UITableViewCell
Xhinoda
quelle
Dieses Bild stimmt nicht überein, aber es gab einen Hinweis.
Martian2049
es ist ein wenig veraltet nur
Martian2049
13

Ziehen Sie einfach eine Zelle (wie bei TableViewController) und fügen Sie sie hinzu, indem Sie die Zelle in TableViewController freigeben. Klicken Sie auf die Zelle und gehen Sie zu ihrem Attributinspektor und setzen Sie ihre Kennung als "Zelle". Hoffentlich funktioniert es.


Vergessen Sie nicht, dass Sie eine Kennung im Attributinspektor haben möchten .

( NICHT die "Wiederherstellungs-ID" im "Identity Inspector"!)

Anish Parajuli 웃
quelle
6
Achten Sie auf die verwirrende "Restoration ID" - das ist nichts! Klicken Sie oben rechts auf die VIERTE Registerkarte, NICHT auf die DRITTE Registerkarte !!!
Fattie
9

Ein weiterer Grund für dieses Problem ist ein früheres Problem. Wenn Sie einen neuen ViewController anzeigen und den ViewController direkt instanziieren, werden die Prototypzellen natürlich nicht aus dem StoryBoard geladen. Die richtige Lösung sollte immer darin bestehen, den View Controller wie folgt über das Storyboard zu instanziieren:

storyboard?.instantiateViewController(withIdentifier: "some_identifier")
Peter Honeder
quelle
Ja!! Es ist wahr!! Dies ist mir passiert, weil ich auf den ViewController umgestiegen bin, der sich in einem anderen Storyboard befindet, nur mit: self.present (MyViewController, animiert: false, Vervollständigung: nil). Und es sieht so aus, als würde der Prototyp wirklich nicht heruntergeladen! Ich habe versucht, direkt mit MyViewController zu beginnen, und es funktioniert richtig! Dies funktioniert auch, wenn ich NIB für meine Zelle in viewDidLoad des Ziel-ViewControllers registriere.
Vitya Shurapov
7

Passen Sie den Bezeichnernamen an beiden Stellen an

Dieser Fehler tritt auf, wenn sich der Bezeichnername der Tabellenzelle in der Swift-Datei und im Storyboard unterscheidet.

Zum Beispiel ist der Bezeichner in meinem Fall placecellIdentifier .

1) Die Swift-Datei

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

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

    // Your code 

    return cell
}

2) Das Storyboard

Geben Sie hier die Bildbeschreibung ein

Rohit Singh
quelle
5

Registrieren Sie in Swift 3.0 eine Klasse für Ihre UITableViewCell wie folgt:

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

Ich hatte das gleiche Problem. Dieses Problem hat bei mir funktioniert. Wählen Sie im Storyboard Ihre Tabellenansicht aus und ändern Sie sie von statischen Zellen in dynamische Zellen.

Reza Dehnavi
quelle
2

Wenn Sie Ihre Zelle über den Interface Builder definiert haben, platzieren Sie eine Zelle in Ihrer UICollectionViewoder UITableView:

Stellen Sie sicher, dass Sie die Zelle mit einer von Ihnen erstellten Klasse verbunden haben, und sehr wichtig, dass Sie "Modul vom Ziel erben" aktiviert haben.

Scaraux
quelle
2

Früher arbeitete es mit Swift 3 und Swift 4, aber jetzt funktioniert es nicht mehr.

mögen

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

Also habe ich die meisten der oben genannten Lösungen in Swift 5 ausprobiert, aber kein Glück bekommen.

Schließlich habe ich diese Lösung ausprobiert und es hat bei mir funktioniert.

override func viewDidLoad() 
{

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

Mein Problem war, dass ich die Tabellenansichtszelle asynchron in der Versandwarteschlange registrierte. Wenn Sie die Quelle der Tabellenansicht registriert und die Referenz im Storyboard delegiert haben, verzögert die Versandwarteschlange die Registrierung der Zelle, da der Name dies asynchron andeutet und Ihre Tabellenansicht nach den Zellen sucht.

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

Entweder sollten Sie die Versandwarteschlange nicht für die Registrierung verwenden, ODER Sie tun dies:

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

Ich habe gerade das gleiche Problem getroffen und sehe diesen Beitrag. Für mich liegt es daran, dass ich vergessen habe, die Kennung der Zelle festzulegen, auch wie in anderen Antworten erwähnt. Was ich sagen möchte ist, dass wenn Sie das Storyboard zum Laden einer benutzerdefinierten Zelle verwenden, wir die Zelle der Tabellenansicht nicht im Code registrieren müssen, was andere Probleme verursachen kann.

Siehe diesen Beitrag für Details:

Benutzerdefinierte Tabellenansichtszelle: IBOutlet-Label ist Null

Maria Chen
quelle
0

Nur für diejenigen, die neu bei iOS-Freunden sind (wie ich), die sich für mehrere Zellen und eine andere xib-Datei entschieden haben, besteht die Lösung nicht darin, eine Kennung zu haben, sondern dies zu tun:

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

hier News ist xib Dateinamen.

androCoder-BD
quelle
0

Swift 5

Sie müssen die UINib- Methode verwenden, um die Zelle in viewDidLoad zu registrieren

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
quelle
0

Wählen Sie im Feld "Unterklasse von" die Option UITableViewController aus.

Der Klassentitel ändert sich in xxxxTableViewController. Lass das so wie es ist.

Stellen Sie sicher, dass die Option "Auch XIB-Datei erstellen" ausgewählt ist.

Kai Lean
quelle
0

Ich bin auf diese Nachricht gestoßen, als UITableView im IB mit Cmd-C - Cmd-V in eine andere Unteransicht verschoben wurde.

Alle Bezeichner, Delegierungsmethoden, Links im IB usw. bleiben erhalten, aber zur Laufzeit wird eine Ausnahme ausgelöst.

Die einzige Lösung besteht darin, alle Tinten, die sich auf die Tabellenansicht im IB beziehen (Outlet, Datenquelle, Delegat), zu löschen und erneut zu erstellen.

Vladimir Vodolazkiy
quelle