images in tableview cells - iphone

Ive added a uiimageview as a subview to my cell.and then put a label on top of it so that it would seem like a button.But whwn the table is scrolled up or down the image seems to get painted again.This turns extremely ugly as my image has transparency effect which is lost as soon as it goes out of view and comes back.???

Ok, I'll try to guess what your code looks like :)
If images are painted multiple times that means you add them each time table view queries data source for a cell:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView #"SomeID"];
if (cell == nil) {
// Create cell
}
UIImageView *imView = ... //Create and initialize view
[cell.contentView addSubview:imView];
...
return cell;
}
So each time your cell appears on screen (after user scrolls the table) new instance of image view is added to the cell. The correct approach is to add image view only once - when cell is created and then obtain and setup the existing image view:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView #"SomeID"];
if (cell == nil) {
// Create cell
UIImageView *imView = ... //Create and initialize view
imView.tag = 1000; // or any other int value
[cell.contentView addSubview:imView];
}
UIImageView *iView = (UIImageView *)[cell.contentView viewWithTag:1000];
iView.image = ...// set required image
...
return cell;
}
So with this approach each time the cell is reused by table view the existing image view is populated with the image appropriate for the current row.
I used a seperate identifier for each cell.
Usually it is not a good idea - in this case table won't be able to reuse its cells and you may get serious performance troubles

Related

Modify existing reusable cells with cellForRowAtIndexPath: method

I use tableview with reusable cells. On each cell I have a textField with text, which I can modify. If text is empty, I delete that cell.
Lets say that we had 100 rows and we want to modify row number 1: we tap on it, give an empty string #"", scroll down to position number 50 and tap on this cell.
What now is going is that we detect tap gesture on another cell and I call method textFieldDidEndEditing: to see should I remove this cell from tableview. I use cellForRowAtIndexPath: to get the modified cell.
The problem is that there appear other cells with empty textField. I delete modified cell, but only one. I think that this is a problem with reusable cells.
Can anybody can help me with this problem?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *ImageIdentyfier = #"StandardCellWithImageIdentifier";
StandardCellWithImage *cellImage = (StandardCellWithImage *)[tableView dequeueReusableCellWithIdentifier:ImageIdentyfier];
if(cellImage == nil) {
cellImage = [[StandardCellWithImage alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ImageIdentyfier];
}
cellImage.nameLabel.delegate = self;
Item *item = [self.mutableFetchResults objectAtIndex:indexPath.row];
cellImage.nameLabel.text = item.itemText;
cellImage.infoLabel.text = item.itemInfo;
cellImage.checkbox.userInteractionEnabled = YES;
cellImage.nameLabel.userInteractionEnabled = NO;
if(item.itemIsChecked.boolValue == YES) {
cellImage.checkbox.tag = indexPath.row;
[cellImage.tapGesture addTarget:self action:#selector(didSelectedImageAtIndexPath:)];
cellImage.checkbox.image = [UIImage imageNamed:#"checkbox-checked.png"];
} else {
cellImage.checkbox.tag = indexPath.row;
[cellImage.tapGesture addTarget:self action:#selector(didSelectedImageAtIndexPath:)];
cellImage.checkbox.image = [UIImage imageNamed:#"open-checkbox.png"];
}
return cellImage;
}
When you scroll from row 1 to row 50, already existing cells are reused - including your cell with empty textField. That is why you see it several times and why your delete routine removed only one instead of all.
Sounds like your cell creation at cellForRowAtIndexPath method needs fixing to make sure empty textfield is not automatically copied to recycled cells. Without seeing any code, this exercise is left to you.
Looked at code, thanx. Could not see any "easy" fix, so proposing that you should avoid the problem. So instead of checking cell taps, maybe you should check list scrolling.
The problem you have exists only because cell, which was being edited, was recycled due user scrolling the list. Therefore remove the problem by a) don't let user to scroll while editing text or b) stop text edit when user starts scrolling.
when your textFieldDidEndEditing is invoked finish , you should check whether the text is "" if it is "" I think you should delete it from the dataSource and then reloadData
your - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath method should write like this :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
XXXXXXXCell *cell = [tableView dequeueReusableCellWithIdentifier: kIdentifier];
if (cell == nil) {
//Init cell, only init
}
//Setup the cells detail, such as the textField.text and so on
return cell;
}

Prototype cells different from dynamically created cells

I have created two types of prototype cells in storyboard. The dimension of one of them have been customized to accomodate UIButton object. However when the cells are created, they have the standard height. I can see the UIButton object but it gets truncated because of the cell height.
Why are the newly created cells different from the prototype cells?
The relevant section of the code is as follows:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell;
if(cell == nil)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"PictureSelectionCell"];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
pictureButtonProperty = (UIButton *) [cell viewWithTag:1];
}
}
Going forward, what are my options for creating the cell of the width (or dimensions) defined in the storyboard? Programmatically, I will be able to achieve this by creating a CGRect object with the specified dimensions and then create a cell using initWithFrame. However, I would like to avoid doing things manually.
Thanks for your response.
first of all you can always set it with code
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return YOUR_ROW_HEIGHT;
}
other way if you choose your UITableView if the storyboard, under the size inspector change the Row Height.

