How to NOT use dequeueReusableCellWithIdentifier? - objective-c

I have a small table view, maybe 10 items max, and I do not want to use the dequeueReusableCellWithIdentifier method. The reason is, each time I'm scrolling the table view, I have the first row in place of the last row, which take few second to update back to get update back with the last row.
I'm using a prototype cell and i try to remove the :
JsonTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
but it return blank cells in table view.
So here is my code :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"Cell";
JsonTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell=[[JsonTableViewCell alloc]initWithStyle:
UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
I also try to keep the
JsonTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
and configure the cell like:
if (cell == nil) {
cell.title.text = titleStrip;
}
but in this case, I've got the prototype cell as it is in the storyboard. It's not blank, but not filled with data.
Anybody can tell me what I am doing wrong?
UPDATE **** 10.10.2014 *******
Here is maybe the all code would help :
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return myObject.count;
}
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"Cell";
JsonTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell=[[JsonTableViewCell alloc]initWithStyle:
UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
NSDictionary *tmpDict = [myObject objectAtIndex:indexPath.row];
NSMutableString *text;
text = [NSMutableString stringWithFormat:#"%#",
[tmpDict objectForKeyedSubscript:title]];
NSMutableString *detail;
detail = [NSMutableString stringWithFormat:#"%# ",
[tmpDict objectForKey:content]];
NSURL *url = [NSURL URLWithString:[tmpDict objectForKey:thumbnail]];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *img = [[UIImage alloc]initWithData:data];
NSString *titleStrip = [[text description] stringByReplacingOccurrencesOfString:#""withString:#""];
NSString *detailStrip = [[detail description] stringByReplacingOccurrencesOfString:#""withString:#""];
dispatch_sync(dispatch_get_main_queue(), ^{
cell.titreNews.text = titleStrip;
cell.detailNews.textAlignment = NSTextAlignmentJustified;
cell.detailNews.text = detailStrip;
UIImage *image0 = [UIImage imageNamed:#"video.png"];
if (img != nil) {
cell.imageNews.image = img;
}
else {
cell.imageNews.image = image0;
}
});
});
[cell setAccessoryType:UITableViewCellAccessoryNone];
return cell;
}

This block of code is never called because you instantiate a cell before it (cell is never nil).
if (cell == nil) {
cell.title.text = titleStrip;
}
Don't call the dequeue methods if you aren't using them. Change your method to this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//Don't even try to dequeue, just create new cell instance
JsonTableViewCell *cell = [[JsonTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
cell.title.text = titleStrip;
return cell;
}

First of all, welcome to Stack Overflow!
Second, I highly recommend against disabling dequeuing. Apple is famously strict when it comes to expected behaviors, and trying to re-work a basic UI element like a TableView to work in a different way could easily get your app rejected. Plus, dequeuing is a good thing, which helps keep memory usage down and streamlines things in general. It's far, far better to find a way to design your own code so it works with the dequeuing process as it is intended to work.
That being said, as I understand it all you need to do is omit the dequeueReusableCellWithIdentifier line, and it should work. cell will be nil each time, and will thus get re-initialized each time from scratch.

Related

"no index path for table cell being reused" issue for custom cell

I am having a Tableview within that i have a custom cell and within that i have another tableview. In this cellForRowAtIndexPath method i am getting this error no index path for table cell being reused and cell gets disappeared after scroll. Is this indexpath issue or cellidentifier issue?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CustomCell";
CustomCell *customCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// __block CustomCell *customCell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// if (customCell == nil)
// {
// customCell = [[[CustomCell alloc] initWithFrame:CGRectMake(0, 0, 320, 416)] autorelease];
//
// }
[customCell prepareCell:arrCategory];
return customCell;
}
-(void)prepareCell:(NSArray *)arrCategory
{
if(mutArr != nil) {
[mutArr removeAllObjects];
mutArr = nil;
[mutArr release];
}
mutArr = [[NSMutableArray alloc] arrCategory];
[tblCusom reloadData];
}
I go through this SO ques but i am not using the method used in this question. So what could be the problem I am not able to trace it. Also not found the same issue after googling
If I right understood, you need check tableView (mainTableView or tblCustom) for which call method of delegate.
Something like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView == tblCusom)
{
__block CustomCell *categoryCell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (customCell == nil)
{
customCell = [[[CustomCell alloc] initWithFrame:CGRectMake(0, 0, 320, 416)] autorelease];
}
[customCell prepareCell:arrCategory];
}
else if (tableView == self.myMainTableView)
{
static NSString *CellIdentifier = #"CustomCell";
CustomCell *categoryCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
return categoryCell;
}
return customCell;
}
Hope it helps you.
I was also facing this bug from a long time and found a solution :-
[tblCusom reloadData];
Replace it with
[self performSelector:#selector(tableReloadMethod) withObject:nil afterDelay:0.5];
Add this method:-
-(void)tableReloadMethod
{
[tblCusom reloadData];
}
Hope it helps you.
CustomCell *categoryCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
You are creating a cell instance but not using it anywhere,and that cell is returning from the reuseIdentifier method.So in fact no use of this line in your code

uiwebview in every tableviewcells

I need to display each webview in each of the tableviewcell in my Uitableview.When using the below code,when there are 2 elements,the first cell is empty but second cell is correct.hrs and hrsHtml contains all values,the problem is only the last data is displaying in their appropriate cell in tableview.Other cells are just blank.Also is total cells is 2,first we can only been able to see the 2nd cell only,but after scrolling tableview reloads and 2nd cell disappears and 1st cell gets displayed.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [brId count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:nil];
if (cell == nil) {
cell = [[ UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
[cell.contentView addSubview:hrs];
hrsHtml = [NSString stringWithFormat:#" <font size=\"2\" face=\"Arial\">%# </font>",[html objectAtIndex:indexPath.row]];
[hrs loadHTMLString:hrsHtml baseURL:nil];
return cell;
}
Screenshot when tableview appears,Only webview in cell 2
Screenshot when tableview scrolls,Only webview in cell 1,cell 2 disappears
Since hrs and hrsHtml are single objects, you only have one of each even though you have multiple cells. If you modify hrs, it will change for all cells since they seem to be sharing it. (Unless you have other code somewhere that changes the objects that those variables point to.)
Another odd thing is that you use a brId array to determine the number of rows and a html array to get the row content. If those ever get out of synchronization, you will have problems.
Also, you should only add a subview to a cell when you create a new one.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil] ;
}
hrs = [[UIWebView alloc] initWithFrame:CGRectMake(10,0,320,84)];
hrs.userInteractionEnabled = YES;
hrs.backgroundColor = [UIColor clearColor];
hrsHtml = [NSString stringWithFormat:#" <font size=\"2\" face=\"Arial\">%# </font>",[html objectAtIndex:indexPath.row]];
[hrs loadHTMLString:hrsHtml baseURL:nil];
[cell.contentView addSubview:hrs];
hrsHtml = nil;
return cell;
}
Now the webview loads correctly in every tableviewcell.
i think you have problem in initializing cell try below code
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil] autorelease];
}

