невозможно исключить ячейку с идентификатором Cell - необходимо зарегистрировать перо или класс для идентификатора или подключить ячейку прототипа в раскадровке


114

Я новичок в кодировании в целом и действительно новичок в Xcode (Swift). Я понимаю, что мне нужно зарегистрировать перо или класс, но не понимаю, «где и как?».

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
Остерегайтесь сбивающего с толку «Restoration ID» - ничего страшного! Щелкните на ЧЕТВЕРТОЙ вкладке вверху справа, а НЕ на ТРЕТЬЕЙ вкладке !!
Fattie

Ответы:


82

Вы установили для идентификатора ячейки таблицы значение «Ячейка» в раскадровке?

Или вы установили класс для UITableViewControllerсвоего класса в этой сцене?


103

Вы можете зарегистрировать свой класс UITableViewCellвот так:

В Swift 3+:

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

В Swift 2.2:

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

Убедитесь, что тот же идентификатор " cell" также скопирован в вашу раскадровку UITableViewCell.

" self" используется для того, чтобы класс использовал имя класса, за которым следует .self.


1
Куда вы это положили?
RJB

7
in viewDidLoad()
Метте

18
Если вы используете xib в своей пользовательской ячейке, вам нужно будет зарегистрировать его следующим образом:tableView.register(UINib.init(nibName: "CustomCell", bundle: nil), forCellReuseIdentifier: "CustomCellIdentifier")
atulkhatri

быстрое решение 3+ выше сработало для меня в быстром 5
Майк Волмар

39

Это сработало для меня, может вам тоже помочь:

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

Мы должны установить свойство идентификатора в ячейку представления таблицы, как показано на рисунке ниже,

введите описание изображения здесь


1
Просто так :-)
Люк-Оливье

1
это сработало! Я устанавливал идентификатор в инспекторе идентичности, но вставка его в инспектор атрибутов у меня
сработала

1
Будьте здоровы! Спас пару на моей жизни
Раген Дазс

26

У меня была эта проблема сегодня, которую решили, выбрав Продукт -> Очистить. Я был так сбит с толку, потому что мой код был правильным. Проблема началась из-за слишком частого использования command-Z :)


1
Серьезно потратил больше часа, пытаясь отладить это. Спасибо :)
проснулся

Конечно , это работает в сочетании с определением идентификатора в раскадровке (смотрите следующий ответ)
Нех

21

В моем случае я решил это, назвав его в свойстве «Идентификатор» ячейки представления таблицы:

введите описание изображения здесь

Не забыл: объявить в своем классе: UITableViewDataSource

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

это изображение не совпадает, но дает некоторый намек.
Martian2049

это немного устаревшее просто
Martian2049

13

Просто перетащите ячейку (как вы это делали для TableViewController) и добавьте в нее, просто отпустив ячейку в TableViewController. Нажмите на ячейку и. Перейдите в ее инспектор атрибутов и установите ее идентификатор как «Ячейка». Надеюсь, это сработает.


Не забывайте, что вам нужен идентификатор в инспекторе атрибутов .

( НЕ «ИД восстановления» в «Инспекторе удостоверений»!)


6
Остерегайтесь сбивающего с толку «Restoration ID» - ничего страшного! Щелкните по ЧЕТВЕРТОЙ вкладке вверху справа, а НЕ ТРЕТЬЕЙ вкладке !!!
Fattie

9

Еще одна причина возникновения этой проблемы - более ранняя проблема. При отображении нового ViewController создание экземпляра целевого ViewController напрямую, конечно, не будет загружать ячейки прототипа из StoryBoard. Правильным решением всегда должно быть создание экземпляра контроллера представления через раскадровку следующим образом:

storyboard?.instantiateViewController(withIdentifier: "some_identifier")

Да!! Это так!! Это случилось со мной, потому что я перешел на ViewController, который находится в другой раскадровке, только с помощью: self.present (MyViewController, animated: false, completion: nil). И, похоже, действительно не скачивает прототип! Я попытался начать с MyViewController напрямую, и он работает правильно! Это также работает, когда я регистрирую NIB для своей ячейки в viewDidLoad целевого ViewController.
Витя Шурапов

7

Сопоставьте имя идентификатора в обоих местах

Эта ошибка возникает, когда имя идентификатора Tablecell отличается в файле Swift и Storyboard.

Например, идентификатор - placecellIdentifier. в моем случае .

1) Быстрый файл

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

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

    // Your code 

    return cell
}

2) Раскадровка

введите описание изображения здесь


5

В Swift 3.0 зарегистрируйте класс для UITableViewCell следующим образом:

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

2

У меня такая же проблема. Эта проблема сработала для меня. В раскадровке выберите вид таблицы и измените его со статических ячеек на динамические.


2

Если вы определили свою ячейку через Interface Builder, поместив ячейку внутри себя UICollectionView, или UITableView:

Убедитесь, что вы связали ячейку с фактическим созданным вами классом, и, что очень важно, вы отметили «Наследовать модуль от цели»


2

Раньше он работал на Swift 3 и Swift 4, но теперь не работает.

лайк

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

Итак, я попробовал большинство решений, упомянутых выше, в Swift 5, но мне не повезло.

Наконец я попробовал это решение, и оно сработало для меня.

override func viewDidLoad() 
{

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

2

Моя проблема заключалась в том, что я асинхронно регистрировал ячейку представления таблицы внутри очереди отправки. Если вы зарегистрировали источник табличного представления и делегировали ссылку в раскадровке, то очередь отправки задержит регистрацию ячейки, поскольку имя предполагает, что это произойдет асинхронно, и ваше табличное представление ищет ячейки.

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

Либо вы не должны использовать очередь отправки для регистрации, либо сделайте это:

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

1

Я только что столкнулся с той же проблемой и увидел этот пост. Для меня это потому, что я забыл установить идентификатор ячейки, как упоминалось в других ответах. Я хочу сказать, что если вы используете раскадровку для загрузки пользовательской ячейки, нам не нужно регистрировать ячейку табличного представления в коде, что может вызвать другие проблемы.

Подробности смотрите в этом посте:

Пользовательская ячейка представления таблицы: метка IBOutlet равна нулю


0

Только для тех, кто плохо знаком с iOS (вроде меня), которые решили иметь несколько ячеек и в другом файле xib, решение состоит не в том, чтобы иметь идентификатор, а в следующем:

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

здесь newsDetails - это имя файла xib.


0

Swift 5

вам нужно использовать метод UINib для регистрации ячейки в 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

В поле «Подкласс из» выберите UITableViewController.

Название класса изменится на xxxxTableViewController. Оставьте все как есть.

Убедитесь, что выбрана опция «Также создать файл XIB».


0

Я столкнулся с этим сообщением, когда UITableView в IB был перемещен в другое подпредставление с помощью Cmd-C - Cmd-V.

Все идентификаторы, методы делегатов, ссылки в IB и т. Д. Остаются неизменными, но во время выполнения возникает исключение.

Единственное решение - очистить все чернила, связанные с табличным представлением в IB (выход, источник данных, делегат), и сделать их снова.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.