UITableViewCell с изображениями разных размеров
Я пытаюсь использовать свой ReusableCell для ячеек с изображениями разных размеров. Изображения помещаются в черный квадрат 220x150 с масштабированием UIViewContentModeScaleAspectFit
.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"NewsTableViewCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NewsItem *item = [self.fetchedResultsController objectAtIndexPath:indexPath];
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:item.imageUrl]];
[cell.imageView setImage:[[UIImage alloc] initWithData:data]];
[cell.imageView setBackgroundColor:[UIColor blackColor]];
[cell.imageView setContentMode:UIViewContentModeScaleAspectFit];
CGRect imageViewFrame = cell.imageView.frame;
imageViewFrame.size.width = 220;
imageViewFrame.size.height = 150
[cell.imageView setFrame:imageViewFrame];
[cell.textLabel setText:item.title];
return cell;
}
Приведенный выше код приводит к следующему макету, и изображения иногда меняются при прокрутке в виде таблицы.
![UITableView with images]()
Вместо этого неструктурированного макета я хотел бы, чтобы изображения были выровнены следующим образом:
![Images in a black box]()
Что я делаю неправильно с этим ReusableCell?
EDIT1:
Я пытаюсь создать imageView и добавить этот образView как супервизор в cell.contentView.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"NewsTableViewCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NewsItem *item = [self.fetchedResultsController objectAtIndexPath:indexPath];
UIImage *placeholderImage = [UIImage imageNamed:@"ImagePlaceholderThumb"]; //220x150
UIImageView *imageView = [[UIImageView alloc] initWithImage:placeholderImage];
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:item.imageUrl]];
[imageView setImage:[[UIImage alloc] initWithData:data]];
[imageView setBackgroundColor:[UIColor blackColor]];
[imageView setContentMode:UIViewContentModeScaleAspectFit];
CGRect imageViewFrame = imageView.frame;
imageViewFrame.size.width = placeholderImage.size.width;
imageViewFrame.size.height = placeholderImage.size.height;
[imageView setFrame:imageViewFrame];
[cell.contentView addSubview:imageView];
[cell.textLabel setText:item.title];
return cell;
}
Приведенный выше код приводит к следующему:
![UIImageView in superview]()
Это похоже на то, что некоторые изображения видны в двух ячейках. Кажется, что они не поддерживают размер, который я установил в imageViewFrame. Вы знаете, почему?
Ответы
Ответ 1
Быстрое исправление будет использовать режим содержимого UIViewContentModeScaleAspectFill
. Изображения будут растянуты в одном или обоих измерениях, чтобы заполнить границы всего изображения.
Вам действительно нужно выполнить подкласс UITableViewCell
, чтобы сделать это правильно.
Thre - это ленивое решение, добавляющее новый UIImageView
и использование спейсера, как сказал Келлер в своем ответе (не стесняйтесь принять его ответ, это всего лишь недостающий код).
Выдержка tableView:cellForRowAtIndexPath:
:
...
cell.textLabel.text = [NSString stringWithFormat:@"Cell #%i", indexPath.row];
cell.imageView.image = [UIImage imageNamed:@"spacer.png"]; /* spacer is 64 x 44 */
/* image view width should be ~ 64 px, otherwise it will overlap the text */
UIImageView *iv = [[UIImageView alloc] initWithFrame:(CGRect){.size={64, tableView.rowHeight}}];
switch (indexPath.row) {
case 0:
iv.image = [UIImage imageNamed:@"waterfall.png"];
break;
/* etc... */
}
if (indexPath.row < 3) {
/* add black bg to cell w/ images */
iv.backgroundColor = [UIColor blackColor];
}
iv.contentMode = UIViewContentModeScaleAspectFit;
[cell.contentView addSubview:iv];
...
Таблица будет выглядеть так:
![aspect fit]()
Вам нужно установить заполнитель (spacer.png
выше) в существующем виде изображения ячейки. Он нажимает текстовую метку справа.
Вы можете использовать аспект заполнения и удалить бит цвета фона:
iv.contentMode = UIViewContentModeScaleAspectFill;
Таблица будет выглядеть неправильно, потому что изображение вычерчивается за пределы границ:
![aspect fill without clipping]()
Просто клип, чтобы получить лучший результат:
iv.clipsToBounds = YES;
![aspect fill]()
Ответ 2
Создайте подпрограмму UIImageView для каждой ячейки и ее в contentView. Каждый UIImageView содержит изображение с согласованным фреймом, но с опцией UIViewContentModeScaleAspectFit
. Затем просто установите цвет фона UIImageView в черный.
Я только что подтвердил это, но вам нужно также создать образ spacer spacer, чтобы убедиться, что textLabel уходит с пути. Просто сделайте одинаковые размеры вашего изображения (с бокс-письмом).
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
//spacer
cell.imageView.image = [UIImage imageNamed:@"placeholder"];
//imageview
UIImageView *thumbnail = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 80, 44)];
thumbnail.tag = kThumbTag;
thumbnail.backgroundColor = [UIColor blackColor];
thumbnail.contentMode = UIViewContentModeScaleAspectFit;
[cell.contentView addSubview:thumbnail];
}
// Configure the cell...
cell.textLabel.text = [NSString stringWithFormat:@"Cell %d", indexPath.row];
cell.imageView.frame = CGRectMake(0, 0, 80, 44);
UIImageView *thumb = (UIImageView*)[cell.contentView viewWithTag:kThumbTag];
if (indexPath.row == 0) {
[thumb setImage:[UIImage imageNamed:@"image1.png"]];
} else {
[thumb setImage:[UIImage imageNamed:@"image2.png"]];
}
return cell;
}
Очевидно, что этот пример - это не ленивая загрузка изображений (я не понимал, что вы загружаете их из URL-адреса). Для этого я бы использовал подкласс с EGOImageView или что-то подобное.