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.
Related
I'm trying to add a data source inside a UITableView. I tried the following, but unfortunately it didn't work:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 8;
}
// Customize the appearance of table view cells.
- (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];
}
// Set the data for this cell:
cell.textLabel.text = [_classCellview objectAtIndex:indexPath.row];
cell.detailTextLabel.text = #"One";
cell.detailTextLabel.text = #"Two";
// set the accessory view:
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
cell.textLabel.text = [_classCellview objectAtIndex:indexPath.row];
You're telling the table that there are 8 sections, but you're not taking the section from the index path into account when you populate the cell. An index path has (in the case of a table view) two values: a section and a row. You need them both to know what cell you're dealing with. So, you're probably getting the same content repeated in each section of your table. (It'd help if you told us exactly what the problem is, though.)
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];
}
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;
}
Okay, I am having another UITableView problem. For some reason the indexPath.row is all jumbled up. When I comment out the if statement that sets up the cell, everything works fine. The NSLogs tell me that they are loading in order, but all the cells are out of order.
It also seems as if they repeat; I only see 8 cells, and they repeat over and over.
Here's my code:
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
NSLog(#"row: %d",indexPath.row);
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.backgroundColor = [UIColor clearColor];
cell.contentView.backgroundColor = [UIColor clearColor];
// Add subviews like this:
// [[cell contentView] addSubview:objectName];
// And I get the row number like this: indexPath.row when getting objects from the array
}
return cell;
}
To use your code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
NSLog(#"row: %d",indexPath.row);
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.backgroundColor = [UIColor clearColor];
cell.contentView.backgroundColor = [UIColor clearColor];
// Add subviews like this:
// [[cell contentView] addSubview:objectName];
}
### Move this here ###
// And I get the row number like this: indexPath.row when getting objects from the array
return cell;
}
" I only see 8 cells, and they repeat over and over." Correct.
What your missing is that that is how it is supposed to work. That's why only if the cell is nil are you alloc & init'ing a new cell. So you alloc and init and set the colors and add subviews in the if statement. Then after the if(cell==nil) you know you have a valid cell to populate with some data according to the indexPath variable passed in.
The problem is that now you are setting up the cell when it is nil and assigning all of the displayed data according to the indexPath passed in. The problem is cell is not nil the second time it's used so the data is never changed.
To address your speed comment further, I'll use an old fallback example.
- (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];
UILabel *hugeLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, cell.frame.size.width, cell.frame.size.height)];
hugeLabel.tag = 300;
[cell addSubview:hugeLabel];
}
[(UILabel *)[cell viewWithTag:300] setText:[arrayOfStrings objectAtIndex:indexPath.row]];
return cell;
}
If you look at the sample above, you'll see that we add a UILabel to the cell setting it's tag to 300. Then after the if statement we will have either a brand new cell or a reused cell with text already in the label. No matter either way we simply change the text of the existing label to whatever it should be considering the row. In this way we avoid creating views over and over.
If you are dead-set on caching your UITableViewCells you could do so like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row < _cells.count){
return [_cells objectAtIndex:indexPath.row]; // _cells is an NSMutableArray setup in viewDidLoad
}
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#""];
cell.textLabel.text = [source objectAtIndex:indexPath.row]; // source is an NSArray of NSStrings I set up in viewDidLoad
[_cells addObject:cell];
return cell;
}
Note When running this on device don't be surprised when in the console you see Received memory warning What's efficient & what's easy are often not the same.
The way you have it set up now, cell.selectionStyle, cell.backgroundColor, and cell.contentView.backgrounColor, etc., only get set when if (cell == nil) is true. You need to move that code outside the if statement block, so that it gets called both when dequeueReusableCellWithIdentifier: produces a cell and when it has no cells in inventory and produces nothing (i.e., nil).
Can anyone help I am trying to set the values of the cells in a table view but I am getting EXC_BAD_ACCESS. here is my code :
- (UITableViewCell *)tableView:(UITableView *) tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView depueueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
cell.textLabel.text = [webRef objectAtIndec:indexPath.row];
return cell;
}
I am trying to set the values from an NSMutableArray. There are objects in the array I can print them to the console but not into the cells.
I have solved this. I was not retaining anything when declaring the Arrays. Thanks everyone for the help you have provided.