简体   繁体   中英

How to change the background image of UITableView cell on a button click

In my UITableViewCell i have a UIButton and a label which is been dynamically added to the cell. I have a background image for the cell too so when this button gets clicked i want either the background of the cell to get replace with another image or i want the text color of the label to change to something else like gray or blue.

Is that possible?

Here's the code for ny cellForRowAtIndexPath :

- (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];
        NSArray *subviews = cell.contentView.subviews;
        for (UIView *vw in subviews)
        {
            if ([vw isKindOfClass:[UILabel class]])
            {
                [vw removeFromSuperview];
            }
        }

    NSArray * temp;
    NSData * imageData;
    if (dataToDisplay!=nil) {
        temp = [dataToDisplay objectAtIndex:indexPath.row];
        imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString: [temp objectAtIndex:4]]];
    }


    playButtonImage = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"music_player_play_button.png"]];
    pauseButtonImage = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"music_player_pause_button.png"]];

   UIButton* preview = [UIButton buttonWithType:UIButtonTypeCustom];
    preview.tag = 100 + indexPath.row;
    [preview addTarget:self
               action:@selector(playPreview:)
     forControlEvents:UIControlEventTouchUpInside];
    preview.backgroundColor = [UIColor clearColor];
    preview.frame = CGRectMake(11,6, 36, 35);
        [preview setBackgroundImage:playButtonImage.image forState:UIControlStateNormal];
    [cell addSubview:preview];

    UILabel * songName = [[UILabel alloc]initWithFrame:CGRectMake(60,15, 150, 15)];
    songName.tag = 100+indexPath.row;
    songName.text = [temp objectAtIndex:5];
    songName.font = [UIFont boldSystemFontOfSize:12];
    songName.backgroundColor = [UIColor clearColor];
    [cell addSubview:songName];

   UIButton * buy = [UIButton buttonWithType:UIButtonTypeCustom];
    [buy addTarget:self
                action:@selector(buySong:)
      forControlEvents:UIControlEventTouchUpInside];
        [buy setImage:[UIImage imageNamed:@"button_buy.png"] forState:UIControlStateNormal];
    buy.tag = 200 + indexPath.row;
    [buy setTitle:@"Buy" forState:UIControlStateNormal];
    buy.titleLabel.font = [UIFont boldSystemFontOfSize:8.0];
    buy.frame = CGRectMake(255,9,41, 30);
    [cell addSubview:buy];
    songsResults.tableHeaderView = headerView;
        UIImage * cellIcon;
    if (indexPath.row==[dataToDisplay count]-1) {
        cellIcon = [UIImage imageNamed:[cellViewImages objectAtIndex:1]];
    }
    else {
        cellIcon = [UIImage imageNamed:[cellViewImages objectAtIndex:0]];
    }
        cell.backgroundView = [[UIImageView alloc]initWithImage:cellIcon];

        cell.clipsToBounds = YES;

    }
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    return cell;
}

Using the tag as an identifier of the cell whose button was pressed. That way you can determine which cell you need to change:

-(void)buySong:(id)sender {
  UIButton *buttonPressed = (UIButton*)sender;
  NSUInteger rowSelected = buttonPressed.tag - 200;
  NSIndexPath *indexPath = [NSIndexPath indexPathForRow:rowSelected inSection:0];
  CustomTableViewCell *cellSelected = (CustomTableViewCell)[self.tableView cellForRowAtIndexPath:indexPath];
  cellSelected.label.textColor = [UIColor redColor];
}

You should subclass UITableViewCell so you can add new attributes to it and access them later on, like I did with CustomTableViewCell .

Here is a tutorial on how to create a custom UITableViewCell .

Cheers

I'd make a subclass of UITableViewCell that has its own action method to receive the button click, and use a block to handle that click so that your controller code could look something like this:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    SongCell *cell = [tableView dequeueReusableCellWithIdentifier:[SongCell identifier]];
    if (cell == nil) {
        cell = [[SongCell alloc] init];        
    }
    cell.songData = [dataToDisplay objectAtIndex:indexPath.row];
    cell.onPreviewClick =
    ^
    (SongCell *cell)
    {
        cell.isPlaying = YES;
        [self playSongAtIndexPath:indexPath]; // method to start the preview
    };
    return cell
}

To support this, your UITableViewCell subclass would look something like this:

// SongCell.h
@interface SongCell : UITableViewCell
@property (nonatomic, strong) NSArray *songData; // NSDictionary would be better
@property (nonatomic, copy) void(^onPreviewClick)(SongCell *cell);
@property (nonatomic, assign) BOOL isPlaying;
+ (NSString *)identifier;
@end

with this implementation:

// SongCell.m
#import "SongCell.h"
@interface SongData()
@property (nonatomic, strong) NSArray *_songData;
@property (nonatomic, assign) BOOL _isPlaying;
@property (nonatomic, strong) UIButton *playImage;
@property (nonatomic, strong) UIButton *pauseImage;
@property (nonatomic, strong) UIButton *previewButton;
@property (nonatomic, strong) UILabel *songNameLabel;
- (void)previewButtonPressed:(UIButton *)button;
@end

@implementation SongCell
@synthesize onPreviewClick, _songData, _isPlaying, playImage, pauseImage, previewButton, songNameLabel;

- (id)init {
    if ((self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:[SongCell identifier]])) {
        self.selectionStyle = UITableViewCellSelectionStyleNone;

        self.playImage = [UIImage imageNamed:@"music_player_play_button.png"];
        self.pauseImage = [UIImage imageNamed:@"music_player_pause_button.png"];
        self.previewButton = [UIButton buttonWithType:UIButtonTypeCustom];
        previewButton.frame = CGRectMake(11,6, 36, 35);
        [previewButton addTarget:self
                          action:@selector(previewButtonPressed:)
                forControlEvents:UIControlEventTouchUpInside];
        [self addSubview:previewButton];

        self.songNameLabel = [[UILabel alloc]initWithFrame:CGRectMake(60,15, 150, 15)];
        songNameLabel.font = [UIFont boldSystemFontOfSize:12];
        [self addSubview:songNameLabel];
    }
    return self;
}

+ (NSString *)identifier {
    return @"SongCell";
}

- (void)setSongData:(NSArray *)songData
{
    self._songData = songData;
    [self updateSubviews];
}

- (NSArray *)songData {
    return _songData;
}

- (void)setIsPlaying:(BOOL)isPlaying {
    self._isPlaying = isPlaying;
    [self updateSubviews];
}

- (BOOL)isPlaying {
    return _isPlaying;
}

- (void)previewButtonPressed:(UIButton *)button {
    if (onPreviewClick) onPreviewClick(self);
}

- (void)updateSubviews {
    if (_isPlaying) {
        [previewButton setBackgroundImage:pauseImage forState:UIControlStateNormal];
    }
    else {
        [previewButton setBackgroundImage:playImage forState:UIControlStateNormal];
    }
    songNameLabel.text = [_songData objectAtIndex:5];
}

@end

Caveat: I didn't test this. Hopefully it doesn't have too many errors.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM