ไม่สามารถถอดคิวเซลล์ที่มีตัวระบุเซลล์ - ต้องลงทะเบียนปลายปากกาหรือคลาสสำหรับตัวระบุหรือเชื่อมต่อเซลล์ต้นแบบในสตอรีบอร์ด


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
ระวัง "รหัสการกู้คืน" ที่สับสน - ซึ่งไม่มีอะไร! คลิกแท็บFOURTHที่ด้านขวาบนไม่ใช่แท็บที่สาม !!
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
ใน viewDidLoad()
Mette

18
หากคุณใช้ xib ในเซลล์ที่กำหนดเองคุณจะต้องลงทะเบียนดังนี้tableView.register(UINib.init(nibName: "CustomCell", bundle: nil), forCellReuseIdentifier: "CustomCellIdentifier")
atulkhatri

โซลูชัน 3+ ที่รวดเร็วข้างต้นใช้งานได้สำหรับฉันใน swift 5
Mike Volmar

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

เราต้องตั้งค่าคุณสมบัติIdentifierเป็น Table View Cell ตามภาพด้านล่าง

ใส่คำอธิบายภาพที่นี่


1
ง่ายมาก :-)
Luc-Olivier

1
มันได้ผล! ฉันกำลังตั้งค่า ID ในตัวตรวจสอบความคิด แต่การวางในตัวตรวจสอบคุณสมบัตินั้นได้ผลสำหรับฉัน
Fato

1
ขอให้พระเจ้าคุ้มครอง! ช่วยชีวิตฉันสองสามชีวิต
Ragen Dazs

26

วันนี้ฉันมีปัญหานี้ซึ่งแก้ไขได้โดยการเลือกผลิตภัณฑ์ -> ทำความสะอาด ฉันสับสนมากเพราะรหัสของฉันถูกต้อง ปัญหาเริ่มต้นจากการใช้ command-Z หลายครั้งเกินไป :)


1
ใช้เวลาอย่างจริงจังกว่าหนึ่งชั่วโมงในการพยายามแก้ไขข้อบกพร่องนี้ ขอบคุณ :)
ewakened

แน่นอนว่ามันทำงานร่วมกับการกำหนดตัวระบุในกระดานเรื่องราว (ดูคำตอบถัดไป)
Nech

21

กรณีของฉันฉันแก้ไขปัญหานี้โดยตั้งชื่อในคุณสมบัติ "Identifier" ของ Table View Cell:

ใส่คำอธิบายภาพที่นี่

อย่าลืม: เพื่อประกาศในคลาสของคุณ: UITableViewDataSource

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

ภาพนี้ไม่ตรงกัน แต่ให้คำใบ้
Martian2049

มันล้าสมัยไป
หน่อย

13

เพียงลากเซลล์ (เช่นเดียวกับที่คุณทำสำหรับ TableViewController) และเพิ่มเข้าไปเพียงแค่ปล่อยเซลล์บน TableViewController คลิกที่เซลล์และไปที่ตัวตรวจสอบคุณสมบัติและตั้งค่าตัวระบุเป็น "เซลล์" หวังว่าจะได้ผล


อย่าลืมคุณต้องการตัวบ่งชี้ในคุณสมบัติสารวัตร

( ไม่ใช่ "รหัสการกู้คืน" ใน "Identity Inspector"!)


6
ระวัง "รหัสการกู้คืน" ที่สับสน - ซึ่งไม่มีอะไร! คลิกแท็บ FOURTH ที่ด้านบนขวาไม่ใช่แท็บที่สาม !!!
Fattie

9

อีกสาเหตุหนึ่งที่ทำให้ปัญหานี้เกิดขึ้นคือปัญหาก่อนหน้านี้ เมื่อแสดง ViewController ใหม่การสร้างอินสแตนซ์ ViewController เป้าหมายโดยตรงจะไม่โหลดเซลล์ต้นแบบจาก StoryBoard วิธีแก้ปัญหาที่ถูกต้องคือการสร้างอินสแตนซ์ตัวควบคุมมุมมองผ่านกระดานเรื่องราวดังนี้:

storyboard?.instantiateViewController(withIdentifier: "some_identifier")

ใช่!! มันเป็นความจริง!! สิ่งนี้เกิดขึ้นกับฉันเพราะฉันเปลี่ยนไปใช้ ViewController ซึ่งอยู่ใน Storyboard ต่างกันเพียงแค่: self.present (MyViewController, animated: false, complete: nil) และดูเหมือนว่าจะไม่ดาวน์โหลดต้นแบบจริงๆ! ฉันได้ลองเริ่มต้นด้วย MyViewController โดยตรงแล้วและมันก็ใช้ได้! นอกจากนี้ยังใช้งานได้เมื่อฉันลงทะเบียน NIB สำหรับเซลล์ของฉันใน viewDidLoad ของ ViewController เป้าหมาย
Vitya Shurapov

7

จับคู่ชื่อตัวระบุที่ทั้งสองแห่ง

ข้อผิดพลาดนี้เกิดขึ้นเมื่อชื่อตัวระบุของ Tablecell แตกต่างกันในไฟล์ Swift และ The Storyboard

ตัวอย่างเช่นตัวระบุคือplacecellIdentifierในกรณีของฉัน

1) ไฟล์ Swift

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

หากคุณกำหนดเซลล์ของคุณผ่านตัวสร้างอินเทอร์เฟซโดยการวางเซลล์ภายในของคุณ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

สวิฟต์ 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 และอื่น ๆ ทั้งหมดยังคงเหมือนเดิม แต่จะมีการเพิ่มข้อยกเว้นที่รันไทม์

ทางออกเดียวคือการล้างหมึกทั้งหมดที่เกี่ยวข้องกับ tableview ใน IB (outlet, datasource, delegate) และสร้างใหม่อีกครั้ง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.