【问题标题】:adding images programmatically via loop in table cell + iOS通过表格单元格中的循环以编程方式添加图像 + iOS
【发布时间】:2015-01-31 06:45:03
【问题描述】:

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

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

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

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

这里是功能代码:

- (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变量

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

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

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

}

【问题讨论】:

  • 还没有真正查看过你的代码,但是这个等式:250/10*t+10 等于 25*t+10,所以你可以大大简化它
  • 而且由于您正在重用您的单元格,因此此比较结果if (!cell.hasImageViews) { 可能没有达到您的预期,因为您也在重用该属性。此外,在这种情况下,您在重用单元格的同时添加子视图是一个很大的禁忌。
  • 我不认为你应该使用循环来分配图像。你应该将运动类型的标题存储在一个数组中。并在 cell.textLabe.text=[sportsArray objectAtIndex:indexpath.Row 中使用它];
  • 我必须添加图像而不是标签和数字,所以图像不知道所以我必须添加 for 循环
  • @Lyndsey Scott:我是 ios 开发的新手,请您指导我找到解决此问题的正确方法

标签: ios objective-c image uitableview


【解决方案1】:

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

尽管如此,在这种特定情况下,重用单元格毫无意义,因为每一行的单元格的全部内容都完全不同。此外,由于您的自定义表格视图单元格似乎只包含 .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;

}

(注意:您在文件名中拼写错误“游泳”,因此如果您不编辑捆绑包中的文件名,我对您的条件所做的更改将不适用于该条件。)

更新:现在从您更新的代码中可以清楚地看出,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;
}

【讨论】:

  • 谢谢,我正在应用你提到的解决方案
  • @Neelanshu 虽然循环是必要的,但我会更新我的答案以大大简化您的实现......一秒钟......
  • 谢谢!应用这个
  • @Neelanshu 另请注意,草地网球是两个词,当文件名只是草地时......我实际上也要对我的代码进行最后一次编辑以处理这种情况......一秒……
  • 谢谢!它就像一个魅力。问题已解决,我只需要配置单元格以显示其余内容并完成
【解决方案2】:

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

【讨论】:

  • :单元格的数量是动态的,因此无法由我控制。由于我是iOS开发的新手,请您更清楚地了解重用标识符的事情。
  • 基本上,当您重用单元格时,您会缓存这些可见单元格。一旦一个单元格从屏幕顶部滚动出来,完全相同的单元格就会显示在底部。如果您不清理单元格,您将看到刚刚从顶部滚动出来的相同信息,因为它是被重复使用的同一单元格。
【解决方案3】:

例如一个数组

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

等等。使用循环不是个好主意。试试这个,看看有没有问题。

【讨论】:

  • 我不同意。在这种情况下需要使用循环,因为 OP 不知道每行所需的图像数量。
  • NSArray *individualSports 从哪里获取数据?来自服务器?
  • @Logic : 是的,数组是从服务器获取的
  • 你能显示存储在数组中的数据吗?实际上..应该在已经加载来自服务器的数据时加载tableview。那么你根本不需要使用循环
【解决方案4】:

首先,您必须在单独的线程上后台下载它们(不要在 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];
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-09
    • 1970-01-01
    相关资源
    最近更新 更多