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

}

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?


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.


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


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


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

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”!)


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

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


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

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.


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”


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

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

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


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.


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

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.


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.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.