Error using self created tableviewcell - uitableview

I'm trying to design a UITableView and a customized UITableViewCell class, however, whenever I use my own UITableViewCell class, the app crashes with the error
fatal error: unexpectedly found nil while unwrapping an Optional value
It works fine with the default class UITableViewCell though.
Here is the code in my class:
import UIKit
import Foundation
class TableViewCell: UITableViewCell {
#IBOutlet var nameLabel: UILabel!
}

Did you correctly implement the UITableViewDataSource & UITableViewDelegate?
Especially, in the cellForRawAtIndexPath function you should have something like this:
let cell = tableView.dequeueReusableCellWithIdentifier("Cell") as TableViewCell
"Cell" refers to the identifier of the custom cell. You can set it up in the storyboard -> Show the Attributes Inspector -> Identifier

Related

unable to dequeue a cell with identifier cell with properly defined identifier

I experienced weird issue with TableViewController
*** Assertion failure in -[UITableView _dequeueReusableCellWithIdentifier:forIndexPath:usingPresentationValues:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit/UIKit-3694.4.18/UITableView.m:7732
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'unable to dequeue a cell with identifier cell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'
It makes no sense while
Identifier is set properly.
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
However if i place
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
in ViewDidLoad, then it works. However prototype from storyboard will not and is not used.
At this point i have no idea what's going on.
TableViewController class is set also correctly.
I understood your question, There are only one reason that your tableview can not find the registered cell.
Solution is that you have to check your code one more time. Please check your identifier spelling in both storyboard and cellForRowAt method.
if this solution not work than follow this steps:
paste below code in cellForRowAt method
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
return cell
Delete all cells from tableviewcontroller from storyboard.
Drag and drop new TableViewCell and give proper indetifer "cell"
Build and run.
This solution will definitely work.
As you using a TableViewCell Differently So I am sure you had also created a tableCell Class , as in my case its "CustomTableCellClass" as follow
class CustomTableCellClass: UITableViewCell {
weak var CategoriesDelegate: CategoriesVcDelegate?
weak var itemsDelegate: ItemsvcDelegate?
//MARK: Outlets of CategoriesVcTableView
#IBOutlet weak var ProductImage: UIImageView!
#IBOutlet weak var ProductName: UILabel!
#IBOutlet weak var ProductPrice: UILabel!
#IBOutlet weak var ProductStarImage: UIButton!
}
My cellReuseIdentifier Declaration -
let cellReuseIdentifier = "cell"
Now Deque it as
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = self.CategoriesTableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as! CustomTableCellClass
cell.CategoriesDelegate = self
cell.ProductStarImage.tag = indexPath.row
cell.ProductName.text = productNameArray[indexPath.row]
cell.ProductPrice.text = productPriceArray[indexPath.row]
cell.ProductImage.image = productImagesArray[indexPath.row]
return cell
}
Hope it helps :)
It seems that issue was in custom library i was using for navigation. Instead initialising view controller from storyboard identifier, it was initialising class directly, thus storyboard view controller was useless.
Everything works well now.

Unable to dequeue view needed as cell for UICollectionView

I've got a UICollectionView with a custom class that is subclassing UICollectionViewCell. I keep getting the following error:
reason: 'could not dequeue a view of kind:
UICollectionElementKindCell with identifier Appointment - must
register a nib or a class for the identifier or connect a prototype
cell in a storyboard'
I have however done the following:
Registered the custom class with the collectionView.
self.collectionView.registerClass(AppointmentCollectionViewCell.self, forCellWithReuseIdentifier:"Appointment");
Here is my dequeue line:
let appointmentCollectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier("Appointment", forIndexPath: indexPath) as! AppointmentCollectionViewCell;
This is what my AppointmentCollectionViewCell looks like:
class AppointmentCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var leftBorderView: UIView!
#IBOutlet weak var appointmentLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
}
func setAppointment(appointment:Appointment){
self.leftBorderView.backgroundColor = appointment.eventColour;
self.appointmentLabel.textColor = appointment.eventColour;
self.backgroundColor = appointment.eventColour.colorWithAlphaComponent(0.2);
}
}
I have also in the view provided the reuse identifier to be "Appointment".
I've also tried the following based on answers posted here - still not working:
let appointmentNib = UINib(nibName: "AppointmentCollectionViewCell", bundle:NSBundle.mainBundle())
self.collectionView.registerNib(appointmentNib, forCellWithReuseIdentifier: "Appointment")
After googling, most people forget to register the class. In my case I have registered the class but still keep getting the error. Where am I going wrong?
If your cell is associated with a xib file you need to use the registerNib method, not the registerClass method.
func registerNib(_ nib: UINib?, forCellWithReuseIdentifier identifier: String)
Documentation
You also seem to be confusing Collection Reusable View and UICollectionViewCell - which is it? Both have specific registration methods, check the documentation.
First Check:
You have a Xib which have class AppointmentCollectionViewCell
Get Nib from class
For e.g.
UINib *favouritesNib = [UINib nibFromClass:[TNYCellRestaurantAnchorclass]];
Register the Nib to CollectionView
[self.collectionViewName registerNib:nib forCellReuseIdentifier:#"identifier name"];

The label outlet is invalid

I want to declare the 4 labels which in my table prototype cells so that I can retrieve all the data from Parse into the label. As you see in the picture, there're 4 labels, I want each of them have their own outlet, but it showing me the invalid outlet error.
I'm using the Parse to do it, so that the superclass of the prototype cell will be the PFTableViewCell.
class TimetableViewController: PFQueryTableViewController, UITextFieldDelegate{
#IBOutlet weak var lblTime: UILabel!
The error that I got will be like this...
The lblTime outlet from the TimetableViewController to the UILabel is
invalid. Outlets cannot be connected to repeating content.
Therefore, what should I do to avoid this problem exist?
You need to create a custom subclass of UITableViewCell and declare your IBOutlets there. Then you use that subclass instead of the generic UITableViewCell throughout your main view controller.
To reiterate: elements inside a tableview cell belong to the cell, not to the view controller that contains everything.
Edit:
In your view controller, you would conform to UITableView's delegate & datasource protocols (and implement any methods that are relevant to what you're trying to accomplish). You would handle populating (initial) cell data in the follow data source method:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cellIdentifier", forIndexPath: indexPath) as! TimetableViewCell
// TODO: setup cell data here
return cell
}
Cells are generated on the fly. There is no real connection between the controller and the cell so you cannot connect something in the cell to a controller. Specifically, usually you have multiple cells of the same type ("repeated content") and you can't have all of the labels connected to one outlet in the parent controller.
Typically, what you want to do is declare a class for the cell, e.g.
class MyCell : UITableCell {
#IBOutlet weak var lblTime: UILabel!
}
and add the outlet to it.
For those that errors still exist after you delete the IBOutlet code from your view controller you still need to right click it and delete the old connection. After deleting it the error message will go away.
This cleared all my errors. Hope will help others as well.

