Краткий ответ: если у вас есть изображение, то 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