I have a UITableView and a UITableCell subclass. Each table cell has two scrollviews that each rotate a dynamic amount of labels, which are created in my table cell implementation. I have poor scrolling performance and I believe it is from memory leaks. I'm referencing this stackoverflow correct answer to fix my problem: cellForRowAtIndexPath memory management.
I can't figure out how to tweak my code so I don't have to allocate memory every time I create labels.
ViewController.m
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Custom Cell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSDictionary *dictionary = [parseDataArray objectAtIndex: indexPath.row];
NSArray *popularLinkTitleArray = [dictionary objectForKey:#"popularLinkTitleArray"];
NSString *soundCloudLink = [dictionary objectForKey:#"soundCloudLink"];
NSArray *soundCloudTrackTitleArray = [dictionary objectForKey:#"soundCloudTrackTitleArray"];
cell.artistNameLabel.text = artistName;
[cell createPopularLinkLabels: popularLinkTitleArray];
return cell;
}
CustomCell.m
- (void)layoutScrollLabelsForPopularLinkScrollView: (float)arrayCount
{
UIView *view = nil;
NSArray *subviews = [popularLinkScrollView subviews];
// reposition all image subviews in a horizontal serial fashion
CGFloat curXLoc = 0;
for (view in subviews)
{
if ([view isKindOfClass:[UILabel class]] && view.tag >= 0)
{
CGRect frame = view.frame;
frame.origin = CGPointMake(curXLoc, 0);
view.frame = frame;
curXLoc += (kScrollObjWidth);
}
}
[popularLinkScrollView setContentSize:CGSizeMake((arrayCount * kScrollObjWidth), [popularLinkScrollView bounds].size.height)];
}
-(void) createPopularLinkLabels:(NSArray *) popularLinkTitleArray
{
popularLinkScrollView.clipsToBounds = YES;
kScrollObjHeight = popularLinkScrollView.frame.size.height;
kScrollObjWidth = popularLinkScrollView.frame.size.width;
for (UIView* subView in popularLinkScrollView.subviews)
[subView removeFromSuperview];
NSUInteger i;
for (i = 0; i < popularLinkTitleArray.count; i++)
{
NSString *string = [NSString stringWithFormat:#"%#", [popularLinkTitleArray objectAtIndex: i]];
UILabel *label = [[UILabel alloc] init];
label.text = [NSString stringWithFormat:#"%#", string];
label.backgroundColor = [UIColor clearColor];
label.numberOfLines = 5;
[label setFont:[UIFont fontWithName:#"Calibri" size:18]];
// setup each frame to a default height and width, it will be properly placed when we call "updateScrollList"
CGRect rect = label.frame;
rect.size.height = kScrollObjHeight;
rect.size.width = kScrollObjWidth;
label.frame = rect;
label.tag = i; // tag our images for later use when we place them in serial fashion
[popularLinkScrollView addSubview:label];
}
[self layoutScrollLabelsForPopularLinkScrollView:popularLinkTitleArray.count];
}
Are you using ARC? If not, you should autorelease to
cell = [[[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]
Cell objects are reused and you do not need to re-add subviews each time you change the contents. Just change the data and update the label frames if needed.
If you have distinctly different cells, consider using separate custom cell classes. You will need to use a separate value for the reuseIdentifier.
Also consider not creating a custom cell but just adding elements to the standard UITableViewCell. Read this about styling a cell.
The first thing you could do is try to reuse UILabels in createPopularLinkLabels. Right now, you are just removing them before adding more.
But if the number of popular links is not the same in all the cells, then you will have to remove the remaining ones or hide them and there will be no way to avoid memory allocations.
A better solution would be to insert a custom UIView inside your scroll view and draw all the texts manually instead of creating tons of subviews.
Hope this helps,
Thomas
Related
I am experiencing performance problems when using some subviews on my UITableViewCells. After I keep scrolling it eventually starts getting very slow.
First step I am doing is creating a common UIView for every cell, essentially this is creating a white cell with a rounded effect on the cell with a shadow. The performance for this seems to be normal so I don't think it's the culprit.
Here is the code I am using to do this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *NewsCellIdentifer = #"NewsCellIdentifier";
NewsItem *item = [self.newsArray objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NewsCellIdentifer];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:NewsCellIdentifer];
cell.contentView.backgroundColor = [UIColor clearColor];
UIView *whiteRoundedCornerView = [[UIView alloc] initWithFrame:CGRectMake(10,10,300,100)];
whiteRoundedCornerView.backgroundColor = [UIColor whiteColor];
whiteRoundedCornerView.layer.masksToBounds = NO;
whiteRoundedCornerView.layer.cornerRadius = 3.0;
whiteRoundedCornerView.layer.shadowOffset = CGSizeMake(-1, 1);
whiteRoundedCornerView.layer.shadowOpacity = 0.5;
[cell.contentView addSubview:whiteRoundedCornerView];
[cell.contentView sendSubviewToBack:whiteRoundedCornerView];
cell.layer.shouldRasterize = YES;
cell.layer.rasterizationScale = [UIScreen mainScreen].scale;
cell.layer.opaque = YES;
cell.opaque = YES;
}
[cell.contentView addSubview:[self NewsItemThumbnailView:item]];
return cell;
}
Here is the method that returns the thumbnail view of the graphic and text:
- (UIView *) NewsItemThumbnailView:(NewsItem *)item
{
UIView *thumbNailMainView = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 50, 70)];
UIImageView *thumbNail = [[UIImageView alloc] initWithImage:[UIImage imageNamed:item.ThumbNailFileName]];
thumbNail.frame = CGRectMake(10,10, 45, 45);
UILabel *date = [[UILabel alloc] init];
date.frame = CGRectMake(10, 53, 45, 12);
date.text = item.ShortDateString;
date.textAlignment = NSTextAlignmentCenter;
date.textColor = [BVColors WebDarkGrey];
CGFloat fontSize = 10.0;
date.font = [BVFont Museo:&fontSize];
date.opaque = YES;
thumbNail.opaque = YES;
thumbNailMainView.opaque = YES;
[thumbNailMainView addSubview:thumbNail];
[thumbNailMainView addSubview:date];
return thumbNailMainView;
}
The performance problem seems to be when I add the thumbnail view to the cell because when I comment that line out, I don't seem to have it. The thumbnail information is dynamic and will change with each cell. I would appreciate any advice on how I should do this without degrading the performance.
UITableView will call tableView:cellForRowAtIndexPath: each time a cell comes into view, and dequeueReusableCellWithIdentifier: will reuse existing cell objects if they are available. These two facts combine to put you in a scenario where every time you scroll, the same finite number of cell objects end up with an increasing number of subviews.
The proper approach is to create a custom UITableViewCell subclass that has a property for thumbnailView. In the setter for that property, remove the previous thumbnail (if any) and then add the new one to the contentView. This ensures that you'll only ever have one thumbnail subview at any time.
A less optimal approach would be adding a tag to the UIView returned from NewsItemThumbnailView (thumbNailMainView.tag = someIntegerConstant) and then searching for any view with that tag and removing it before adding another:
// remove old view
UIView *oldThumbnailView = [cell.contentView viewWithTag:someIntegerConstant];
[oldThumbnailView removeFromSuperview];
// add new view
[cell.contentView addSubview:[self NewsItemThumbnailView:item]];
I ended up leveraging a solution found on this stackoverflow post:
How should I addSubview to cell.contentView?
Essentially when the cell is first initialized I am setting the view as mentioned by Nishant; however once the cell is reused I am extracting out the items I need to change, such as an UIImageView and then a UILabel. Since these are pointers I can modify just what I need when I need to and the performance is fast again. Here is a abbreviated version of what I did.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *NewsCellIdentifer = #"NewsCellIdentifier";
NewsItem *item = [self.newsArray objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NewsCellIdentifer];
UIView *thumbNailMainView = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 50, 70)];
UIImageView *thumbNail;
UIView *textMainView = [[UIView alloc] initWithFrame:CGRectMake(20,20,80,80)];
UILabel *headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(52,-5, 70, 20)];
UILabel *teaserLabel = [[UILabel alloc] initWithFrame:CGRectMake(50,20, 210, 40)];
UIView *newsItemCornerMainView = [[UIView alloc] initWithFrame:CGRectMake(255.7, 55.2, 55, 55)];
UIImageView *cornerIconView;
// If the cell doesn't existing go ahead and make it fresh.
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:NewsCellIdentifer];
// Configure all the various subviews
..... //Sample below
// Make the title view
headerLabel.text = item.Title;
CGFloat textfontSize = 16.0f;
headerLabel.font = [BVFont Museo:&textfontSize];
headerLabel.textColor = [BVColors WebBlue];
headerLabel.textAlignment = NSTextAlignmentLeft;
headerLabel.numberOfLines = 0;
headerLabel.tag = 50;
// Make the Teaser view
teaserLabel.text = item.Teaser;
teaserLabel.numberOfLines = 0;
CGFloat tfontSize = 13.0f;
teaserLabel.textAlignment = NSTextAlignmentLeft;
teaserLabel.textColor = [BVColors WebDarkGrey];
teaserLabel.font = [BVFont HelveticaNeue:&tfontSize];
[teaserLabel sizeToFit];
teaserLabel.tag = 51;
[textMainView addSubview:headerLabel];
[textMainView sendSubviewToBack:headerLabel];
[textMainView addSubview:teaserLabel];
[cell.contentView addSubview:textMainView];
....
}
thumbNail = (UIImageView *) [cell viewWithTag:47];
[thumbNail setImage:[UIImage imageNamed:item.ThumbNailFileName]];
headerLabel = (UILabel *) [cell viewWithTag:50];
headerLabel.text = item.Title;
teaserLabel = (UILabel *) [cell viewWithTag:51];
teaserLabel.text = item.Teaser;
cornerIconView = (UIImageView *) [cell viewWithTag:48];
[cornerIconView setImage:[UIImage imageNamed:item.CornerIconFileName]];
return cell;
}
You should change thumbNailMainView content only everytime but you should not add its content on cell everytime.
So add this line where you are allocating cell
[cell.contentView addSubview:[self NewsItemThumbnailView:item]];
add this inside braces. and then access thumbNailMainView from cell and pass that item data which you need to change for each cell.
Assign a tag to thumbNailMainView and its subview thumbNail then access it as
UIView *_thumbNailMainView = [cell.contentView viewWithTag:_thumbNailMainView_tag];
UIImageView *_thumbNail = [_thumbNailMainView viewWithTag:thumbNail_tag];
_thumbNail.image = [UIImage imageNamed:item.ThumbNailFileName];
Hope it helps you.
I have a custom cell designed with a scrollview and a pageview control, which I am displaying as follows
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString * CellIdentifier = #"ScrollViewCell";
cell = (ScrollViewCell*)[newsTable dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
NSArray * customcellArray = [[NSBundle mainBundle]loadNibNamed:#"ScrollViewCell" owner:self options:nil];
for(id customcellObject in customcellArray){
if([customcellObject isKindOfClass: [UITableViewCell class]]){
cell = (ScrollViewCell *)customcellObject;
break;
}
}
}
// Customize your UIScrollView here..
[cell.scrollView setDelegate:self];
[cell.scrollView setPagingEnabled:YES];
scrollView = cell.scrollView;
pageControl = cell.pageControl;
cell.backgroundColor = [UIColor grayColor];
NSArray *colors = [NSArray arrayWithObjects:[UIColor redColor], [UIColor greenColor],[UIColor blueColor], nil];
cell.scrollView.contentSize = CGSizeMake(cell.scrollView.frame.size.width * colors.count,cell.scrollView.frame.size.height);
for (int i = 0; i < colors.count; i++) {
CGRect frame;
frame.origin.x = cell.scrollView.frame.size.width * i;
frame.origin.y = 0;
frame.size = cell.scrollView.frame.size;
UIView *subview = [[UIView alloc] initWithFrame:frame];
subview.backgroundColor = [colors objectAtIndex:i];
[cell.scrollView addSubview:subview];
}
// Configure the cell...
UIView* bgview = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1, 1)];
bgview.opaque = YES;
bgview.backgroundColor = [UIColor grayColor];
[cell setBackgroundView:bgview];
return cell;
}
The scrollview appears and scrolls just fine in cell , but problem is page control doesnt update with the scroll, basically I want to update the page control on scroll of scrollview but since page control and scrollview both are from cell I am not getting how to achieve this, I tried implementing UIScrollViewDelegate protocol with cell and then the parent view of table view but couldnt get it working, pleas guide.
Thanks
Vishal
Don't place your UIPageControll over UIScrollview in your custom cell, if it is then it will get scroll along UIScrollView itself.So create your Custom cell like this and make outlet for each UIScrollview & UIPageControll,
One change in your cellForRowAtIndexPath
// Customize your UIScrollView here..
[cell.scrollView setDelegate:self];
[cell.scrollView setPagingEnabled:YES];
[cell.scrollView setTag:indexPath.row]; // set indexpath.row as tag for cell.scrollview
NSArray * colors = [NSArray arrayWithObjects:[UIColor redColor], [UIColor greenColor],[UIColor blueColor],nil];
cell.pageControll.numberOfPages = [colors count];
And in,
- (void)scrollViewDidScroll:(UIScrollView *)sender {
CGFloat xOffset = sender.contentOffset.x;
CGFloat frameWidth = sender.frame.size.width;
int page = floor((xOffset - frameWidth / 2) / frameWidth) + 1;
GroupButtonCell * cell = (GroupButtonCell*)[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:sender.tag inSection:0]]; // get appropriate cell based on scrollview tag (sender.tag).
cell.pageControll.currentPage = page; // assigning to pagecontroll
}
Hope this will help..
I am writing a geometry based app. At one point in the app, there will be a UITableView with some custom cells. These cells contain UILabels. Amid the text of some these labels, I want to insert symbols that look these two triangles:
(source: wiley.com)
However, since I cannot find these symbols in any Apple fonts, is there a way to insert an image into the string in place of a symbol?
Here is a (very) rough idea of what I'm going for (the actual table will not be static):
Ok, I get what you're trying to do. The key, I think, is to just keep adding controls to your cell, calculating the width as you go along.
First, I'd suggest a data structure to hold your cell contents. A simple array will do the job. I generally do this stuff as an ivar:
#interface LabelWithImagesViewController ()
{
NSMutableArray *_cells;
}
#end
Then fill this array with the text and images you want. I'm doing a single row, but you can repeat for every row you need.
- (void)viewDidLoad
{
[super viewDidLoad];
_cells = [[NSMutableArray alloc] init];
[_cells addObject:[[NSArray alloc] initWithObjects:
[UIImage imageNamed:#"triangle.png"],
#"CAT",
[UIImage imageNamed:#"semiequal.png"],
[UIImage imageNamed:#"triangle.png"],
#"DOG",
#" If",
[UIImage imageNamed:#"triangle1.png"],
#"then",
[UIImage imageNamed:#"triangle2.png"],
nil]];
}
And then, you need to create your cell:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return _cells.count;
}
#define kEquationTag 100
#define kCellHeight 44
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"equationCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UIView *equationContainer;
if (cell == nil)
{
// if we don't have a cell create it, including the frame to hold our custom stuff
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
equationContainer = [[UIView alloc] initWithFrame:cell.contentView.bounds];
equationContainer.tag = kEquationTag;
[cell.contentView addSubview:equationContainer];
}
else
{
// if we are dequeing one that already exists, let's get rid of the old custom stuff
equationContainer = [cell.contentView viewWithTag:kEquationTag];
for (UIView *view in equationContainer.subviews)
{
[view removeFromSuperview];
}
}
// Configure the cell...
NSArray *cellContents = [_cells objectAtIndex:indexPath.row];
NSUInteger x = 0;
UIFont *font = [UIFont systemFontOfSize:12.0];
for (NSObject *obj in cellContents)
{
if ([obj isKindOfClass:[NSString class]])
{
NSString *text = (NSString *)obj;
CGSize size = [text sizeWithFont:font];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(x, (kCellHeight - size.height)/2.0, size.width, size.height)];
label.text = text;
label.font = font;
[equationContainer addSubview:label];
x += size.width;
}
else if ([obj isKindOfClass:[UIImage class]])
{
UIImage *image = (UIImage *)obj;
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(x, (kCellHeight - image.size.height) / 2.0, image.size.width, image.size.height)];
imageView.image = image;
[equationContainer addSubview:imageView];
x += image.size.width;
}
}
return cell;
}
This yields:
Make a UILabel and use instances of that UILabel for each letter.
Use some geometry logic about the rect of the image view to place the letters regardless of size...such as
UILabel *aLetterLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 35, 35)];
aLetterLabel.text = #"A";
//centered top
aLetterLabel.frame = CGRectMake((shapeImage.frame.origin.x + (shapeImage.frame.size.width/2)), shapeImage.frame.origin.y, 35, 35);
//centered
aLetterLabel.frame = CGRectMake((shapeImage.frame.origin.x + (shapeImage.frame.size.width/2)), (shapeImage.frame.origin.y + (shapeImage.frame.size.height/2)), 35, 35);
//cenetered bottom
aLetterLabel.frame = CGRectMake((shapeImage.frame.origin.x + (shapeImage.frame.size.width/2)), (shapeImage.frame.origin.y+(shapeImage.frame.size.height-35)), 35, 35);
//left center align
aLetterLabel.frame = CGRectMake(shapeImage.frame.origin.x, (shapeImage.frame.origin.y + (shapeImage.frame.size.height/2)), 35, 35);
Wrote these up really fast as a proof of concept...feel free to revise, etc.
You can create your own font with the exact symbols you need. Try this:
http://glyphdesigner.71squared.com
You can't insert an image in a UILabel.
But you can add a UIImageView in the custom cells of your UITableView and then put a UIImage inside.
I'm trying to implement a UIScrollView in each cell of `UITableView'. I wrote my code based on Apple's custom Scrollview project: https://developer.apple.com/library/ios/#samplecode/Scrolling/Listings/ReadMe_txt.html
Each table cell's UIScrollView scrolls through a set of labels, which are initialized in the cellForRowAtIndexPath method. Each label's text is set after initialization to equal a string from an array.
Everything works correctly until I scroll down to the 4th table cell. The UIScrollView in this cell has the same exact labels as the first cell. The same first 3 set of labels or the first 3 scrollViews keep repeating after the first 3 cells. The strange part is, when I log the label.text after it is set, the output shows the correct label.text of what should be displaying in the respective cell.
- (void)layoutScrollLabels: (float)arrayCount
{
UIView *view = nil;
NSArray *subviews = [cell.popularLinkScrollView subviews];
// reposition all image subviews in a horizontal serial fashion
CGFloat curXLoc = 0;
for (view in subviews)
{
if ([view isKindOfClass:[UILabel class]] && view.tag >= 0)
{
CGRect frame = view.frame;
frame.origin = CGPointMake(curXLoc, 0);
view.frame = frame;
curXLoc += (kScrollObjWidth);
}
}
[cell.popularLinkScrollView setContentSize:CGSizeMake((arrayCount * kScrollObjWidth), [cell.popularLinkScrollView bounds].size.height)];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Custom Cell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSDictionary *dictionary = [parseDataArray objectAtIndex:indexPath.row];
NSArray *popularLinkTitleArray = [dictionary objectForKey:#"popularLinkTitleArray"];
cell.popularLinkScrollView.clipsToBounds = YES;
kScrollObjHeight = cell.popularLinkScrollView.frame.size.height;
kScrollObjWidth = cell.popularLinkScrollView.frame.size.width;
NSUInteger i;
for (i = 0; i < popularLinkTitleArray.count; i++)
{
NSString *string = [NSString stringWithFormat:#"%#", [popularLinkTitleArray objectAtIndex: i]];
UILabel *label = [[UILabel alloc] init];
label.text = [NSString stringWithFormat:#"%#", string];
label.backgroundColor = [UIColor clearColor];
label.numberOfLines = 5;
NSLog(#"%#", label.text);
// setup each frame to a default height and width, it will be properly placed when we call "updateScrollList"
CGRect rect = label.frame;
rect.size.height = kScrollObjHeight;
rect.size.width = kScrollObjWidth;
label.frame = rect;
label.tag = i; // tag our images for later use when we place them in serial fashion
[cell.popularLinkScrollView addSubview:label];
}
[self layoutScrollLabels:popularLinkTitleArray.count];
}
return cell;
}
You should not add label as a subview to popularLinkScrollView in cellForRowAtIndexPath. If the count of labels is required to be dynamic, try this code before your for loop in cellForRowAtIndexPath.
for (UIView* subView in cell.popularLinkScrollView.subviews)
[subView removeFromSuperview];
Okay I am just totally too close to this I think. I have a tableview. In that table view everything is working except section 2 row 0.
AND -- before anyone asks...I know I am not using the *imgWordView (in the code below) and that is why the icons are not showing but i do not know where to add it to the subview so i can place it at coordinates in the cell... :)
// 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) {
if (indexPath.section == 2 && indexPath.row == 0)
{
cell = [self getCellContentViewForIconRow:CellIdentifier];
cell.backgroundColor = [UIColor grayColor];
}
else
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
}
}
The above code (except for my addition of of my section == 2 && indexPath.row == 0) is normal and generic..
getCellContentViewForIconRow is defined here:
- (UITableViewCell *) getCellContentViewForIconRow:(NSString *)cellIdentifier {
ResortsListViewController *resortsListViewController = [[ResortsListViewController alloc] init];
NSMutableArray *categoryArray = [resortsListViewController getCategoriesForLocation:[[locationData objectForKey:#"theid"]intValue]];
[resortsListViewController release];
CGRect CellFrame = CGRectMake(0, 0, 260, 60);
UITableViewCell *cell = [[[UITableViewCell alloc] initWithFrame:CellFrame reuseIdentifier:cellIdentifier] autorelease];
cell.contentView.backgroundColor = [UIColor grayColor];
int x = 10;
int y = 10;
for (NSMutableDictionary *cat_object in categoryArray) {
CGRect Label1Frame = CGRectMake(x, y, x + 40, 40);
UILabel *lblTemp = [[UILabel alloc] initWithFrame:Label1Frame];
lblTemp.tag = x + 1;
NSString *filePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"alcohol.png"];
UIImage *imgWord = [[[UIImage alloc] initWithContentsOfFile:filePath] autorelease];
UIImageView *imgWordView = [[[UIImageView alloc] initWithImage:imgWord] autorelease];
[cell.contentView addSubview:lblTemp];
[lblTemp release];
x = x + 30;
}
return cell;
}
Okay, so
ResortsListViewController *resortsListViewController = [[ResortsListViewController alloc] init];
NSMutableArray *categoryArray = [resortsListViewController getCategoriesForLocation:[[locationData objectForKey:#"theid"]intValue]];
[resortsListViewController release];
gets back a group of categories that I would use to build the filenames for the PNG images. Everything is okay so far. Then I am looping through the array to build the places for the images in the cell.
I am expecting no more than 5 images...at 30x30 each. so, to test, I just used the filename "alcohol.png" which exists. I want all 5 images to be displayed in a row inside the cell
I already do this:
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 2 && indexPath.row == 0)
{
return 60;
}
}
But, all I see is my table cell (in gray like it is supposed to be) with a LONG white box inside it.
So, two questions.
1: The box (i am assuming it is the CGRect CellFrame = CGRectMake(0, 0, 260, 60);) in white. I need to know how to change that to gray...just like my cell background.
The big reason is that my icons are white...and i cannot tell if the icons are visible or not.
If the only problem is that this white CGRECT is hiding my icons, then all is well.
Otherwise we come to #2:
2: Is this the best way to put a group of icons within a cell row when the icon names are inside an array?
If not, how?
So, How do i make the CGRect gray & how do i get the 5 icons to appear horizontally in the cell?
Thanks in advance for your help!
The big long white box is your labels you are making and adding to the contentView. The UILabels are opaque with a white background. Do the following:
lblTemp.backgroundColor = [UIColor clearColor];
This will get rid of the white box so you can see what is behind your labels.
The other issue is that you you are adding your x + 40 on every iteration of your loop. I would think you would want the width to be a constant value and not adding your X coord + 40 each time, this will end up making a pretty wide set of labels across your cell.
Okay, found out how to do this elegantly and with a flair. I am voting for #bstahlhood's answer as the answer as it is partially what I needed to know..however, this subroutine in place of the one I submitted above is how I fully fixed it.
- (UITableViewCell *) getCellContentViewForIconRow:(NSString *)cellIdentifier {
ResortsListViewController *resortsListViewController = [[ResortsListViewController alloc] init];
NSMutableArray *categoryArray = [resortsListViewController getCategoriesForLocation:[[locationData objectForKey:#"theid"]intValue]];
[resortsListViewController release];
MainAppDelegate *mainAppDelegate = [[MainAppDelegate alloc] init];
CGRect CellFrame = CGRectMake(10, 10, 100, 40);
UITableViewCell *cell = [[[UITableViewCell alloc] initWithFrame:CellFrame reuseIdentifier:cellIdentifier] autorelease];
int x = 10;
int y = 10;
int ctr = 0;
NSFileManager *fileManager = [NSFileManager defaultManager];
for (NSString *category_name in categoryArray) {
if (ctr <= 7)
{
BOOL valid_for_user = [mainAppDelegate validate_category_for_users_level:category_name];
if (valid_for_user)
{
NSMutableString *subt = [[[NSMutableString alloc]init]autorelease];
[subt appendString: category_name];
[subt appendString: #".png"];
NSString *filePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:[NSString stringWithString:subt]];
BOOL success = [fileManager fileExistsAtPath:filePath];
if (success)
{
UIImage *imgWord = [[[UIImage alloc] initWithContentsOfFile:filePath] autorelease];
UIImageView *imgWordView = [[[UIImageView alloc] initWithImage:imgWord] autorelease];
CGRect Label1Frame = CGRectMake(x, y, 30, 30);
UILabel *lblTemp = [[UILabel alloc] initWithFrame:Label1Frame];
lblTemp.tag = x + 1;
// BEGIN FIX TO MY PROBLEM: thanks #bstahlhood
lblTemp.backgroundColor = [UIColor clearColor];
// END FIX TO MY PROBLEM
[lblTemp addSubview:imgWordView];
[cell.contentView addSubview:lblTemp];
[lblTemp release];
x = x + 40;
ctr += 1;
}
}
}
}
[mainAppDelegate release];
return cell;
}
As you see I also changed the CGRECT inside my loop to fix the horizontal spacing:
CGRect Label1Frame = CGRectMake(x, y, 30, 30);
as #bstahlhood suggested. I had forgotten CGRrect commands handle the startpoints and width instead of startpoints and endpoints inside the cell area. that is why I thought I had to use x+40. As stated, it is now corrected.
I also changed this the heightForRowAtIndexPath to better balance the look of a 30x30 pixel image. The label above starts my subview 10px across and 10px down from the inside of the cell, so it just makes sense to ensure that the cell is 50px vertically and not 60px so there is exactly 10px on top and 10px on bottom of the icon.
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 2 && indexPath.row == 0)
{
return 50;
}
}
So, even though I solved my own problem prior to the posting by #bstahlhood, I am giving him the vote for the correct answer as it was correct. I also wanted to point out that I wish more people would post fixed code after their issue was corrected so that others having the same issue would know what (exactly) they did. That is why I posted this code.