nie można usunąć z kolejki komórki z identyfikatorem Komórka - musi zarejestrować stalówkę lub klasę dla identyfikatora lub podłączyć prototypową komórkę w scenorysie

114

Jestem całkiem nowy w kodowaniu w ogóle i naprawdę nowy w Xcode (Swift). Rozumiem, że muszę zarejestrować stalówkę lub klasę, ale nie rozumiem „gdzie i jak?”.

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
źródło
11
Uważaj na mylący „identyfikator przywrócenia” - to nic! Kliknij CZWARTĄ zakładkę w prawym górnym rogu, NIE TRZECI zakładkę !!
Fattie

Odpowiedzi:

82

Czy w swoim storyboardzie ustawiłeś identyfikator komórki tabeli na „Komórka”?

A może ustawiłeś klasę dla UITableViewControllerswojej klasy w tej scenie?

Wyścig B
źródło
102

Możesz zarejestrować taką klasę UITableViewCell:

Z Swift 3+:

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

Z Swift 2.2:

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

Upewnij się, że ten sam identyfikator „ cell” jest również kopiowany w Twojej scenorysie UITableViewCell.

self” służy do uzyskania klasy, używając nazwy klasy, po której następuje .self.

Aks
źródło
1
Gdzie to położyłeś?
RJB
7
w viewDidLoad()
Mette
18
Jeśli używasz xib w swojej komórce niestandardowej, będziesz musiał zarejestrować go w następujący sposób:tableView.register(UINib.init(nibName: "CustomCell", bundle: nil), forCellReuseIdentifier: "CustomCellIdentifier")
atulkhatri
szybkie rozwiązanie 3+ powyżej działało dla mnie w Swift 5
Mike Volmar
38

To zadziałało dla mnie, może ci też pomóc:

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

Musimy ustawić właściwość Identyfikatora na komórkę widoku tabeli, jak na poniższym obrazku,

wprowadź opis obrazu tutaj

Jaywant Khedkar
źródło
1
Po prostu takie proste :-)
Luc-Olivier
1
zadziałało! Ustawiałem identyfikator w inspektorze tożsamości, ale wklejenie go w inspektorze atrybutów zadziałało
Fato
1
Niech cię Bóg błogosławi! Uratowałem parę z mojego życia
Ragen Dazs
26

Miałem dzisiaj ten problem, który został rozwiązany, wybierając Produkt -> Wyczyść. Byłem tak zdezorientowany, ponieważ mój kod był poprawny. Problem zaczął się od zbyt częstego użycia polecenia-Z :)

MacInnis
źródło
1
Poważnie spędziłem ponad godzinę, próbując to debugować. Dziękuję :)
ewakened
Oczywiście działa to w połączeniu ze zdefiniowaniem identyfikatora w storyboardzie (patrz następna odpowiedź)
Nech
21

y mój przypadek rozwiązałem, nazywając go we właściwości „Identyfikator” komórki widoku tabeli:

wprowadź opis obrazu tutaj

Nie zapomnij: zadeklarować w swojej klasie: UITableViewDataSource

 let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as UITableViewCell
xhinoda
źródło
ten obraz nie pasuje, ale dał pewną wskazówkę.
Martian2049
jest trochę przestarzały
Martian2049
13

Po prostu przeciągnij komórkę (tak jak w przypadku TableViewController) i dodaj do niej po prostu zwalniając komórkę na TableViewController. Kliknij komórkę i .Przejdź do inspektora atrybutów i ustaw jej identyfikator jako „Komórka”. Mam nadzieję, że zadziała.


Nie zapomnij, że chcesz mieć identyfikator w Inspektorze atrybutów .

( NIE „Identyfikator przywrócenia” w „Inspektorze tożsamości”!)

Anish Parajuli 웃
źródło
6
Uważaj na mylący „identyfikator przywrócenia” - to nic! Kliknij CZWARTĄ zakładkę w prawym górnym rogu, NIE TRZECI zakładkę !!!
Fattie
9

Jeszcze jednym powodem wystąpienia tego problemu jest wcześniejszy problem. Podczas wyświetlania nowego ViewController bezpośrednie utworzenie instancji docelowego ViewController nie spowoduje oczywiście załadowania prototypowych komórek ze StoryBoard. Prawidłowym rozwiązaniem powinno być zawsze utworzenie instancji kontrolera widoku za pomocą tablicy scenariuszy w następujący sposób:

