如何在UITableView的选定单元格中设置图像

我想知道如何在UITableView Selected cell行中设置图像。

如果我select第一个单元格,图像应显示在第一个单元格中,稍后当我select第二个单元格时,图像应仅显示在第二个单元格中( 而不是第一个单元格中

基本上,图像应该只显示在选定的单元格中。

最简洁的方法将是UITableViewCell的子类。


 #import <UIKit/UIKit.h> @interface SongCell : UITableViewCell @property (nonatomic, assign) BOOL isPlaying; @end 

 @interface SongCell () @property (nonatomic, strong) UIImage *speakerImage; @end @implementation SongCell -(void)layoutSubviews { if (!_speakerImage) { // http://commons.wikimedia.org/wiki/File:Speaker_Icon.svg self.speakerImage = [UIImage imageNamed:@"speaker_icon.png"]; } if(!self.isPlaying){ self.imageView.image = nil; } else { self.imageView.image = _speakerImage; self.imageView.hidden =NO; } [super layoutSubviews]; } - (void)setSelected:(BOOL)selected animated:(BOOL)animated { [super setSelected:selected animated:animated]; if (!selected) { self.isPlaying = NO; } } -(void)setIsPlaying:(BOOL)isPlaying { _isPlaying = isPlaying; [self setNeedsLayout]; } @end 

UITableViews数据源和委托实现

 -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return 20; } -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *identifier = @"SongCell"; SongCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath]; return cell; } -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { SongCell *cell =(SongCell *)[tableView cellForRowAtIndexPath:indexPath] ; cell.isPlaying = !cell.isPlaying; } 

我为你准备了一个演示项目。 你会在GitHub上find它

 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath { [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; [UIView animateWithDuration:2.0f animations:^{ [imageView setHidden:NO]; } completion:^(BOOL finished) { ; }]; } 

你想为imageView切换types的性质。

 - (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]; } [cell.imageView setImage: [UIImage imageNamed:@""]]; return cell; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { //refresh all cells //basically call cellForRowAtIndexPath to reset all cells [tableView reloadSections:indexPath.section withRowAnimation:UITableViewRowAnimationFade]; //get cell for the currently selected row UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; //set image [cell.imageView setImage: [UIImage imageNamed:@"loudspeaker.png"]]; } 

但这只是一个视觉方面。
如果您select第一行并向下滚动,然后返回到第一行,则图像将不再存在,因为-cellForRowAtIndexPath:被调用,因为我们有[cell.imageView setImage: [UIImage imageNamed:@""]]; 在其中, imageView.image被重置。


要处理上述情况,您需要记住select了哪些行。 (你可以通过一个基本的数组来实现这个)

例:

 - (void)viewDidLoad { [super viewDidLoad]; //arrMyDataSource is defined in .h as 'NSArray *arrMyDataSource;' //needless to say but this is the tableView's datasource contents arrMyDataSource = @[@"Apple",@"Banana",@"Candy",@"Door",@"Elephant"]; //arrMemoryMap is defined in .h as 'NSMutableArray *arrMemoryMap;' //this is one way to remember which row is selected arrMemoryMap = [NSMutableArray alloc] init]; for (int i = 0 ; i < arrMyDataSource.count ; i++) { NSNumber *tmpSelectStatus = [NSNumber numberWithBool:NO]; [arrMemoryMap addObject: tmpSelectStatus]; } } 

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { //... if([[arrMemoryMap objectAtIndex:indexPath.row] boolValue] == YES) { [cell.imageView setImage: [UIImage imageNamed:@"loudspeaker.png"]]; } else { [cell.imageView setImage: [UIImage imageNamed:@""]]; } return cell; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { //first, reset arrMemoryMap for all rows for (int i = 0 ; i < arrMemoryMap.count ; i++) { if([[arrMemoryMap objectAtIndex:i] boolValue] == YES]) { [[arrMemoryMap objectAtIndex:i] setBoolValue: NO]; break; } } //now, set current row as selected in arrMemoryMap [[arrMemoryMap objectAtIndex:indexPath.row] setBoolValue: YES]; //reload data or particular section [tableView reloadSections:indexPath.section withRowAnimation:UITableViewRowAnimationFade]; }