在 table 单元格 + iOS 中通过循环以编程方式添加图像

adding images programmatically via loop in table cell + iOS

我正在创建一个应用程序来显示列表,每个列表都有 x 个图像要显示在 table 单元格中。

要显示图像,我必须动态创建 UIImageView 并在 for 循环中将图像加载到单元格中{取决于从服务器调用接收到的数据}。

现在,我可以动态添加图像,但单元格中显示的图像数量不正确。我已经检查了数组值和循环次数,但仍然无法理解为什么图像无法正确加载。

问题: 加载视图时加载的前 3-4 个单元格显示以编程方式添加的图像视图的正确数量。但是当我滚动到 table 底部时,单元格中未显示正确数量的图像,而是显示随机数量的图像

这里是函数代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

static NSString *Cellidentifier1 = @"VenueCell";
VenueCell *cell = [tableView dequeueReusableCellWithIdentifier:Cellidentifier1 forIndexPath:indexPath];

// Configure the cell...

long row = [indexPath row];

if (!cell.hasImageViews) {
    cell.hasImageViews = YES;
    NSArray *individualSports = [_venueSports[row] componentsSeparatedByString:@"|"] ;

    NSLog(@"sports132431 = %@",individualSports);
    for (int t = 0; t<individualSports.count; t++) {
        UIImageView * imageView = [[UIImageView alloc]initWithFrame:CGRectMake((250/10*t+10), 125, 20, 20)];
        if ([individualSports[t] isEqual:@"Cricket"]) {
            [imageView setImage:[UIImage imageNamed:@"cricket_unselected.png"]];
        } else if ([individualSports[t] isEqual:@"Basketball"]) {
            [imageView setImage:[UIImage imageNamed:@"basketball_unselected.png"]];
        } else if ([individualSports[t] isEqual:@"Football"]) {
            [imageView setImage:[UIImage imageNamed:@"football_unselected.png"]];
        } else if ([individualSports[t] isEqual:@"Lawn Tennis"]) {
            [imageView setImage:[UIImage imageNamed:@"lawn_unselected.png"]];
        } else if ([individualSports[t] isEqual:@"Squash"]) {
            [imageView setImage:[UIImage imageNamed:@"squash_unselected.png"]];
        } else if ([individualSports[t] isEqual:@"Table Tennis"]) {
            [imageView setImage:[UIImage imageNamed:@"table_unselected.png"]];
        }  else if ([individualSports[t] isEqual:@"Badminton"]) {
            [imageView setImage:[UIImage imageNamed:@"badminton_unselected.png"]];
        }  else if ([individualSports[t] isEqual:@"Pool"]) {
            [imageView setImage:[UIImage imageNamed:@"pool_unselected.png"]];
        }  else if ([individualSports[t] isEqual:@"Swimming"]) {
            [imageView setImage:[UIImage imageNamed:@"swiming_unselected.png"]];
        }
        [cell addSubview:imageView];
    }
    individualSports = [[NSArray alloc] init];
    NSLog(@"sports = %@",_venueSports[row]);
    NSLog(@"asx=%@",individualSports);
}


return cell;

}

// hasImageViews是VenueCell的bool变量class

任何建议都是好的。 提前致谢!

更新:这是更新后的代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];

long row = [indexPath row];
// Configure the cell...

long row = [indexPath row]; 
cell.vName.text = _venueName[row];
cell.vTiming.text = _venueTiming[row];
cell.vAreaName.text = _venueArea[row];
cell.starRatingImage.backgroundImage=[UIImage imageNamed:@"starsbackground iOS.png"];
cell.starRatingImage.starImage = [UIImage imageNamed:@"star.png"];
cell.starRatingImage.starHighlightedImage = [UIImage imageNamed:@"starhighlighted.png"];
cell.starRatingImage.maxRating = 5.0;
cell.starRatingImage.delegate = self;
cell.starRatingImage.horizontalMargin = 12;
cell.starRatingImage.editable=NO;
cell.starRatingImage.rating=[_venueAvgRating[row] floatValue] ;
cell.starRatingImage.displayMode=EDStarRatingDisplayAccurate;




NSArray *individualSports = [_venueSports[row] componentsSeparatedByString:@"|"] ;

for (int t = 0; t<individualSports.count; t++) {
    UIImageView * imageView = [[UIImageView alloc]initWithFrame:CGRectMake((25*t+10), 125, 20, 20)]; 

    // Since each of your individualSports[t] options
    // first words is simply the prefix to your image file name,
    // you can simplify the contents of your loop like so:
    NSString *firstWord = (NSString*)[[individualSports[t] componentsSeparatedByString:@" "] objectAtIndex:0];
    [imageView setImage:[UIImage imageNamed:[NSString stringWithFormat:@"%@_unselected.png", firstWord.lowercaseString]]];

    [cell addSubview:imageView];
} 
if([_venueCategory[row] isEqualToString:@"Partner"]){ 

    cell.vImageCategory.image=[UIImage imageNamed:@"venue_partner.png"];
} 
else if([_venueCategory[row] isEqualToString:@"Verified"]){
    cell.vImageCategory.image=[UIImage imageNamed:@"venue_verified.png"];
} 
else{ 

    cell.vImageCategory.image=[UIImage imageNamed:@"venue_unverified.png"];
}
cell.vImage.image=[UIImage imageNamed:@"agon_logo.png"];



return cell;

}

