UI图像& UITableViewCell 尺寸

发布于 2024-10-01 01:49:21 字数 641 浏览 1 评论 0原文

我通过 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];

....

I am loading into my UITableViewCells different sized images dynamically via URLs. I want to be able to resize the Cell depending on the size of the image that's downloaded. Can I extract the dimensions then change the heightForRowAtIndexPath for each cell?

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

....

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

半山落雨半山空 2024-10-08 01:49:21

简短的回答:一旦你有了图像,那么 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

The short answer: once you have the image, then image.size.height should give you what you want. However, heightForRowAtIndexPath: gets called before cellForRowAtIndexPath:. So you will probably want to implement some type of async image loader. Have a look at the Apple sample LazyTableImages for a full implementation of that.

The long answer: I made a few shortcuts to answer your question without writing 1000 lines of code, but this should demonstrate the idea. The important bits are cellForRowAtIndexPath: and 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文