storyboard?.instantiateViewController(withIdentifier: "some_identifier")
Peter Honeder
źródło
Tak!! To prawda!! Zdarzyło mi się to, ponieważ przeszedłem do ViewController, który znajduje się w innym Storyboard tylko z: self.present (MyViewController, animated: false, complete: nil). I wygląda na to, że to naprawdę nie pobiera prototypu! Próbowałem uruchomić bezpośrednio z MyViewController i działa dobrze! Działa również, gdy rejestruję NIB dla mojej komórki w viewDidLoad docelowego ViewController.
Vitya Shurapov
7

Dopasuj nazwę identyfikatora w obu miejscach

Ten błąd występuje, gdy nazwa identyfikatora Tablecell jest inna w pliku Swift i The Storyboard.

Na przykład w moim przypadku identyfikator to placecellIdentifier .

1) Swift File

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

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

    // Your code 

    return cell
}

2) Storyboard

wprowadź opis obrazu tutaj

Rohit Singh
źródło
5

W Swift 3.0 zarejestruj klasę dla swojego UITableViewCell w następujący sposób:

tableView.register(UINib(nibName: "YourCellXibName", bundle: nil), forCellReuseIdentifier: "Cell")
ak_ninan
źródło
2

Miałem ten sam problem. Ten problem zadziałał dla mnie. W scenorysie wybierz widok tabeli i zmień go z komórek statycznych na komórki dynamiczne.

Reza Dehnavi
źródło
2

Jeśli zdefiniowałeś swoją komórkę za pomocą Interface Builder, umieszczając komórkę wewnątrz swojego UICollectionViewlub UITableView:

Upewnij się, że powiązałeś komórkę z faktycznie utworzoną klasą i bardzo ważne, że zaznaczyłeś „Dziedzicz moduł z celu”

Scaraux
źródło
2

Kiedyś działał na Swift 3 i Swift 4, ale teraz nie działa.

lubić

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

Wypróbowałem więc większość wyżej wymienionych rozwiązań w swift 5, ale nie udało mi się.

W końcu wypróbowałem to rozwiązanie i zadziałało.

override func viewDidLoad() 
{

    tableView.register(UINib.init(nibName: "MyTestTableViewCell", bundle: nil), forCellReuseIdentifier: "myTestTableViewCell")
}
ABS
źródło
2

Mój problem polegał na tym, że asynchronicznie rejestrowałem komórkę widoku tabeli w kolejce wysyłkowej. Jeśli zarejestrowałeś źródło widoku tabeli i odwołanie do delegowania w scenorysie, kolejka wysyłkowa opóźni rejestrację komórki, jak sugeruje nazwa, nastąpi to asynchronicznie, a widok tabeli szuka komórek.

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

Albo nie powinieneś używać kolejki wysyłki do rejestracji LUB zrób to:

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
źródło
1

Właśnie spotkałem ten sam problem i widzę ten post. U mnie to dlatego, że zapomniałem ustawionego identyfikatora komórki, również jak wspomniałem w innych odpowiedziach. Chcę powiedzieć, że jeśli używasz scenorysu do ładowania niestandardowej komórki, nie musimy rejestrować komórki widoku tabeli w kodzie, co może powodować inne problemy.

Zobacz ten post, aby uzyskać szczegółowe informacje:

Komórka niestandardowego widoku tabeli: etykieta IBOutlet jest zerowa

Maria Chen
źródło
0

Tylko dla tych nowych kumpli z iOS (takich jak ja), którzy zdecydowali się mieć wiele komórek w innym pliku xib, rozwiązaniem nie jest posiadanie identyfikatora, ale zrobienie tego:

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

tutaj newsDetails to nazwa pliku xib.

androCoder-BD
źródło
0

Szybki 5

musisz użyć metody UINib , aby zarejestrować komórkę w 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
źródło
0

W polu „Subclass of” wybierz UITableViewController.

Tytuł klasy zmieni się na xxxxTableViewController. Zostaw to tak, jak jest.

Upewnij się, że opcja „Utwórz również plik XIB” jest zaznaczona.

Kai Lean
źródło
0

Napotkałem tę wiadomość, gdy UITableView w IB został przeniesiony do innego podglądu z Cmd-C - Cmd-V.

Wszystkie identyfikatory, metody delegatów, łącza w IB itp. Pozostają nienaruszone, ale wyjątek jest zgłaszany w czasie wykonywania.

Jedynym rozwiązaniem jest wyczyszczenie wszystkich atramentów związanych z widokiem tabeli w IB (outlet, źródło danych, delegat) i ponowne ich wykonanie.

Vladimir Vodolazkiy
źródło