在UITableView

时间:2015-05-06 00:18:03

标签: objective-c json uitableview uiimageview nsmutablearray

毋庸置疑,我是新手。我正在尝试将图像和文本添加到UITableView。我已经能够添加文本,但我在向所需文本添加不同图像时遇到问题。

我有1个数据库的2个单独的PHP代码:

  • 第一个获取文本和分配给文本(imageID)的图像的ID
  • 第二个使用id(来自第一个PHP)获取图像

我的代码很好,但目前所有文字只显示1张图片

我的问题是如何将每张图片分配到文字中?

如何将图像分配给没有图像的文本,因为某些文本没有图像?

我的代码如下:

连接和数据下载:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    // Create an array to store the locations
        NSMutableArray *list = [[NSMutableArray alloc] init];

    // Parse the JSON that came in
    NSError *error;
    jsonArray = [NSJSONSerialization JSONObjectWithData:downloadedData options:NSJSONReadingAllowFragments error:&error];

    // Loop through Json objects, create question objects and add them to our questions array
    for (int i = 0; i < jsonArray.count; i++)
    {
        jsonElement = jsonArray[i];

        // Create a new cell object and set its props to JsonElement properties
        if (![jsonElement [@"Thought"] isEqual:[NSNull null]])
        {
            NSString *listText =jsonElement [@"Thought"];
            if ([listText length] > 0)
            {
                NSString *cellText = jsonElement[@"Thought"];
                [list addObject:cellText];
                NSLog(@"list Cell: %@", cellText);
            }

            if (![jsonElement [@"filename"] isEqual:[NSNull null]])
            {
                imageID = jsonElement[@"id"];
            }
            NSLog(@"Cell Image: %@", imageID);
        }
    }
    [[self tableView1] reloadData];
}

表中的单元格:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *simpleIdentifier = @"SimpleIdentifier";
    cell = [tableView dequeueReusableCellWithIdentifier:simpleIdentifier];
    if (cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:simpleIdentifier];
    }

    cell.textLabel.text = [list objectAtIndex:indexPath.row];
    cell.textLabel.font = [UIFont italicSystemFontOfSize:20];

    if ([imageID length] > 0)
    {
        urlStr = [NSString stringWithFormat:@"http://database.name/getimage.php?id=%@", imageID];
        NSURL *imageUrl = [NSURL URLWithString:urlStr];
        NSData *imageData = [NSData dataWithContentsOfURL:imageUrl];
        UIImage *imageLoad = [[UIImage alloc] initWithData:imageData];
        cell.imageView.image = imageLoad;
    }

    return cell;
}

2 个答案:

答案 0 :(得分:1)

UITableView的细胞是可重复使用的。这意味着在重置之前,不可见的单元格将显示相同的内容。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *simpleIdentifier = @"SimpleIdentifier";
    cell = [tableView dequeueReusableCellWithIdentifier:simpleIdentifier];
    if (cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:simpleIdentifier];
    }

    cell.textLabel.text = @"";
    cell.imageView.image = nil;

    cell.textLabel.text = [list objectAtIndex:indexPath.row];
    cell.textLabel.font = [UIFont italicSystemFontOfSize:20];

    ...
}

只需添加重置代码。

答案 1 :(得分:1)

你不应该在tableview:cellForRowAtIndexPath中保持不动。当你尝试这个时会发生什么

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *simpleIdentifier = @"SimpleIdentifier";
    cell = [tableView dequeueReusableCellWithIdentifier:simpleIdentifier];
    if (cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:simpleIdentifier];
    }

    cell.textLabel.text = [list objectAtIndex:indexPath.row];
    cell.textLabel.font = [UIFont italicSystemFontOfSize:20];

    if ([imageID length] > 0)
    {
        urlStr = [NSString stringWithFormat:@"http://database.name/getimage.php?id=%@", imageID];
        NSURL *imageUrl = [NSURL URLWithString:urlStr];
        NSData *imageData = [NSData dataWithContentsOfURL:imageUrl];
        UIImage *imageLoad = [[UIImage alloc] initWithData:imageData];
        cell.imageView.image = imageLoad;
    }
    else //I assume this is the case when a row does not contain an image right?
    {
        cell.imageView.image = nil; //Or the below line for better aestethics
        //cell.imageView.image = [UIImage imageNamed:@"placeholderimage.png"];
    }
    return cell;
}

每次NSData *imageData = [NSData dataWithContentsOfURL:imageUrl];被触发时都会调用tableview:cellForRowAtIndexPath,这种情况很快发生。据我所知,dataWithContentsOfURL:是一个繁重的过程,并且会停止UI,直到它下载图像为止。因此,最好下载一次特定图片并将其保存在NSMutableArrayNSMutableDictionary中。例如:

//in your .m
@interface ViewController ()

@property NSMutableDictionary * imageIdDictionary;

@end

@implementation ViewController

-(void)viewDidLoad
{
    [super viewDidLoad];
    imageIdDictionary = [[NSMutableDictionary alloc] init];
}

将您的tableView:cellForRowAtIndexPath:更改为:

//Added this. You need a second array just like `list` which has all the different imageID's stored
imageID = [list2 objectAtIndex:indexPath.row];
if ([imageID length] > 0) {
    if([self.imageIdDictionary objectForKey:imageID]) {
        cell.imageView.image = [self.imageIdDictionary objectForKey:imageID];
    }
    else {
        urlStr = [NSString stringWithFormat:@"http://database.name/getimage.php?id=%@", imageID];
        NSURL *imageUrl = [NSURL URLWithString:urlStr];
        NSData *imageData = [NSData dataWithContentsOfURL:imageUrl];
        UIImage *imageLoad = [[UIImage alloc] initWithData:imageData];
        cell.imageView.image = imageLoad;
        [self.imageIdDictionary setValue:imageLoad forKey:imageID];
        //added these two lines!!!!!!!
        NSArray * array = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section]];
        [table reloadRowsAtIndexPaths:array withRowAnimation:UITableViewRowAnimationFade];
    }
}
else {
    cell.imageView.image = nil; //Or the below line for better aestethics
    //cell.imageView.image = [UIImage imageNamed:@"placeholderimage.png"];
}

这将使您的应用程序运行得更顺畅