Registered NIB, still getting assertion error when I use dequeueReusableCellWithIdentifier - objective-c

I have a custom UITableViewCell class that I want to use to create custom table cells. I created the custom table cell's xib as well as its header and implementation files, all called RTRepairOrderTableCell.m/.h/.xib.
My issue is that even though I set the reuse identifier of the table cell to RTRepairOrderTableCell inside of the .xib file and registered the xib inside of my table view controller, I am still getting assertion errors when it tries to dequeue or create a new cell for use.
Inside of my view (table) controller I have the following:
- (void)viewDidLoad
{
[super viewDidLoad];
//Load the nib file
UINib *nib = [UINib nibWithNibName:#"RTRepairOrderTableCell"
bundle:nil];
// Register this Nib, which contains the cell
[self.tableView registerNib:nib
forCellReuseIdentifier:#"RTRepairOrderTableCell"];
}
There are no errors here and it finishes viewDidLoad just fine.
Inside of my cellForRowAtIndexPath I have the following:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
RTRepairOrderTableCell *cell = [tableView dequeueReusableCellWithIdentifier:#"RTRepairOrderTableCell" forIndexPath:indexPath];
return cell;
}
According to every tutorial I've seen, this should work so long as I have the reuse identifier set properly inside the xib file and I register that xib inside of viewDidLoad in the view controller class that will display the table cells, so I am at a loss as to why I am getting
*** Assertion failure in -[UITableView _dequeueReusableViewOfType:withIdentifier:], /SourceCache/UIKit/UIKit-2935.138/UITableView.m:5413

Turns out I had a few orphaned UIImage objects inside the nib file but outside of the UITableViewCell area, so it was throwing errors saying that the UITableViewCell needed to be the topmost view.

I faced this and it was driving me crazy. But it was my fault. I had set identifier #"Abc" in Nib file and I was registering the same nib file with some other identifie #"Xyz". Removed the identifier from nib, left that part blank and it worked like a champ. :)

This might be a rare case, but due to some sloppy copy pasta two different UITableViewCell custom classes used in my table had the exact same Identifier specified in the Xib.
Switching one of these cells to have a different Identifier in the Attributes Inspector fixed my Assertion failures.

Check if in your .xib there are no UI component outside main layout:
Label is not accepted
In this example, Label is not accepted and cause the exception

Related

Reusing custom UITableViewCells, see old UIView pictures briefly before new pictures load

I have a custom UITableViewCell that contains a UIView, in which I display a couple of pictures.
In my tableView:cellForRowAtIndexPath: function, I call dequeueReusableCellWithIdentifier: to reuse old custom cells, and then I update them with new pictures.
The problem is that when I scroll quickly on my screen, I see flickers of the old pictures before the new ones are loaded, which is unattractive.
I've tried to fix this by:
implementing prepareForReuse in the custom TableViewCell implementation file; this led to the same three UIViews appearing over and over again, and in this case the new pictures stopped loading altogether
clearing the UIView right after calling dequeueReusableCellWithIdentifier by using a for loop to remove all subviews; the app now takes a really long time to load pictures.
What is the best way to fix this, and why do the above errors in my attempted fixes occur? Here is my current code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellIdentifier = #"Blah";
blahCell *someCell = (blahCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!someCell) {
//initialize cell
} else {
someCell.imageContainerView = nil;
}
... (other code here)
}
I'd try setting the cell's imageView property to nil as the first step in your table view data source method cellForRowAtIndexPath.
You can use this UIImageView Category by AFNetworking.
Whenever you have to set a new image you just need to call
[someCell.imageContainerView setImageWithURL:url placeholderImage:placeholderImage];
Now, whenever you scroll, if the image is not loaded you will see a placeholder image instead of seeing previous cell images.

Xcode Table View erased after assigning custom class to controller