How to access the cell in tableview?

I am new to the iPhone development. I got stuck with a problem. I want a check box function implemented in my UITableView. But my UITableViewCells are custom cell which consist of image and 3 UILabels. I could bring a sub view to the table view so that check box image can placed and I am successful in that. But the problem comes is whenever I click on the image only the last cell check box get changed. I would like to access the cell which I've clicked.
I have tried this
UITableViewCell *cell = [self cellForRowAtIndexPath:indexPath]
But this crashes since cell is custom.
Can any one suggest me a good method to do that?
Instead of using
UITableViewCell *cell = [self cellForRowAtIndexPath:indexPath]
try using
YourCustomCell *cell = (YourCustomCell *)[self.tableView cellForRowAtIndexPath:indexPath];
Hope it helps
First of all you need to define a tag -
#pragma imageViewTag 1
then in your cellForRowAtIndexPath assign this tag to your image view
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
then you can access your image view any where with the help of this tag as -
UITableViewCell *cellView = (UITableViewCell*) [tblView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]];
UIImageView *imgView = (UIImageView*) [cellView viewWithTag:imageViewTag];
In your TableView DidSelect Delegate method
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
UIImageView *image = [cell.contentView viewWithTag:15];
//You should have set the tag value as 15 when creating the image in cell
//and you should have added to the cell contentview
}
If you cant able to get the cell then probably you wouldnt have used the reusable cell concept correctly. So post your entire cellforrowindex code.
If you are using the check kind of thing. Why dont you use the default disclosure indicator of tableview instead of your image.

how to cascade uitableview's width to its custom table view cell?

I have a certain sized UIView used as a container of a UITableView. I use a subclass of UITableViewCell in my table view.
The problem is that my custom table view cell can not get the proper width from the UITableVIew.
This is how I create the table view
categoryListView = [[UITableView alloc] initWithFrame:categoryListContainer.bounds style:(UITableViewStylePlain)];
This is how I create the custom table view cell.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView == categoryListView) {
static NSString *CellIdentifier = #"MenuCategoryListIdentifier";
MenuCategoryListCellView *cell = (MenuCategoryListCellView*) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
// create dynamically
cell = [[MenuCategoryListCellView alloc] initWithStyle:(UITableViewCellStyleDefault) reuseIdentifier:CellIdentifier];
}
....
I wish to be able to get the correct cell bounds to in my MenuCategoryListCellView's initWithStyle method to draw my UI controls. But I don't know how to pass the value down.
Help will be appreciated!
Leo
The system will send the layoutSubviews message to your cell when the cell is resized. Override that method to lay out the UI controls according to the cell's current size.

Hierarchical UITableview

In my first view I have a UITableView with 5 records. In UITableView cells are holding two different components. One UILabel is text and another UILabel shows value for that cell.
On selection of this UITableViewCell user is navigated to another view where I have given a picker controller for changing the value of 2nd label in the table view for the selected row. I reload the UITableView data on -viewWillAppear but this overlaps the text on lables as many times I visit it.
Can anyone give me relevant example of hierarchical tableview where UItableViewCell's right section is dependant on selection of picker from next view.
I think you are adding the labels on cell.contentView everytime you reload the table, but are not removing the previous ones. Thats why the overlapping is happening.
try to remove the lables
- (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];
}
for (UIView * view in cell.contentView.subviews) {
[view removeFromSuperview];
view = nil;
}
// add your labels
}