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

时间:2015-01-31 06:45:03

标签: ios objective-c image uitableview

我正在创建一个应用程序来显示列表,每个列表都有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;

}

4 个答案:

答案 0 :(得分: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除了原始问题中显示的属性之外还有其他属性,因此也许重用您的单元格是有意义的。但要做到这一点,您必须在每次调用UIImageView期间清除旧的cellForRowAtIndexPath子视图,例如:

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

答案 1 :(得分:0)

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

答案 2 :(得分:-1)

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

答案 3 :(得分:-1)

示例数组

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

等。使用循环不是一个好主意。试试这个并告诉是否有任何问题。