I am using XCode 5, and I am having an issue with assigning class to a TableViewController
I made a form using tableViews within a TableViewController. The TableView has static cells that are the ones containing the textBoxes for user input.
The problem is that after designing the tableView, I added a custom class to it. When I run the program, the view is an empty table view, but in the storyboard looks like I design it.
So maybe after assigning the custom class (which is a new empty class UITableViewController) everything is either not being load or being re-instanced?
Added:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
return cell;
}
This is the default method.
You need to create custom class for UITableViewCell, instead of creating it for UITableView, as table view contains tableViewCell, as the default ones, but your cell contains textFields which is not by default. Let me know if you need more clarity here
None of the above helped me. This is what solved the problem:
What was going on? the problem was that even with Static Cells instead of Prototypes, the TableViews was trying to use his datasource to get the cells to display (The class that i assigned to its controller). It was easy then, i just had to erase the methods in the TableViewController Class.
Maybe because the class had an function that weren't suppose to be there, or because the TableView had the DataSource linked to it.
The result was a TableViewController with a static table.

UITableViewCell as Header or Footer View

I know about UITableView reusable header and footer view
but in my case, i have UITableView Cells, which i need to place also in section headers and also in normal rows
if i use
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
MyCell * cell = [tableView dequeueReusableCellWithIdentifier:#"MyCell"];
// ...
return cell;
}
How does it work out with the reusing? (is the message to be available for reuse even than passed), or does this disable the cell reuse
The cells get dealloc'ed when they go off-screen. So they don't get reused. An easy way to verify this is to subclass UITableViewCell with the following
- (void)dealloc
{
NSLog(#"I got dealloc'ed");
}
and observe the console output as you scroll.
These has always worked fine. You first should create a prototype with that name, or register a custom nib with your custom section identifier. HOWEVER , I noticed this breaks in iOS 7 when you add new sections to the table dynamically. Reverting to a plain non-reusing UIView works. Really a shame!

UICollectionViewController multiview error

I have an issue with the UICollectionViewController. I start with the default view controller and i make a segue to a UICollectionView. When i click on the button which link to that collection i have that
error :
could not dequeue a view of kind: UICollectionElementKindCell with identifier Cell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'
and the signal seems to be throw from that lign :
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
What does it mean ?
From UICollectionView reference:
Before you call either of these methods, you must tell the collection
view how to create the corresponding view if one does not already
exist. For this, you must register either a class or a nib file with
the collection view. For example, when registering cells, you use the
registerClass:forCellWithReuseIdentifier: or
registerNib:forCellWithReuseIdentifier: method. As part of the
registration process, you specify the reuse identifier that identifies
the purpose of the view. This is the same string you use when
dequeueing the view later.
So you need to register a class or nib to be able to deuqeue one.
To register:
[collectionView registerClass:[MyCellClass class] forCellWithReuseIdentifier:#"MyCellIdentifier"];
To dequeue:
[collectionView dequeueReusableCellWithReuseIdentifier:#"MyCellIdentifier" forIndexPath:indexPath]

Why can't I define IBOutlets when using custom "prototype tableviewcells"

I have my own table view cell which is defined in my storyboard. I have also defined a custom UITableViewCell class for this special cell. So when I want to create an Outlet for my custom prototype cell I get an error that the Outlet cant be created.
Since this is not possible I have to do some ugly workarounds and use the tags in IB to reference the individual labels and buttons later on in my code.
I don't really see why this is not possible and I wonder if working with tags and [myCell viewWithTag:] is the best possible way to go here?
Because the outlet is a one-to-one connection between your controller and a specific item within the view. In the case of a prototype cell, it is simply a description of a cell that can have an arbitrary number of different items (i.e. rows in your table view). How would the controller know which item you are referring to (e.g. row 5 or 500)? That is why you are receiving the error message.
Lucas provided one method to refer to your connection via tags which works perfectly well.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"CellIdentInIB"];
UIImageView *img = (UIImageView*) [cell.contentView viewWithTag:1];
//img.image = ...
//Access you prototype cell here to alter its style, example:
[[cell layer] setCornerRadius:10];
[cell setClipsToBounds:YES];
return cell;}
I assume you are using dynamic prototypes - in the attribute inspector of the tableview in the storyboard there is an option to select "static cells" or "dynamic prototypes". You can do what you are trying to do if you select "static cells" as there is only one cell in your tableview at run time for each cell in the storyboard. Using this approach you will only be able to use the cells you create in storyboard i.e. you will not be able to select the number of cells in your code.