由于您要重复使用单元格,因此在开始向单元格中添加新图像之前,您需要清除之前添加到单元格中的图像。如果您没有太多要显示的单元格,您可能根本不想重复使用这些单元格。

首先,您必须在单独的线程上在后台下载它们(不要在 cellForAtIndexPath 上编写此代码(它可能在 viewdidload 中))并且在成功下载后您必须重新加载 tableview。只需要一个自定义单元格和一个图像视图。

     -(void)viewDidLoad
    {
       UIImage *image;
        NSMutableArray *imageArray;

        for (int i=0; i<[totalImgesURLSArray count]; i++) {
            NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[totalImgesURLSArrayobjectAtIndex:i]]];
            image = [[UIImage alloc] initWithData:imageData];

            [imageArray addObject:image];
        }
        dispatch_async(dispatch_get_main_queue(), ^{

            [tableview reloadData];

        });
    });

}

       - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
        {

        return [imageArray count];
    }

例如数组

NSArray *sportsTypeArray=[NSArray arrayWithObjects:@"Cricket",@"Football",@"Hockey",@"Skitting",@"Running", nil];

inCellForRowAtIndex 方法

cell.textLabel.text=[sportsArray objectAtindex=indexPath.row];

if ([cell.textLabel.text isEqualToString: @"Cricket"]
{

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

else if ([cell.textLabel.text isEqualToString: @"Football"]
{

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

等使用循环不好idea.Try这个并告诉是否有任何问题。

首先,由于您正在重复使用您的单元格,因此此比较 - if (!cell.hasImageViews) { - 不一定会为 cellForRowAtIndexPath 的当前单元格保留适当的值,因为正在使用的单元格重用可以不同于当前单元格。例如,如果 table 视图的 4 个单元格可以同时显示在屏幕上,当您滚动到最初位于 table 之外的单元格 5 时,重新使用它意味着它包含内容并且 属性 单元格 1 的值。因此该比较完全不相关。

但在这种特定情况下,重复使用您的单元格毫无意义,因为单元格的全部内容对于每一行都是完全不同的。此外,由于您的自定义 table 视图单元格似乎只包含 .hasImageViews 属性,在这种情况下不需要使用自定义单元格,因为正如我们已经确定的那样,我们不会重复使用细胞。

最后,您可以像我在下面的代码中所做的那样大大简化 for 循环中的条件。

要实施这些更改,我建议执行以下操作:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];

    long row = [indexPath row];

    NSArray *individualSports = [_venueSports[row] componentsSeparatedByString:@"|"] ;

    for (int t = 0; t<individualSports.count; t++) {
        UIImageView * imageView = [[UIImageView alloc]initWithFrame:CGRectMake((25*t+10), 125, 20, 20)];

        // Since each of your individualSports[t] options
        // first words is simply the prefix to your image file name,
        // you can simplify the contents of your loop like so:
        NSString *firstWord = (NSString*)[[individualSports[t] componentsSeparatedByString:@" "] objectAtIndex:0];
        [imageView setImage:[UIImage imageNamed:[NSString stringWithFormat:@"%@_unselected.png", firstWord.lowercaseString]]];

        [cell addSubview:imageView];
    }

    return cell;

}

(注意:您在文件名中拼写 "swimming" 不正确,因此如果您不编辑捆绑包中的文件名,我对您的条件所做的更改将不适用于该条件。 )

更新: 从您的更新代码中可以清楚地看出,VenueCell 具有超出您原始问题中明显的其他属性,因此重用也许是有意义的毕竟是你的细胞。不过,要做到这一点,您必须在每次调用 cellForRowAtIndexPath 期间清除旧的 UIImageView 子视图,例如:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *Cellidentifier1 = @"VenueCell";
    VenueCell *cell = [tableView dequeueReusableCellWithIdentifier:Cellidentifier1 forIndexPath:indexPath];

    long row = [indexPath row];

    cell.vName.text = _venueName[row];
    cell.vTiming.text = _venueTiming[row];
    cell.vAreaName.text = _venueArea[row];
    cell.starRatingImage.backgroundImage=[UIImage imageNamed:@"starsbackground iOS.png"];
    // ... all the other starRatingImageCode ...
    cell.starRatingImage.displayMode=EDStarRatingDisplayAccurate;

    // Clear out any images previously added to the
    // cell during cellForRowAtIndexPath (images have been
    // assigned a tag of 1000 in the next for loop)
    for (UIView *subview in cell.subviews) {
        if (subview.tag == 1000) {
            [subview removeFromSuperview];
        }
    }

    NSArray *individualSports = [_venueSports[row] componentsSeparatedByString:@"|"] ;

    for (int t = 0; t<individualSports.count; t++) {
        UIImageView * imageView = [[UIImageView alloc]initWithFrame:CGRectMake((25*t+10), 125, 20, 20)];
        imageView.tag = 1000 //<-- Use a tag unique to these image views

        NSString *firstWord = (NSString*)[[individualSports[t] componentsSeparatedByString:@" "] objectAtIndex:0];
        [imageView setImage:[UIImage imageNamed:[NSString stringWithFormat:@"%@_unselected.png", firstWord.lowercaseString]]];

        [cell addSubview:imageView];
    }

    // Assuming the only "else" condition is "default",
    // I've similarly simplified this code as I did with
    // your other conditional
    cell.vImageCategory.image = [NSString stringWithFormat:@"venue_%@.png", _venueCategory[row].lowercaseString];
    cell.vImage.image = [UIImage imageNamed:@"agon_logo.png"];

    return cell;
}