【问题标题】:UIImage & UITableViewCell dimensionsUIImage & UITableViewCell 尺寸
【发布时间】:2010-11-06 00:40:14
【问题描述】:

我正在通过 URL 动态地将不同大小的图像加载到我的 UITableViewCells 中。我希望能够根据下载的图像大小调整单元格的大小。我可以提取尺寸然后更改每个单元格的 heightForRowAtIndexPath 吗?

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSData *receivedData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[arrayOfImages objectAtIndex:indexPath.row]] 
                                             options:NSUncachedRead     
                                               error: &error];

UIImage *image = [[UIImage alloc] initWithData:receivedData];

imgView.image = image;

[cell.contentView addSubview:imgView];

....

【问题讨论】:

    标签: objective-c uitableview ios4 uiimage


    【解决方案1】:

    简短的回答:一旦你有了图片,那么 image.size.height 应该会给你你想要的。但是,heightForRowAtIndexPath: 在 cellForRowAtIndexPath: 之前被调用。所以你可能想要实现某种类型的异步图像加载器。查看 Apple 示例 LazyTableImages 以获得完整的实现。

    长答案:我做了一些快捷方式来回答您的问题,而无需编写 1000 行代码,但这应该可以证明这个想法。重要的位是 cellForRowAtIndexPath: 和 heightForRowAtIndexPath:。

    RootViewController.m

    #import "RootViewController.h"
    
    @interface RootViewController()
    - (void)loadImagesForOnscreenRows;
    - (void)loadImageForIndexPath:(NSIndexPath *)indexPath;
    @end
    
    @implementation RootViewController
    
    static NSMutableDictionary *images;
    static NSDictionary *pathAndName;
    
    #pragma mark -
    #pragma mark NSObject
    - (void)dealloc {
        [images release];
        [pathAndName release];
        [super dealloc];
    }
    
    
    #pragma mark UIViewController
    - (void)viewDidLoad {
    
        // image paths from WikiMedia
        pathAndName = [[NSDictionary alloc] initWithObjectsAndKeys:
                       @"http://upload.wikimedia.org/wikipedia/commons/8/89/Crystal_Clear_app_virus_detected_2.png", @"Big Virus",
                       @"http://upload.wikimedia.org/wikipedia/commons/thumb/c/c7/Crystal_Clear_app_virus_detected.png/64px-Crystal_Clear_app_virus_detected.png", @"Little Virus",
                       nil];
    
        images = [[NSMutableDictionary alloc] initWithCapacity:[pathAndName allKeys].count];
    }
    
    - (void)viewDidUnload {
        [images release];
        images = nil;
    
        [pathAndName release];
        pathAndName = nil;
    }
    
    
    #pragma mark UIScrollViewDelegate
    - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
        if (!decelerate) {
            [self loadImagesForOnscreenRows];
        }
    }
    
    - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
        [self loadImagesForOnscreenRows];
    }
    
    
    #pragma mark UITableViewDataSource
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        return [pathAndName allKeys].count;
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
        // typical cell creation
        static NSString *CellIdentifier = @"Cell";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
        }
    
        // if the image is downloaded, then set the cell image.
        NSString *key = [[pathAndName allKeys] objectAtIndex:indexPath.row];
        UIImage *image = [images objectForKey:key];
        if (image) {
            [cell.imageView setImage:image];
        }
    
        [cell.textLabel setText:key];
        return cell;
    }
    
    #pragma mark UITableViewDelegate
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    
        NSString *key = [[pathAndName allKeys] objectAtIndex:indexPath.row];
        UIImage *image = [images objectForKey:key];
        if (image) {
            return image.size.height;
        }
    
        // if the image is not yet downloaded, kick off downloading it and return a default row height.
        [self performSelector:@selector(loadImageForIndexPath:) withObject:indexPath afterDelay:0.1f];
        return tableView.rowHeight;
    }
    
    
    #pragma mark -
    #pragma mark RootViewController
    #pragma mark Private Extension
    - (void)loadImagesForOnscreenRows {
        NSArray *visiblePaths = [self.tableView indexPathsForVisibleRows];
        for (NSIndexPath *indexPath in visiblePaths) {
            [self loadImageForIndexPath:indexPath];
        }
    }
    
    // This is a big shortcut from the Apple sample, LazyTableImages.
    - (void)loadImageForIndexPath:(NSIndexPath *)indexPath {
    
        NSString *key = [[pathAndName allKeys] objectAtIndex:indexPath.row];
        if ([images objectForKey:key]) return;
    
        NSString *path = [pathAndName objectForKey:key];
    
        NSError *error = nil;
        NSData *receivedData = [NSData dataWithContentsOfURL:[NSURL URLWithString:path] 
                                                     options:NSUncachedRead     
                                                       error: &error];
        if (error) return;
    
        UIImage *image = [[UIImage alloc] initWithData:receivedData];
        [images setObject:image forKey:key];
        [image release];
        NSArray *indexPaths = [NSArray arrayWithObject:indexPath];
        [self.tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationFade];
    }
    
    
    @end
    

    【讨论】:

    • 非常感谢 - 我找到了 LazyTableImages,它的帮助很大
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-18
    • 2014-02-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多