【问题标题】:Selected cell Image will display in UITableView [duplicate]选定的单元格图像将显示在 UITableView [重复]
【发布时间】:2013-12-28 06:39:03
【问题描述】:

我在默认的UITabelViewCell 中添加了UIImageView 作为subView
当我单击单元格时,UIImageView 应在所选单元格中显示图像。
该怎么做?

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        //Creating cells
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                      reuseIdentifier:CellIdentifier];
        [cell setSelectionStyle:UITableViewCellSelectionStyleNone]; 
    }
    //Image
    imv = [[UIImageView alloc]initWithFrame:CGRectMake(7,10, 20, 25)];
    imv.image=[UIImage imageNamed:@"loudspeaker.png"];
    [cell addSubview:imv];
   return cell;
}

-didSelectRowAtIndexPath:做什么?

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//????
}

我只想在一个单元格中显示图像(以最后选择的为准)。

当我点击第一行时,图像应该只显示在第一行。
当我点击第二行时,图像将只显示在第二行,而不是第一行。

【问题讨论】:

    标签: ios cocoa-touch uitableview didselectrowatindexpath


    【解决方案1】:

    最简洁的方法是继承 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找到它

    【讨论】:

      【解决方案2】:

      试试这个:

      - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
          //...
      
          //Create UIImageView object locally (so each cell has separate UIImageView)
          UIImageView *cellSpecificImage = [[UIImageView alloc] initWithFrame:CGRectMake(7,10, 20, 25)];
          [cellSpecificImage setImage:[UIImage imageNamed:@""]];
          [cellSpecificImage setTag:100]; //important
      
          //add the UIImageView object to the contentView of the cell
          //[cell addSubView:cellSpecificImage]; //incorrect
          [cell.contentView adSubView:cellSpecificImage]; //correct
          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];
      
          //basically, pointer to the cell's UIImageView object
          UIImageView *tmpCellSpecificImage = (UIImageView *)[cell viewWithTag:100];
          //change parameters and it will manifest on the cell
          [tmpCellSpecificImage setImage:[UIImage imageNamed:@"loudspeaker.png"]];
      }
      

      或者...(替代方法)

      由于您的单元格是UITableViewCellStyleDefault 样式,您甚至不需要创建自己的UIImageView 对象,因为UITableViewCellStyleDefault 已经提供了一个预定义 imageView 对象(只是比如textLabel & detailTextLabel)。
      这个imageView 对象出现在单元格的左侧。

      简单地说:

      cell.imageView.image = [UIImage imageNamed:@"image.png"];
      

      例子:

      - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
          //...
      
          [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];
      
          //change image
          [cell.imageView setImage: [UIImage imageNamed:@"loudspeaker.png"]];
      }
      

      至于仅在一个单元格中显示图像(取决于最后选择哪个),我已经回答了here您的其他问题):How to set image in selected cell row in UITableView

      编辑:事实上,我已经合并了我的答案,下面继续。


      终于...

      上述方法的问题在于它只是一个视觉方面。
      如果您选择第一行并向下滚动并稍后返回第一行,则图像将不再存在,因为-cellForRowAtIndexPath: 已被调用,并且由于其中有[cell.imageView setImage: [UIImage imageNamed:@""]];imageView.image 被重置。


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

      示例:

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

      【讨论】:

      • 我只想在选定的单元格中显示图像,当我单击第一个单元格图像时,仅在第一个单元格中显示,当我单击第二个单元格图像时,仅在第二个单元格中不显示在第一个单元格中。怎么做..
      • @user2841148 :我在你的另一个问题中回答了那部分:link
      • @user2841148 :我在这里合并了我的两个答案
      猜你喜欢
      • 2015-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多