EXC_BAD_ACCESS scrolling TableView

im getting EXC_BAD_ACCESS when i scroll my TableView. I heard something like alloc being called wrong, I dont know. Here's my code:
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [[resultsDictionary objectForKey: #"bills"] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Identifier for retrieving reusable cells.
static NSString *cellIdentifier = #"MyCellIdentifier";
// Attempt to request the reusable cell.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
// No cell available - create one.
if(cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:cellIdentifier];
}
NSArray *billsArray = [resultsDictionary objectForKey:#"bills"];
cell.textLabel.text = [NSString stringWithFormat:#"%#", [[billsArray objectAtIndex:indexPath.row] objectForKey:#"name"]];
return cell;
}
EDIT
I think the error is here:
* -[JKArray objectAtIndex:]: message sent to deallocated instance 0x6a5d030
NSString *cellName = [NSString stringWithFormat:#"%#", [[billsArray objectAtIndex:indexPath.row] objectForKey:#"name"]];
It looks like resultsDictionary is a dangling pointer. If you are using ARC, you need a strong reference to it somewhere. If you are not using ARC, you need to retain it somewhere.
Fixed. My billsArray was missing 'self' instance, as inside of cellForRowAtIndexPath method. Thanks to everyone.

Table view doesn't show up custom cells

I have a view controller that shows up a table view controller when a button is clicked. Everything works fine with table view delegates, table view is shown fine, but in ellForRowAtIndexPath: delegate method, cell is instantiated and returned, but it's not shown correctly.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"alrededor";
alrededorCell *cell = [tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[alrededorCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSDictionary *categoria = [[NSDictionary alloc] initWithDictionary: [_categoriasArray objectAtIndex:indexPath.row]];
NSLog(#"categoria %#", categoria);
cell.title.text = [categoria valueForKey:#"title"];
return cell;
}
Many thanks
Why are you creating your cell like this?
if (cell == nil) {
cell = [[alrededorCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
If it is your own custom cell why do you use UITableViewCellStyleDefault ?
If the cell you are loading is a subclass of UITableViewCell and you've used the interface builder to build the cell you have to do a couple of things.
In the nib file delete the view that is there when you create it, add a UITableViewCell and change it's class to alrededorCell. Changes the cells class and not the file's owner. When you are linking buttons,labels etc . be sure to link them to the cell not to file's owner. Also set the cells uniqueIdentifier to alrededor.
In cellForRowAtIndexPath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"alrededor";
alrededorCell *cell = [tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *xib = [[NSBundle mainBundle] loadNibNamed:#"nibName" owner:nil options:nil];
for (alrededorCell *view in xib) {
if ([view isKindOfClass:[alrededorCell class]]) {
cell = view;
}
}
}
NSDictionary *categoria = [[NSDictionary alloc] initWithDictionary: [_categoriasArray objectAtIndex:indexPath.row]];
NSLog(#"categoria %#", categoria);
cell.title.text = [categoria valueForKey:#"title"];
return cell;
}

NSFetchedResultsController returning objects with null attributes

So I'm using mogenerator with Core Data, the resultsController returns good objects with valid attributes when I first load the tableview. But when I scroll the table, all the reloaded cells are populated with objects with null attributes returned from resultsController. Is it some caching issue?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Configure the cell...
Log *log = [self.resultsController objectAtIndexPath:indexPath];
cell.textLabel.text = [NSString stringWithFormat:#"%#", log.text];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
Turns out I shouldn't put the resultsController in the viewWillLoad or viewDidLoad. I put it into it's own access method and it works fine now.