This class is not key value coding-compliant for the key...why?

I've linked output from the IB to the code, as shown below.
class DiaryTableViewCell: UITableViewCell {
#IBOutlet weak var TitleLabel: UILabel!
#IBOutlet weak var SubTitleLabel: UILabel!
#IBOutlet weak var leftImageView: UIImageView!
#IBOutlet weak var rightImageView: UIImageView!
}
Here, I'm registering the class:
override func viewDidLoad() {
self.title = "My Diary"
cellNib = UINib(nibName: "TableViewCells", bundle: nil)
tableView.registerClass(DiaryTableViewCell.classForCoder(), forCellReuseIdentifier: kCellIdentifier)
}
But I keep getting the following runtime error:
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '...setValue:forUndefinedKey:]: this class is not key value
coding-compliant for the key SubTitleLabel.'
From within the following code:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier(kCellIdentifier) as DiaryTableViewCell?
if (cell == nil) {
tableView.registerClass(DiaryTableViewCell.classForCoder(), forCellReuseIdentifier: kCellIdentifier)
cell = cellNib?.instantiateWithOwner(self, options: nil)[0] as? DiaryTableViewCell
cell?.selectionStyle = .None
}
if (cell != nil) {
println("\(x++)) Inside cell")
cell!.TitleLabel.text = "Hello"
cell!.SubTitleLabel.text = "World"
}
return cell!
}
Specifically, it's happening here:
cell = cellNib?.instantiateWithOwner(self, options: nil)[0] as? DiaryTableViewCell
Question: How am I violating the key value coding-compliant for a UILabel?
This hasn't happened before... UILabel is KVO compliant.
I linked to the WRONG Source!
Here's the result:
You should not be calling instantiateWithOwner yourself inside tableView:cellForRowAtIndexPath.
Register the nib in viewDidLoad and then dequeueReusableCellWithIdentifier will do all the work for you.
The reason for your particular error is that you are calling instantiateWithOwner passing self as the owner and so the nib is trying to wire the outlets up to your UITableViewDataSource implementation class rather than a DiaryTableViewCell.
Show the references of your ViewController rigth-clicking in it on the Document Outline. Probably you will see a warning in one of the references. Delete it and link it again if still need it.
sometimes its like when you create button in your xib, you create one button and copy paste other buttons from one buttons, in that case this error occurs, and yes removed connections from xib could also be an reason.
I have created a TableViewCell same like your & have the same problem. I have research solving the problem but nothing. Then I delete Label in TableViewCell and recreate again, connect it to TableViewCell through File Owner,v..v And the result is right. No error. You should recreate them again.

Swift iOS custom cell properties can't be changed (unwrap empty optional)

I have gone through all the questions regarding this matter that seems to be popular. Anyhow, I have created a simple app with a table view that uses custom cells.
I use the storyBoard, and defined the cells with the same name the class I created, Xcode even auto-completed me.
Though when I initialise a new cell, I can't change the properties of the labels and image contained in the cell. I receive an error saying I accessed a nil, and I kinda get it. Though I couldn't seem to find a way around it. Can someone help?
import UIKit
class ExtenderCell: UITableViewCell {
#IBOutlet var main_image: UIImageView!
#IBOutlet var name_label: UILabel!
#IBOutlet var desc_label: UILabel!
init(to_put_image: UIImage, name: String, desc:String){
super.init(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "cell")
name_label.text = name
desc_label.text = desc
main_image.image = to_put_image
}
}
You are using storyBoard for cell creation with outlets.Your outlets are not accessible to you till awakeForNib() using storyBoard as it is not unarchived till awakeFromNib. Your outlets or properties are nil in init so you are getting this exception as you are trying to unwrap nil outlet property in init method.
As your outlet properties are not accessible in init method and they are nil in init.So you need to set your outlets in awakeForNib().Or you can set the properties in cellForRowAtIndexPath.So best approach is to make your init method as instance method if you want to use storyBoard.
import UIKit
class ExtenderCell: UITableViewCell {
#IBOutlet var main_image: UIImageView!
#IBOutlet var name_label: UILabel!
#IBOutlet var desc_label: UILabel!
func setContents(to_put_image: UIImage, name: String, desc:String){
name_label.text = name
desc_label.text = desc
main_image.image = to_put_image
}
}
set the contents of cell in cellForRowAtIndexPath
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
//Check your identifier in storyBoard is "cell"
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as ExtendedCell
cell.setContents(yourImage, name: yourName, desc: yourDescription)
return cell
}

Resources