I have a table view. I have created a method that takes all the data it needs with a cell and returns the updated cell. In that method I have:
my cell for row goes like this
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
cell = myCellcreationMethod : cell : reuseIdentifier: other arguments;
MycellCreation method goes like this:
MycellCreation with args some strings , the cell and the reuseIdentifier.
if ( cell == nil ) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier];
//Here code that creates a custom image view something like:
thumbnailView = [[UIImageView alloc] initWithFrame:CGRectMake(9, 9, 70, 70)];
thumbnailView = [imUtil getImageViewWithRoundedCorners:thumbnailView andRadius:10.0];
thumbnailView.contentMode = UIViewContentModeScaleAspectFit;
[cell.contentView addSubview:thumbnailView];
//same here for another image view,
//same again
//and there same for a UILabel
}
//Here I set in each case the data for each imageView from above and the UIlabel text like
UIImage *thumbnailImage = [imUtil getThumbnailImageWithFile:thumbnail];
thumbnailView.image = thumbnailImage;
//the others go here
textLabel.text = #"something";
return cell;
All cells have the same identifier since they all are of the same type. But when I scroll down, instead of showing the data that corresponds to the next object in my list (new thumbnail new image, new text in uilabel) it replicates the first ones. I guess it loads the reused cell but does not put the new data in.
Any suggestions please?
I found the answer. I shouldn't just add the views with a method in my tableview class. I created a NEW subclass of UITableView, initialized it with my custom views and created a method in there that sets the new data. then used them two and it works like a charm!
Related
I am attempting to call a reloadData on my table's rows on a viewDidAppear method access. However, my cells are not refreshing their values and I cannot figure out why, as it seems everything is being accessed in the order it is suppose to. To make matters more odd, 1 row actually does refresh, but none of the others do.
Here is my code...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Set up the cell...
static NSString *CellWithIdentifier = #"Cell";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellWithIdentifier];
NSLog(#"generating cell contents");
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellWithIdentifier];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.textLabel.text = [_tableGroup.options objectAtIndex:rowcount];
rowcount++;
//label for currently selected/saved setting
_currentSetting = [[UILabel alloc] initWithFrame:CGRectMake(160, 8, 115, 25)];
[_currentSetting setFont:[UIFont systemFontOfSize:14]];
_currentSetting.backgroundColor = [UIColor clearColor];
_currentSetting.textColor = [UIColor blueColor];
_currentSetting.textAlignment = NSTextAlignmentRight;
[cell.contentView addSubview:_currentSetting];
NSLog(#"added new label to cell");
}
//depending on the setting, set the label in the cell to what is currently selected
if (indexPath.section == 1 && indexPath.row == 0) {
_currentSetting.text = [NSString stringWithFormat:#"%# %#",[settings.mapDistance stringValue], NSLocalizedString(#"MILES_IDENTIFIER", nil)];
NSLog(#"setting map distance label: %#", settings.mapDistance);
}
else if(indexPath.section == 1 && indexPath.row == 1)
{
_currentSetting.text = [NSString stringWithFormat:#"%# %#",[settings.maxCustomers stringValue], NSLocalizedString(#"ITEMS_IDENTIFIER", nil)];
NSLog(#"setting max customers: %#", settings.maxCustomers);
}
else if(indexPath.section == 2)
{
_currentSetting.text = [NSString stringWithFormat:#"%# %#",[settings.maxProducts stringValue], NSLocalizedString(#"ITEMS_IDENTIFIER", nil)];
NSLog(#"setting max products: %#", settings.maxProducts);
}
return cell;
}
based on this code, i get this output with my NSLOGS.
this is the first run of the cells when the view is created. It generates 4 cells, puts labels in each cell, and in 3 of those labels, puts in a value.
generating cell contents
added new label to cell
generating cell contents
added new label to cell
setting map distance: 15
generating cell contents
added new label to cell
setting max customers: 250
generating cell contents
added new label to cell
setting max products: 150
at this point i have clicked a row, went to a different screen, and have now returned. as you can see, map distance is different. although no change is displayed, even though the code to change the label's text is accessed during the reload process.
reloading data
generating cell contents
generating cell contents
setting map distance: 25
generating cell contents
setting max customers: 250
generating cell contents
setting max products: 150
again, I'm at a loss because the last row DOES refresh correctly. But none of the others do.
Thanks
When you reload your tableView, the cells already exist and are dequeued from the tableView, so the condition if (cell == nil) returns false, and the cell creation code is not executed.
In that cell creation code, you are assigning a value to _currentSetting and then proceed with the acode assuming that value is correct. However, when the cell creation code is not executed, that value points to the latest created cell, and thus, it won't update.
To fix this: make _currentSetting a local variable and change the code to look like this:
(You don't really need to make it a local variable, but it's more appropriate because you don't really need a reference to the last label you created after you leave this method)
UILabel *_currentSetting = nil;
if (cell == nil) {
_currentSetting = ...
_currentSetting.tag = 123;
}
else
_currentSetting = [cell.contentView viewWithTag:123];
...
The problem here is that the second time (when you are reloading the view ) the _currentSetting is not having a valid memory .So it is better to implement a custom cell and do the job
Better refer this an excellent guide
The second time around, you can see that "added new label to cell" isn't being called, so you're re-using an old tableViewCell.
Note that you're not setting _currentSetting when re-using a cell, only when creating a new cell. So _currentSetting is set to the last new cell that was created, most likely the last cell in the table.
You need to make sure to set _currentSetting to the correct label (maybe by using viewWithTag: or something similar).
(e:f;b)
I've been trying to resolve this issue for quite some time now and I still can't figure it out. What I have is a custom table view cell in story board. In the cell, I added 6 views and each view has an imageView subview. I set the views' tag so that I can access them later on. This table serves as a thumbnail view in my app. The problem is that, in a specific row, the last thumbnail container view no longer have the imageview as subview resulting to a crash.
Below is my code in setting up the images for the table. Any help would be greatly appreciated. Thank you!
NSString *CellIdentifier = #"ThumbnailCell";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
//loops through each thumbnails
for (int i=1; i<=kNumberOfThumbnails; i++)
{
//get index of current thumbnail- starting value is 0
int index=((indexPath.row *kNumberOfThumbnails)+i)-1;
NSLog(#"index %d",index);
//create an indexpath given the computed index and cell section
NSIndexPath *currentIndexPath=[NSIndexPath indexPathForRow:index inSection:indexPath.section];
//get number of sections
NSArray *sections = [self.fetchedResultsController sections];
NSInteger count=0;
id <NSFetchedResultsSectionInfo> sectionInfo = [sections objectAtIndex:indexPath.section];
//get number of objects for given section
count = [sectionInfo numberOfObjects];
NSLog(#" i: %d number of subviews ni thumn container %d",i,thumbContainer.subviews.count);
//get view container for thumbnails
UIView *thumbContainer=(UIView *)[cell.contentView viewWithTag:i];
UIImageView *imageView=[thumbContainer.subviews objectAtIndex:0];// this is where the app crashes.. thumbContainer no longer have a subview (for a specific row only)so it throws out an nsrangeexception
if (index<count)
{
//get file using the created indexpath
File *imageFile=[self.fetchedResultsController objectAtIndexPath:currentIndexPath];
//set image
imageView.image=[UIImage imageNamed:imageFile.thumbnail];
thumbContainer.backgroundColor=[UIColor grayColor];
//set tag for image view for the system to know what file is tapped
imageView.tag=(currentIndexPath.section*kImageTagMultiplier)+currentIndexPath.row;
//add tap gesture to thumbnail container view
UITapGestureRecognizer *tap=[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(resultTapped:)];
tap.numberOfTapsRequired=1;
[thumbContainer addGestureRecognizer:tap];
}
else {
imageView.image=[UIImage imageNamed:#""];
thumbContainer.backgroundColor=[UIColor clearColor];
for (UIGestureRecognizer *gest in thumbContainer.gestureRecognizers) {
[thumbContainer removeGestureRecognizer:gest];
}
}
return cell;
What I'm trying to do here is that I have an array of objects and each object is represented by a thumbnail image, i used a tableview to show these thumbnails.., for each row there is a fixed number of thumbnails. In the storyboard I have a cell that has 6 square views and each view has an imageview inside. The reason why i added a container view instead of just putting an imageview is that each thumbnails is tappable and i need to know what object is tapped by getting the tapgesture's view's(the container view) subview's(which is the imageview) tag.
By the way, I have put a comment where i encounter a crash
You should use the new iOS 6 UICollectionView as it is designed for things like this.
i want to customize table cell to show data like this (chk image)
For those rows which you want set color like above the simply set this color (shown in above pic) fo cell' background color.
or find this color use digital meter and use that rgb. like this
[UIColor colorWithRed:200.0/255 green:200.0/255 blue:200.0/255 alpha:1.0];
replace 200.0 with your rgb values
waht you need, you need to store data in common array for simply showing single detail you need to save that in form of string others in dictionary format.
And at time of showing data.
check wheter object is string or dictionary, and show accordingly.
for checking type of object use this
if([[myArray objectAtIndex:index] isKindOfClass:[NSString class]])
You can implement delegate method of viewForHeaderInSection: and implement view for yellow area shown in screenshot, and for for rest, you can implement custom table view cell inherited from UITableViewCell
You can subclass UITableViewCell.
In Xcode -> New File -> Objective-C class -> Subclass of UITableViewCell
Then in your tableview at cellForRowAtIndexPath:
static NSString *CellIdentifier = #"Cell";
MySubclassedTableviewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[MySubclassedTableviewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell...
return cell;
Use custom tableviewcell
In my application I parsed the data through NSXMLParser and made separate class to store that data from which i usually display the data. Everything works fine in simulator except the the title which is display in table cell with image. Images appears properly but the title not appear properly.
This is my code:-
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:#"TableCell3" owner:self options:NULL];
cell = nibLoadedCell;
}
NewsInfo *aNewsInfo = [appDelegate.newsArray objectAtIndex:indexPath.row];
titleLabel.text = aNewsInfo.title;
imageLabel.image = aNewsInfo.smallImageData;
return cell;
}
and in this way i configured my TableCell3.xib
Now i want my title data in 2 rows in label of the TableCell3.
I already used both the way through xib attributes settings or through code.
Code which i used instead of this xib attributes settings are:-
titleLabel.lineBreakMode = UILineBreakModeWordWrap;
titleLabel.numberOfLines = 2;
titleLabel.text = aNewsInfo.title;
Now Can any one help me to figure out this prob i want to display my title in two rows of the table view cell.
Thanks in Advance.
Just increase the height of your label and give a try. If the height is too less to hold 2 lines, the label will truncate the contents to 1 line and end with the ellipsis.
Shouldn't you be accessing them by
cell.titleLabel.text = sometest;
cell.imageLabel.image = someImage;
and also ensure that the titleLabel and imageLabel are connected properly to the outlets. And pls check your naming for the variables. imageLabel is not a good choice if you want that to be an imageview.
i'm using a default style table (UITableViewCellStyleSubtitle)
i want to add more then one detailTextLabel in each row,
how can i customize it?
code:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:CellIdentifier] autorelease];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
// Leave cells empty if there's no data yet
if (nodeCount > 0)
{
// Set up the cell...
ARecord *aRecord = [self.entries objectAtIndex:indexPath.row];
cell.textLabel.text = aRecord.lDate;
cell.detailTextLabel.text = aRecord.WNum;
// Only load cached images; defer new downloads until scrolling ends
//(!aRecord.appIcon) - use icon
if (!aRecord.appIcon)
{
if (self.tableView.dragging == NO && self.tableView.decelerating == NO)
{
[self startIconDownload:aRecord forIndexPath:indexPath];
}
// if a download is deferred or in progress, return a placeholder image
cell.imageView.image = [UIImage imageNamed:#"Placeholder.png"];
}
else
{
cell.imageView.image = aRecord.appIcon;
}
}
return cell;
}
The best way of doing this is to add a UILabel to the cell.contentView. You would do this when you initially create the cell. I've found two things to be especially helpful: to lay out the label on a table cell in a throwaway document in Interface Builder to determine the initial frame. It's also especially helpful to set the autoresizingMask so that the label will be resized appropriately when the cell is resized (due to autorotation, going into edit mode, etc.).
Finally, you'll need to set the table view's rowHeight to a higher value to accommodate the larger cells, otherwise you'll end up with overlapping cells.
Also, set a tag on your label to make it easy to retrieve with viewWithTag: when you go to update the text.
You could add the labels to cell.contentView.