không thể xếp hàng lại một ô với Ô định danh - phải đăng ký một nib hoặc một lớp cho số nhận dạng hoặc kết nối một ô nguyên mẫu trong một bảng phân cảnh


113

Tôi khá mới đối với việc viết mã nói chung và thực sự mới đối với Xcode (Swift). Tôi hiểu rằng tôi cần đăng ký một nib hoặc một lớp học nhưng tôi không hiểu 'ở đâu hoặc bằng cách nào?'.

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
Cẩn thận với "ID phục hồi" khó hiểu - không có gì! Nhấp vào tab THỨ TƯ ở trên cùng bên phải, KHÔNG phải tab THỨ BA !!
Fattie,

Câu trả lời:


82

Bạn đã đặt số nhận dạng Ô trong bảng thành "Ô" trong bảng phân cảnh của mình chưa?

Hay bạn đã đặt lớp cho UITableViewControllerlớp của mình trong cảnh đó?


102

Bạn có thể đăng ký một lớp học UITableViewCellnhư thế này:

Với Swift 3+:

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

Với Swift 2.2:

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

Đảm bảo rằng cùng một số nhận dạng " cell" cũng được sao chép vào bảng phân cảnh của bạn UITableViewCell.

" self" là để nhận lớp, sử dụng tên lớp theo sau .self.


1
Bạn đặt cái này ở đâu?
RJB

7
trong viewDidLoad()
Mette

18
Nếu bạn đang sử dụng một xib trong tế bào tùy chỉnh của bạn, bạn sẽ phải đăng ký nó như thế này:tableView.register(UINib.init(nibName: "CustomCell", bundle: nil), forCellReuseIdentifier: "CustomCellIdentifier")
atulkhatri

giải pháp nhanh chóng 3+ ở trên đã hiệu quả với tôi trong vòng 5 nhanh chóng
Mike Volmar

38

Điều này làm việc cho tôi, cũng có thể giúp bạn:

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

Chúng tôi phải đặt thuộc tính Định danh thành Ô Chế độ xem Bảng theo hình ảnh bên dưới,

nhập mô tả hình ảnh ở đây


1
Chỉ đơn giản vậy thôi :-)
Luc-Olivier

1
nó đã làm việc! Tôi đã thiết lập ID trong thanh tra idendity nhưng dán nó vào thanh tra thuộc tính làm việc cho tôi
Fato

1
Chúa phù hộ bạn! Đã lưu một vài cuộc đời của tôi
Ragen Dazs vào

26

Tôi gặp sự cố này hôm nay đã được giải quyết bằng cách chọn Sản phẩm -> Sạch sẽ. Tôi đã rất bối rối vì mã của tôi là thích hợp. Vấn đề bắt đầu từ việc sử dụng lệnh-Z quá nhiều lần :)


1
Nghiêm túc đã dành hơn một giờ để cố gắng gỡ lỗi này. Cảm ơn bạn :)
ewakened

Tất nhiên nó hoạt động kết hợp với việc xác định các định danh trong các kịch bản (xem câu trả lời tiếp theo)
Nech

21

y trường hợp của tôi, tôi đã giải quyết vấn đề này bằng cách đặt tên nó trong thuộc tính "Định danh" của Ô Chế độ xem Bảng:

nhập mô tả hình ảnh ở đây

Đừng quên: khai báo trong Lớp của bạn: UITableViewDataSource

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

hình ảnh này không khớp nhưng nó đã đưa ra một số gợi ý.
Martian2049

đó là một chút out-ngày chỉ
Martian2049

13

Chỉ cần kéo một ô (như bạn đã làm đối với TableViewController) và thêm vào đó chỉ bằng cách giải phóng ô trên TableViewController. Nhấp vào ô và đi tới trình kiểm tra thuộc tính của nó và đặt số nhận dạng của nó là "Ô". Hy vọng nó hoạt động.


Đừng quên rằng bạn muốn Mã định danh trên Trình kiểm tra thuộc tính .

( KHÔNG phải là "ID khôi phục" trên "Trình kiểm tra danh tính"!)


6
Cẩn thận với "ID phục hồi" khó hiểu - không có gì! Nhấp vào tab THỨ TƯ ở trên cùng bên phải, KHÔNG phải tab THỨ BA !!!
Fattie

9

Một lý do nữa cho vấn đề này xảy ra là một vấn đề sớm hơn. Khi hiển thị một ViewController mới, việc khởi tạo trực tiếp ViewController đích tất nhiên sẽ không tải các ô nguyên mẫu từ StoryBoard. Giải pháp đúng luôn phải là khởi tạo bộ điều khiển chế độ xem thông qua bảng câu chuyện như sau:

