Foo
Foo

Reputation: 606

UITableViewCell in combination with UIButton and visualization issue

I am trying to create a star button in my tableviewCells, so the user can save the favorite items.

I've tried this so far.

- (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];        
    }

    UIButton *CameraBreak=[UIButton buttonWithType:UIButtonTypeRoundedRect];
    CameraBreak.frame=CGRectMake(260, 10, 60, 40);
    CameraBreak.tag=indexPath.row;
    [CameraBreak setImage:[UIImage imageNamed:@"first.png"] forState:UIControlStateNormal];

    [CameraBreak addTarget:self action:@selector(starClicked::) forControlEvents:UIControlEventTouchUpInside]; 
    [cell.contentView addSubview:CameraBreak];  

    cell.textLabel.text = [titles objectAtIndex:indexPath.row];
    cell.textLabel.font = [UIFont fontWithName:@"Helvetica" size:15];   

    return cell;
}

The issue is that the buttons on viewDidLoad looks like this: VIEWDIDLOAD

But once I scoll the table it buttons changes like this: ON SCROLL

Does anybody know the reason for this behavior? And how I can solve this?

UPDATE

Not selected: enter image description here

Selected: enter image description here

Upvotes: 0

Views: 139

Answers (3)

Lorenzo B
Lorenzo B

Reputation: 33428

Why don't you just use accessoryView property of UITableViewCell class.

// create your button here...    
[cell setAccessoryView:cameraBreak]; // or cell.accessoryView = cameraBreak;

Also, rename CameraBreak into cameraBreak. You should use camelCaseNotation.

Let me know if this works.

Edit

Is this way also useful for the following idea: if (Accessory selected) {show yellowstar.png } else (show graystar.png)

You can change the imageView property of UITableViewCell.

cell.imageView = // set the correct image

It's really simple to achieve this. Follow how to set a tableview delegate. In particular you should take a look at - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath; protocol method.

Upvotes: 1

danh
danh

Reputation: 62676

What you see is the result of many many buttons being added to each cell, one over the next. All of that button creation code should happen inside the cell==nil condition. That way it occurs on new cells only, not reused cells:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];


    UIButton *CameraBreak=[UIButton buttonWithType: UIButtonTypeCustom];
    CameraBreak.frame=CGRectMake(260, 10, 60, 40);
    CameraBreak.tag=indexPath.row;
    [CameraBreak setImage:[UIImage imageNamed:@"first.png"] forState:UIControlStateNormal];

    [CameraBreak addTarget:self action:@selector(starClicked:) forControlEvents:UIControlEventTouchUpInside]; 
    [cell.contentView addSubview:CameraBreak];
}

// configure the parts of the cell here that vary based on indexPath

Upvotes: 0

Nishant Tyagi
Nishant Tyagi

Reputation: 9913

Change UIButton type Custom in place of roundRect and you are adding buttons everytime you reload your table. So add all this code in braces where you are allocating your cell, so that they can be reused (not allocated repeatedly).

Replace this code

if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];

}
UIButton *CameraBreak=[UIButton buttonWithType:UIButtonTypeRoundedRect];               
CameraBreak.frame=CGRectMake(260, 10, 60, 40);
CameraBreak.tag=indexPath.row;
[CameraBreak setImage:[UIImage imageNamed:@"first.png"] forState:UIControlStateNormal];

[CameraBreak addTarget:self action:@selector(starClicked::) forControlEvents:UIControlEventTouchUpInside]; 
[cell.contentView addSubview:CameraBreak];

as

if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
UIButton *CameraBreak=[UIButton buttonWithType:UIButtonTypeCustom];        

CameraBreak.frame=CGRectMake(260, 10, 60, 40);
CameraBreak.tag=indexPath.row;
[CameraBreak setImage:[UIImage imageNamed:@"first.png"] forState:UIControlStateNormal];

[CameraBreak addTarget:self action:@selector(starClicked::)    forControlEvents:UIControlEventTouchUpInside]; 
[cell.contentView addSubview:CameraBreak];

}

It will display properly.

Hope it helps you.

Upvotes: 0

Related Questions