i have the following code which will displays result in a UItable view along with an image.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//create a cell
UITableViewCell *cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:#"cell"];
// fill it with contnets
NSDictionary *exercise = [exercises objectAtIndex:indexPath.row];
cell.textLabel.text = [exercise valueForKey:#"player"];
UIImage *image = [UIImage imageNamed:#"iphone.gif"];
cell.imageView.image = image;
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
// return it
return cell;
}
is there an option where i can display one image for all the cells for ex. 1 image on the left side and then 3 rows by the right side. I am a new bid and still getting my grip on iPhone coding.Please suggest me how we can do this.Thanks.
Yup, a UITableViewCell is pretty much another UIView, so you can add subviews to it and customize it anyway you need. For example, if you need to add an image to all the cells, just add it onto the contentView;
[cell.contentView addSubview:myImageView];
If you have several customizations needed for your cell, and are looking for a highly custom look as opposed to the generic look provided by the standard cells, I'd recommend looking into creating a custom UITableViewCell. The reason is that the standard cells have already laid out UI's with labels, images etc, and anything you add onto it may interfere with the existing UI in ways you do not intend.
Related
In my application i need to display multiple images in a UITableView,so i've already searched a lot in the web for the proper way to load large images to UITableViewCells,to be more clearly i'll divide the procedure that my app execute:
Download images asynchronous;
Save them to NSHomeDirectory();
=> Thins part is working perfectly.
The problem is,how to display the images in the UITableViewCell,i've already tried to add UIImageView's to the cell contentView but the scrolling performance were a bit affected,i've searched on Apple guides and i believe the correct way is adding UIImageView's to the cell and loading the images from NSHomeDirectory(),so:
What's the best way to customize a UITableViewCell and add the UIImageView's(302x302px) to it?
To get the best scroll performance, you must draw the content of the UITableViewCell yourself.
Loren Brichter, the author of the Tweetie app (now the official Twitter app), wrote a very famous blog post on this. Sadly, this blog post has been deleted.
This article may help you, though. It explains the fast scrolling, it has examples and it has a video to a presentation from Loren Brichter.
Basically, what you want to do is to subclass UITableViewCell and override the drawRect:method. To show an image, you would do something like the following:
- (void)drawRect:(CGRect)rect
{
[myImage drawAtPoint:CGPointMake(10, 10)];
}
This way you avoid to layout a lot of subviews.
I have the same question.
I'm doing the following:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString* CustomCellIdentifier = #"CustomCellIdentifier";
CustomCell* cell = [tableView dequeueReusableCellWithIdentifier:CustomCellIdentifier];
if (cell == nil) {
cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CustomCellIdentifier];
}
// add subview to cell
if (cell.customView == NULL) {
cell.customView = [[CustomView alloc] initWithFrame:cell.frame];
[cell.contentView addSubview:cell.customView];
}
// bind cell data
return cell;
}
Firstly, you need to create a custom cells for UITableView & keep going through following points.
set height of each row to 302 pixels as
-(CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 302.0;
}
Use following code to create UIImageView at each cell of table
-(UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:#"cell"];
const NSInteger IMAGE_VIEW_TAG=1001;
UIImageView *imageView;
if(cell==nil)
{
cell=[[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"] autorelease];
cell.accessoryType=UITableViewCellAccessoryDisclosureIndicator;
imageView =[[[UIImageView alloc] initWithFrame:CGRectMake(10, 0, 302, 302)] autorelease];
imageView.tag=IMAGE_VIEW_TAG;
imageView.contentMode=UIViewContentModeScaleAspectFit;
[cell.contentView addSubview:imageView];
}
imageView=(UIImageView*)[cell.contentView viewWithTag:IMAGE_VIEW_TAG];
[imageView setImage:[UIImage imageNamed:#"image.png"];
return cell;
}
set number of rows you want to display
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 5;
}
dont forget to add TableView delegate and data source , UITableViewDelegate and UITableViewDataSource
This is driving me absolutely insane.
I have a UITableView with cells populated via an NSFetchedResultsController that should have their background color set based upon one of the Core Data parameters.
This table view is in the master view of a UISplitViewController and the selected cell needs to remain visibly selected to indicate what is being displayed in the detail view.
Based upon guidance from several other Stack Overflow questions, I have learned that the ideal place to configure the cell is during the willDisplayCell delegate call, like this:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
WorkTask *workTask = (WorkTask*) [self.fetchedResultsController objectAtIndexPath:indexPath];
if ([workTask.strStatus isEqualToString:#"A"]) {
cell.backgroundColor = [self colorWithHexString:#"fffdcf"];
// cell.textLabel.backgroundColor = [self colorWithHexString:#"fffdcf"];
// cell.detailTextLabel.backgroundColor = [self colorWithHexString:#"fffdcf"];
} else if ([workTask.strStatus isEqualToString:#"B"]) {
cell.backgroundColor = [self colorWithHexString:#"cfffd1"];
// cell.textLabel.backgroundColor = [self colorWithHexString:#"cfffd1"];
// cell.detailTextLabel.backgroundColor = [self colorWithHexString:#"cfffd1"];
} else if ([workTask.strStatus isEqualToString:#"C"]) {
cell.backgroundColor = [self colorWithHexString:#"ffcfcf"];
// cell.textLabel.backgroundColor = [self colorWithHexString:#"ffcfcf"];
// cell.detailTextLabel.backgroundColor = [self colorWithHexString:#"ffcfcf"];
} else {
cell.backgroundColor = [self colorWithHexString:#"ffffff"];
// cell.backgroundColor = cell.contentView.backgroundColor;
}
This mostly sort of works. But...
Depending on how I play around with different variants of accomplishing this, I end up with the background color being ignored sometimes (and only sometimes?!?) behind the textLabel and detailTextLabel. Or causing the cell to display incorrectly while selected. Or having the checkmark indicator displayed without a background color. Or having new items added to the core data database showing up in the table, but with the no background color for the cell, but the text labels having a background color.
No matter what I do, I have not found a simple and intuitive way to make things behave overall as expected - particularly when cells are being programmatically selected.
In fact - the cell selection seems like it might be at the root of the problem. The selected cell is usually the one that ends up drawn incorrectly after I change the selection to another, particularly if the color of the cell changed while the cell was selected.
Is there any example out there anywhere of how this is supposed to work?!?!
Thanks!
If I were you I would create a UITableViewCell subclass with your own titleLabel/subtitleLabel UILabels in it and stop using the textLabel/detailTextLabel. In the xib file you can just change the background color of the labels and of the cell. I have never had the sort of problem you are experiencing when I have used custom cells as opposed to the default cells.
Here's an example of how to load a UITableViewCell from an xib:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:#"CustomCell"];
if (cell == nil) {
// Load the top-level objects from the custom cell XIB.
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
// Grab a pointer to the first object (presumably the custom cell, as that's all the XIB should contain).
cell = [topLevelObjects objectAtIndex:0];
}
cell.titleLabel.text = #"whatever";
cell.subtitleLabel.text = #"whatever";
return cell;
}
You could also try setting the background color of the cell's contentView.
cell.contentView.backgroundColor = ...;
If you really can't figure it out, then in a UITableViewCell subclass you could always just put a UIView of your own in the background of the cell and change the background color of that view instead.
willDisplayCell:forRowAtIndexPath: might not get called after insertRowsAtIndexPaths: is called (i.e. when you add items into core data w/ a fetchedresultscontroller). If absolutely necessary maybe you should try setting the background color of the cell and it's contentView in both cellForRowAtIndexPath: and willDisplayCell:forRowAtIndexPath:.
For some bizarre reason the background color of UITableViewCell objects can only be set just before the cell is drawn. In your UITableView's delegate implement this method:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
Set the background color of the cell there and it will draw the way you want.
I want to make a table view in which i want to show some items or images ( 4 items in a row)For eg: If i have 7 images i want to show 4 in first row and 3 in next row and if i have 13 images then it should display like 4,4,4,1 in rows 1,2,3,4 respectively. I have achievd this but my problem is those images keep changing their position (shift from 1 to 3 row and vice versa) when i scroll the table view. Please tell me some way so that my images automatically adjust themselves 4 in a row and does not repeat if i scroll the table view.
My code is:
(array has 7 image-datas stored in it)
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 93;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [array count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Avi"];
for (UIView *view in cell.contentView.subviews) {
[view removeFromSuperview];
}
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Avi"] autorelease];
cell.backgroundColor = [UIColor clearColor];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
NSData *imageData;
for(int i=0;i<4;i++){
imageData=[array objectAtIndex:indexpath.row];
UIButton *Button = [UIButton buttonWithType:UIButtonTypeCustom];
Button.frame = CGRectMake(5+(i*77), 5, 77,85);
[Button setBackgroundImage:[UIImage imageWithData:imageData] forState:UIControlStateNormal];
[cell.contentView addSubview:Button];
}
return cell;
So the code snippet you've posted isn't particularly helpful, but this almost certainly is a case of not recycling your table view cells properly.
Table views 'recycle' their cells for efficiency and performance - when a cell scrolls out of view it is marked for recycling: when you next request a new cell you will be given a recycled cell if one is available (otherwise a new cell will be created).
If all your cells use the same layout, this isn't a problem. However, if you adjust the layout of your cells (as you do) this can cause problems, because you might have set up a cell for 2-picture layout and have it be recycled for a 4-picture cell.
You have two options here: either take care to reset your cells as required (when you request a new cell reset all the view parameters you've created, which in your case would be by removing all the superviews), or create different cells with different identifiers for each of your layouts.
By the way, just looking at your current code it seems like you may want to consider some custom cells. Currently you add new images to the cell's contents view, which means since you never remove them every time your cell gets recycled more and more and more images get added! It's quite inefficient. Better to create a cell that has four image views ready to go, and you just assign the image property as required.
I have a table cell to which I'm adding subviews programmatically. All the textual subviews work fine, but I can't get an image subview working at all.
You'll notice that I set the background color to black. This is simply to indicate to me that the subview is indeed being initialized and positioned properly within the cell. When I remove the background color there is nothing there.
Also, the cell style is UITableViewCellStyleDefault but I don't think that's pertinent for custom subviews. I want the image positioned on the right, which is why I'm not using the standard imageView property that cells offer.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
// ... add textual views ...
UIImageView *img = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"clock.png"]];
img.frame = CGRectMake(271.0f, 10.0f, 19.0f, 22.0f);
img.backgroundColor = [UIColor blackColor];
[cell addSubview:img];
}
// ... more code ...
return cell;
}
Your code looks fine to an extent. One issue I had when I was creating my own UITableViewCells in code was I was creating the cells with variables like you are but you shouldn't do this.
What you should do is create the cell and then set the variables. If cells are different you should use different reuse identifiers. Hope this makes sense if not let me know and I'll update.
How do i change the location of the text AND show the FULL string in UITableView?
Here is a screen shot of what I have, once you look at it you will know what I mean. Thanks
My App http://img188.imageshack.us/img188/9926/chucknhelp.tif
You can do it without subclassing UITableViewCell.
In the method tableView:cellForRowAtIndexPath:, create a basic UITableViewCell and change the properties of the UILabel contained in this cell. Change the maximum number of lines to fit more text in your cell.
Unfortunately, the label of the cell is not accessible by properties, so you need to fetch it with the subviews property.
Of course this uses an implementation detail of UITableViewCell, so it might break with future releases of the SDK. Use with care.
Here is an example:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:#"YourCellId"];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:#"YourCellId"] autorelease];
cell.font = [UIFont systemFontOfSize:16];
UILabel* cellLabel = [cell.contentView.subviews objectAtIndex:0];
[cellLabel setNumberOfLines:3];
}
cell.text = #"Your text";
return cell;
}
Update:
To set the row height to fit the text, you can do the following:
1. Set the cell height to fit the text.
You need something like this:
CGSize textSize = [text sizeWithFont:font
constrainedToSize:CGSizeMake(313, 1000)
lineBreakMode:UILineBreakModeWordWrap];
cell.frame = CGRectMake(0.0f, 0.0f, 320.0, textSize.height);
2. Return the cell height in the tableView:heightForRowAtIndexPath: method.
For example like this:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell* cell = [self tableView:(UITableView*)self.view cellForRowAtIndexPath:indexPath];
CGRect cellFrame = cell.frame;
return cellFrame.size.height;
}
Subclass UITableViewCell, and in the subclass's loadView method, create a UILabel inside its contentView. Set this label to have the appropriate wrapping and location.
Adam has it right. For a little more detail (as well as a method that scrolls lightning fast) you can check out this entry on atebits.com that bypasses the UILabel approach entirely.
Loren Brichter's UITableViewCell subclassing example
You can also look at the TableViewSuite example from developer.apple.com It contains 5 different examples, in increasing complexity, for building custom TableViews. The last example is structurally very similar to the tutorial on atebits.com.
Lecture 8 of the Stanford iPhone course is also all about Scroll and TableViews, and has some examples of subclassing UITableViewCell.
iPhone Course