storyboard?.instantiateViewController(withIdentifier: "some_identifier")

Đúng!! Đúng rồi!! Điều này xảy ra với tôi vì tôi đã chuyển sang ViewController nằm trong Storyboard khác chỉ với: self.present (MyViewController, animation: false, hoàn thành: nil). Và có vẻ như nó thực sự không tải xuống nguyên mẫu! Tôi đã cố gắng bắt đầu trực tiếp với MyViewController và nó hoạt động đúng! Nó cũng hoạt động khi tôi đăng ký NIB cho ô của mình trong viewDidLoad của ViewController đích.
Vitya Shurapov

7

Khớp tên mã định danh ở cả hai nơi

Lỗi này xảy ra khi tên định danh của Tablecell trong tệp Swift và Bảng phân cảnh khác nhau.

Ví dụ: giá trị nhận dạng là placecellIdentifier trong trường hợp của tôi.

1) Tệp Swift

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

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

    // Your code 

    return cell
}

2) Bảng phân cảnh

nhập mô tả hình ảnh ở đây


5

Trong Swift 3.0, đăng ký một lớp cho UITableViewCell của bạn như thế này:

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

2

Tôi đã từng gặp vấn đề tương tự. Vấn đề này đã làm việc cho tôi. Trong bảng phân cảnh, hãy chọn chế độ xem bảng của bạn và thay đổi nó từ các ô tĩnh thành các ô động.


2

Nếu bạn đã xác định ô của mình thông qua Trình tạo giao diện, bằng cách đặt một ô bên trong UICollectionViewhoặc UITableView:

Đảm bảo rằng bạn đã liên kết ô với một lớp thực tế mà bạn đã tạo và rất quan trọng, rằng bạn đã chọn "Kế thừa mô-đun từ đích"


2

Nó đã từng hoạt động trên swift 3 và swift 4 nhưng bây giờ nó không hoạt động.

giống

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

Vì vậy, tôi đã thử hầu hết các giải pháp được đề cập ở trên trong swift 5 nhưng không gặp may.

Cuối cùng tôi đã thử giải pháp này và nó đã làm việc cho tôi.

override func viewDidLoad() 
{

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

2

Vấn đề của tôi là tôi đã đăng ký ô xem bảng bên trong hàng đợi gửi một cách không đồng bộ. Nếu bạn đã đăng ký nguồn chế độ xem bảng và tham chiếu ủy quyền trong bảng phân cảnh thì hàng đợi điều phối sẽ trì hoãn việc đăng ký ô như tên cho thấy, nó sẽ xảy ra không đồng bộ và chế độ xem bảng của bạn đang tìm kiếm các ô.

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

Bạn không nên sử dụng hàng đợi gửi để đăng ký HOẶC làm điều này:

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

1

Tôi vừa gặp vấn đề tương tự và xem bài đăng này. Đối với tôi, đó là vì tôi đã quên thiết lập định danh của ô, cũng như đã đề cập trong các câu trả lời khác. Điều tôi muốn nói là nếu bạn đang sử dụng bảng phân cảnh để tải ô tùy chỉnh, chúng tôi không cần đăng ký ô chế độ xem bảng trong mã, điều này có thể gây ra các vấn đề khác.

Xem bài đăng này để biết chi tiết:

Ô xem bảng tùy chỉnh: Nhãn IBOutlet là nil


0

Chỉ đối với những người mới làm quen với iOS (như tôi), những người quyết định có nhiều ô và trong một tệp xib khác, giải pháp không phải là có số nhận dạng mà là làm điều này:

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

ở đây newsDetails là tên tệp xib.


0

Swift 5

bạn cần sử dụng phương thức UINib để đăng ký ô trong 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

Trong trường “Lớp con của”, chọn UITableViewController.

Tiêu đề lớp thay đổi thành xxxxTableViewController. Để nguyên như vậy.

Đảm bảo rằng tùy chọn “Đồng thời tạo tệp XIB” được chọn.


0

Tôi gặp thông báo này khi UITableView trong IB được chuyển sang một chế độ xem phụ khác với Cmd-C - Cmd-V.

Tất cả các số nhận dạng, phương thức ủy quyền, liên kết trong IB, v.v. vẫn nguyên vẹn, nhưng ngoại lệ được đưa ra trong thời gian chạy.

Giải pháp duy nhất là xóa tất cả các loại mực, liên quan đến tableview trong IB (đầu ra, nguồn dữ liệu, ủy nhiệm) và làm lại chúng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.