UITableViewCell с изображениями в разных измерениях - PullRequest
11 голосов
/ 01 февраля 2012

Я пытаюсь использовать мой 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 и добавить этот imageView в качестве суперпредставления для 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 . Ты знаешь почему?

Ответы [ 2 ]

18 голосов
/ 01 февраля 2012

Быстрое исправление - использование режима контента UIViewContentModeScaleAspectFill.Изображения будут растягиваться в одном или обоих измерениях, чтобы заполнить границы всего изображения.

Вам действительно нужно иметь подклассы UITableViewCell, чтобы сделать это правильно.

Это ленивое решение с добавлением нового 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 голосов
/ 01 февраля 2012

Создайте подпредставление UIImageView для каждой ячейки и его в contentView.Каждый UIImageView содержит изображение с непротиворечивой рамкой, но с опцией UIViewContentModeScaleAspectFit.Затем просто установите цвет фона UIImageView на черный.

Я только что подтвердил, что это работает, но вам также нужно создать изображение-разделитель, чтобы убедиться, что 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 или чем-то подобным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...