I have a UITableView that gets information from a server and publishes the data into a table view. Inside of each cell is the information from the server.
For the purpose of this example, let's say the information we get from the server are numbers: 1, 2, 3, 4.
What I want to do is add an image (programmatically because there are if statements involved, etc) to the left side of the cell, and the text (1, 2, etc) right next to it.
Basically, I want each cell to look like this:
_____________________________________
| (IMAGE) (TEXT) | --CELL 0
--------------------------------------
_____________________________________
| (IMAGE) 2 | --CELL 1
--------------------------------------
Please excuse my crude illustration. :)
here you go:
cell.imageView.image = [UIImage imageNamed:#"image.png"];
Swift:
cell.imageView?.image = UIImage(named: "image.png")
You can add both the image and the text to the UITableViewCell in your UITableViewController subclass like so:
- (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] autorelease];
}
[[cell imageView] setImage:anImage];
[[cell textLabel] setText:[NSString stringWithFormat:#"%d",[indexPath row]];
return cell;
}
There are a few "built-in" properties to UITableViewCell that you can take advantage of, such as the imageView, textLabel, and detailTextLabel. For more information, check out the Table View Programming Guide.
The Swift 2.0 version of the first answer is:
cell.imageView?.image = UIImage(named: "image.png")
UITableViewCell objects have an imageView property; you can just set this image view's image and it will automatically display the image in the right place with the title next to it.
// create a rectangle box for image view
UIImageView *iconImage = [[UIImageView alloc] init];
iconImage.frame = CGRectMake(12,4,53.5,53.5);
// Create a label for cells
UILabel *cellName = [[UILabel alloc] initWithFrame:CGRectMake(75,18,200,20)];
cellName.font = [self fontForBodyTextStyle];
NSString *cellNameStr = [NSString stringWithFormat:#"%#",self.tableCellNames[indexPath.row]];
// Select path row tab actions
switch (indexPath.row) {
case 0:
cellName.text = cellNameStr;
iconImage.image = [UIImage imageNamed:#"condition.png"];
[cell.contentView addSubview:iconImage];
[cell.contentView addSubview:cellName];
break;
case 1:
cellName.text = cellNameStr;
iconImage.image = [UIImage imageNamed:#"videos.png"];
[cell.contentView addSubview:iconImage];
[cell.contentView addSubview:cellName];
break;
case 2:
cellName.text = cellNameStr;
iconImage.image = [UIImage imageNamed:#"provider.png"];
[cell.contentView addSubview:iconImage];
[cell.contentView addSubview:cellName];
break;
case 3:
cellName.text = cellNameStr;
iconImage.image = [UIImage imageNamed:#"info.png"];
[cell.contentView addSubview:iconImage];
[cell.contentView addSubview:cellName];
break;
default:
NSAssert(NO, #"Unhandled value in cellForRowAtIndexPath");
break;
}
Related
Can we set Background image for UITableView Section like UITableViewCell backGroundView. As per my research Its not possible & we need to customize the row like section of it.
Cane we able to get better solution apart from this.
Thanks in advance!
In case anyone are still interrested, there is actually a pretty straigt forward solution to this. UITableView will tell you the frames of each of your sections using the selector rectForSection:
Adding a backgroud image to each section would then look something like this (Somewhere in the view controller):
for(int i = 0;i < [self numberOfSectionsInTableView:self.tableView]; i++) {
UIImage *img = [[UIImage imageNamed:#"background"] resizableImageWithCapInsets:UIEdgeInsetsMake(30.0, 30.0, 40.0, 40.0) ]; //In this example the image is stretchable
UIView *borderView = [[UIImageView alloc] initWithImage:img];
CGRect section_rect = [self.tableView rectForSection:i];
borderView.frame = section_rect;
[self.tableView addSubview:borderView];
}
Just remember that if you reload the data in the tableview you would have to redo this as well.
Yes, I am doing this by following way, I think it work for you also,....
-(void)addBackgroundViewForSectionIndex:(int)tagIndex {
for (UIView * subview in tableView.subviews) {
if(subview.tag == tagIndex)
[subview removeFromSuperview];
}
CGRect sectionFrame = [tableView rectForSection:tagIndex];
UIImageView *newView = [[UIImageView alloc]initWithFrame:sectionFrame];
newView.tag = tagIndex;
[newView setImage:[UIImage imageNamed:#"image.PNG"]];
[tableView addSubview:newView];
[tableView sendSubviewToBack:newView];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView1 cellForRowAtIndexPath: (NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView1 dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [collection objectAtIndex:indexPath.row];
[self addBackgroundViewForSectionIndex:indexPath.section];
return cell;
}
Let me know if any issue,...:)
No, this is not possible using UITableView as it was intended. Section headers, as others have suggested, won't work because they'll only be visible while the header is visible. As soon as it disappears while scrolling up, the background image would disappear.
Your two options are:
Add UIImageView instances directly as subviews to the table view. Not fun, as you'll have to size and position them manually, which is kind of hard to do.
Use UICollectionView, which supports decoration views (exactly what you're looking for).
The UICollectionView method is probably better, but to be honest, either option would require a lot of work.
Swift 5 bare-bones implementation of Jesper's answer.
for sectionIndex in 0..<tableView.numberOfSections {
let backgroundView = UIView() // replace UIView with anything else you want, whether it was UIImage, nibView, etc...
backgroundView.frame = tableView.rect(forSection: sectionIndex)
tableView.addSubview(backgroundView)
}
You can set the Background for Section of TableView.
Have a look at delegate method as below:
- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIImageView *bgImgView = [[[UIImageView alloc] initWithFrame:CGRectMake(0.0,0.0,tableView.bounds.size.width,40.0)] autorelease];
bgImgView.image = [UIImage imageNamed:#"yourimage.jpg"];
return bgImgView;
}
Hope this will be helpful to you.
Cheers!
table= [[UITableView alloc] initWithFrame:CGRectMake(7,0, 307, 124) style:UITableViewStylePlain];
[table setSeparatorStyle:UITableViewCellSeparatorStyleNone];
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"tablebg_pt12.png"]];
imageView.frame=CGRectMake(0, 0, 307, 124);
imageView.image= [UIImage imageNamed:#"tablebg_pt12.png" ];
table.backgroundView = imageView;
[imageView release];
table.delegate = self;
table.dataSource = self;
// table.backgroundColor=[UIColor clearColor];
[viewTable addSubview:table];
I am new to iPhone devlopemnt I am developing one app. In that app I need show list items with their respective prices in an UITableView. To solve this problem I am following some concept like creating label dynamically in UITableViewCell to show the items and their prices.
In app the first indexid == 1 means that I am showing list places on click of particular cell on list am geting list of favorite items with prices that means indexid = 2 ...on click of back button indexid = 1 then i need hide that label ...but label is not hideing it show list prices not list of items
lblText.text = nil;
btnBack.hidden = FALSE;
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.textLabel.font = [UIFont boldSystemFontOfSize:14.0];
cell.textLabel.highlightedTextColor = [UIColor orangeColor];
}
///////////////////// Cell Title /////////////////////
if (indexId == 1)
{
// NSLog(#"%#",lblText1);
cell.textLabel.text = [NSString stringWithFormat:#"%#", [test.arrTitle objectAtIndex:indexPath.row]];
lblText = [[UILabel alloc] initWithFrame:CGRectMake(250, 7, 40, 30)]; // For right alignment
lblText.text = [test.arrId objectAtIndex:indexPath.row];
[lblText setTextAlignment:UITextAlignmentCenter];
lblText.textColor = [UIColor redColor];
lblText.backgroundColor = [UIColor clearColor];
[cell addSubview:lblText];
cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"products-category-bg.png"]];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
[lblText release];
}
else
{
lblText.hidden = YES;
cell.textLabel.text = [NSString stringWithFormat:#" %#", [test.arrTitle objectAtIndex:indexPath.row]];
cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"product-bg-hover.png"]];
}
return cell;
}
I have the following problem. The label is creating ok, but after on click of back button, I get label values in main tableview.
How can I release the label object with data ?
thanks & regards
Please help me out of this problem
Your code looks fine to me, just replace one line in above code with the link written below
[cell.contentView addSubview:lblText];
Instead
[cell addSubview:lblText];
Hope It will resolve your issue.
If you're using the same table view instance for the different states in your application you're also re-using cells that were created previously:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
With each cell, when the indexid == 1 you're also doing this:
[cell addSubview:lblText];
To me, this says that each cell you've created (and that will be re-used) has a UILabel added as a subview. To truly re-use that cell you need to remove that UILabel before your logic says that you need to add it again. Not only will this remove the cells when you don't need them, it will also prevent you from adding extra UILabel instances to the cell at runtime. Try adding the code below before you check indexid
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.textLabel.font = [UIFont boldSystemFontOfSize:14.0];
cell.textLabel.highlightedTextColor = [UIColor orangeColor];
}
// Be sure to remove the UILabels on the re-used cell.
for(UIView *view in cell.subviews)
if ([view isKindOfClass:([UILabel class])])
[view removeFromSuperview];
if (indexid == 1) { ....
This will remove the UILabel each time the cell is created allowing you to conditionally re-added it as a subview.
Try to set a tag to your label(will help you to set data to labels, you can get the label by calling
[cell viewWithTag:theLabelTag]
where theLabelTag tag can be the index)
and set the label value in
tableView: willDisplayCell: forRowAtIndexPath:
instead of
tableView: cellForRowAtIndexPath:
I have the following code
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UIImage * i1 = [UIImage imageNamed: #"inc_01.png"];
UIImage * i2 = [UIImage imageNamed: #"inc_02.png"];
UIImage * i3 = [UIImage imageNamed: #"inc_04.png"];
UIImage * i5 = [UIImage imageNamed: #"inc_05.png"];
UIImage * i6 = [UIImage imageNamed: #"inc_06.png"];
UIImage * i7 = [UIImage imageNamed: #"inchd.png"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if(indexPath.row == 0)
{
UIImageView * header= [[UIImageView alloc] initWithImage: i1];
cell.backgroundView = header;
// Configure the cell…
}
else if (indexPath.row == 2)
{
UIImageView *backgroundCellImage=[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 280, 11)];
backgroundCellImage.image=[UIImage imageNamed:#"inc_06.png"];
[cell.contentView addSubview:backgroundCellImage];
}
else
{
// Configure the cell…
UIImageView *imageView = [[UIImageView alloc] initWithImage: i3];
cell.textLabel.text = #"text";
UIImageView *backgroundCellImage=[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 57, 46)];
backgroundCellImage.image=[UIImage imageNamed:#"inc_02.png"];
UIImageView *backgroundCellImage2=[[UIImageView alloc] initWithFrame:CGRectMake(223, 0, 57, 46)];
backgroundCellImage2.image=[UIImage imageNamed:#"inc_04.png"];
UILabel * label = [[UILabel alloc] initWithFrame:CGRectMake(57, 0, 166, 46)];
label.text = #"wow";
[cell.contentView addSubview:backgroundCellImage];
[cell.contentView addSubview:backgroundCellImage2];
[cell.contentView addSubview:label];
}
return cell;
}
that basically creates a table view and puts an image to the left and right of each cell. I want it so that people can click on the left or right image in each cell, and something different happens based on the cell number.
So if they click on the left image for cell in row 1, a function gets call with the row number they clicked on, and an indicator telling me they clicked on the left image and not the right image.
How can I do that using objective-c?
Make a custom prototype cell as follows
---------------------------------------
| Button 1 | Text | Button 2 |
---------------------------------------
Call different methods for both the buttons.
Alternatively, you can have a look at this official documentation which explains cells in detail
Add right image as an accessory view and left image as an editing control
this is a noob question.i subclassed my table view cell in interface builder and created a table view.what i want is to change the color of the textlabel to UITableViewCellStyleValue1 color(light blue).since i created the cell in .nib file.i m not able to use cell.detailtextlabel.text.could u guys help me out.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[NSBundle mainBundle] loadNibNamed:#"CCell" owner:self options:nil] objectAtIndex:0];
}
UILabel *lbl=(UILabel*)[cell viewWithTag:1];
UIImageView *imgV = (UIImageView*)[cell viewWithTag:2];
UILabel *label=(UILabel*)[cell viewWithTag:3];
NSDictionary *dToAccess = [self.listOfItems objectAtIndex:indexPath.row];
[lbl setText:[dToAccess valueForKey:#"title"]];
NSUInteger intVal = [[dToAccess valueForKey:#"rating"] integerValue];
switch (intVal) {
case 0:
[imgV setImage:[UIImage imageNamed:#"0star.png"]];
[label setText:#"Snitt 0"];
label.textColor=[UIColor blueColor];
break;
case 1:
[imgV setImage:[UIImage imageNamed:#"1star.png"]];
[label setText:#"Snitt 1"];
break;
case 2:
[imgV setImage:[UIImage imageNamed:#"2star.png"]];
[label setText:#"Snitt 2"];
break;
case 3:
[imgV setImage:[UIImage imageNamed:#"3star.png"]];
[label setText:#"Snitt 3"];
break;
case 4:
[imgV setImage:[UIImage imageNamed:#"4star.png"]];
[label setText:#"Snitt 4"];
break;
case 5:
[imgV setImage:[UIImage imageNamed:#"5star.png"]];
[label setText:#"Snitt 5"];
break;
default:
break;
}
CGSize size = [lbl.text sizeWithFont:[UIFont boldSystemFontOfSize:16] forWidth:205 lineBreakMode:UILineBreakModeCharacterWrap];
[lbl setFrame:CGRectMake(5, 0, size.width, 43)];
[imgV setFrame:CGRectMake(5+size.width+5, 4, 118, 36)];
return cell;
}
You can get the detail label cell color for UITableViewCellStyleValue1 by doing:
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:#"resuse"];
UIColor *lightBlueColor = cell.detailTextLabel.textColor;
which can be broken down into it's RGB values and alpha by doing:
const float* colors = CGColorGetComponents( lightBlueColor.CGColor );
It's up to you if you want to hardcode the values in code or just compute it every time. I'd say hardcode would be better.
The trick is getting hold of the label on which to set the color. If you've rolled your own cell, a quick thing to do is give your label a tag value in the nib, (look for it along with the other view properties of your label).
Then when you're configuring the cell, get the label like this:
UILabel *label = (UILabel *)[cell viewWithTag:16]; // 16 is a unique in the view, non-zero int that you make up yourself
label.textColor = [UIColor redColor];
The alternative is to connect outlets from your nib to properties on a custom cell, but tags might be a simpler way to start out.
I'm trying to use my ReusableCell for cells with images in different dimensions. The images are put inside a 220x150 black box with with scaling UIViewContentModeScaleAspectFit.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"NewsTableViewCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NewsItem *item = [self.fetchedResultsController objectAtIndexPath:indexPath];
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:item.imageUrl]];
[cell.imageView setImage:[[UIImage alloc] initWithData:data]];
[cell.imageView setBackgroundColor:[UIColor blackColor]];
[cell.imageView setContentMode:UIViewContentModeScaleAspectFit];
CGRect imageViewFrame = cell.imageView.frame;
imageViewFrame.size.width = 220;
imageViewFrame.size.height = 150
[cell.imageView setFrame:imageViewFrame];
[cell.textLabel setText:item.title];
return cell;
}
The above code results in a layout like below and the images are sometimes changing when scrolling in the table view.
Instead of this unstructured layout, I would like the images to be aligned like this:
What am I doing wrong with this ReusableCell?
EDIT1:
I'm trying to create an imageView and add this imageView as a superview to cell.contentView.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"NewsTableViewCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NewsItem *item = [self.fetchedResultsController objectAtIndexPath:indexPath];
UIImage *placeholderImage = [UIImage imageNamed:#"ImagePlaceholderThumb"]; //220x150
UIImageView *imageView = [[UIImageView alloc] initWithImage:placeholderImage];
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:item.imageUrl]];
[imageView setImage:[[UIImage alloc] initWithData:data]];
[imageView setBackgroundColor:[UIColor blackColor]];
[imageView setContentMode:UIViewContentModeScaleAspectFit];
CGRect imageViewFrame = imageView.frame;
imageViewFrame.size.width = placeholderImage.size.width;
imageViewFrame.size.height = placeholderImage.size.height;
[imageView setFrame:imageViewFrame];
[cell.contentView addSubview:imageView];
[cell.textLabel setText:item.title];
return cell;
}
The above code results in the following:
It is like some of the images are visible in two cells. It seems that they are not keeping the size I've set in the imageViewFrame. Do you know why?
A quick fix would be using content mode UIViewContentModeScaleAspectFill. Images will be stretched in one or both dimensions to fill up the whole image view bounds.
You really need subclassing UITableViewCell to do this right.
Thre is a lazy solution adding a new UIImageView and using a spacer, as Keller told you in his answer (feel free to accept his answer, this is just the missing code).
Extract of tableView:cellForRowAtIndexPath::
...
cell.textLabel.text = [NSString stringWithFormat:#"Cell #%i", indexPath.row];
cell.imageView.image = [UIImage imageNamed:#"spacer.png"]; /* spacer is 64 x 44 */
/* image view width should be ~ 64 px, otherwise it will overlap the text */
UIImageView *iv = [[UIImageView alloc] initWithFrame:(CGRect){.size={64, tableView.rowHeight}}];
switch (indexPath.row) {
case 0:
iv.image = [UIImage imageNamed:#"waterfall.png"];
break;
/* etc... */
}
if (indexPath.row < 3) {
/* add black bg to cell w/ images */
iv.backgroundColor = [UIColor blackColor];
}
iv.contentMode = UIViewContentModeScaleAspectFit;
[cell.contentView addSubview:iv];
...
The table will look like this:
You need to set the placeholder (spacer.png above) in the existing cell image view. It will push the text label to the right.
You can use aspect fill and remove the background color bit:
iv.contentMode = UIViewContentModeScaleAspectFill;
The table will look wrong because the image is drawn outsite the bounds:
Just clip to bounds to get a better result:
iv.clipsToBounds = YES;
Create a UIImageView subview for each cell and it to the contentView. Each UIImageView contains an image with a consistent frame but with option UIViewContentModeScaleAspectFit. Then just Set the background color of the UIImageView to black.
I just confirmed this works, but you need to also create a placeholder spacer image to make sure the textLabel moves out of the way. Just make it the same dimensions of your image (with the letter boxing).
- (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];
//spacer
cell.imageView.image = [UIImage imageNamed:#"placeholder"];
//imageview
UIImageView *thumbnail = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 80, 44)];
thumbnail.tag = kThumbTag;
thumbnail.backgroundColor = [UIColor blackColor];
thumbnail.contentMode = UIViewContentModeScaleAspectFit;
[cell.contentView addSubview:thumbnail];
}
// Configure the cell...
cell.textLabel.text = [NSString stringWithFormat:#"Cell %d", indexPath.row];
cell.imageView.frame = CGRectMake(0, 0, 80, 44);
UIImageView *thumb = (UIImageView*)[cell.contentView viewWithTag:kThumbTag];
if (indexPath.row == 0) {
[thumb setImage:[UIImage imageNamed:#"image1.png"]];
} else {
[thumb setImage:[UIImage imageNamed:#"image2.png"]];
}
return cell;
}
Obviously, this example isn't lazy loading the images (I didn't realize you were loading them from a URL). For that, I would use a subclass with EGOImageView or something of the like.