Переупорядочивание подвидов ячеек при изменении размера UITableViewCell

У меня есть UITableViewCell, который реализован с использованием раскадровки, которая выглядит так:

введите здесь описание изображения

Вот как должна выглядеть ячейка без изображения:

введите здесь описание изображения

Я возился с ограничениями и ломал голову, пытаясь понять это, но мне не повезло. У меня довольно хорошее понимание ограничений и того, как добавить их программно, но мне не повезло с этой конкретной проблемой, и я чувствую, что просто добавляю ограничения макета в ячейку волей-неволей без логического мыслительного процесса. Ячейка представляет собой публикацию в ленте новостей, которая может иметь или не иметь изображение в основном представлении изображения вверху и должна вести себя следующим образом. Если в ячейке нет изображения, нижняя полоса с подсчетом лайков и комментариев перемещается вверх, чтобы выровняться с верхней частью ячейки. Я добился такого поведения, установив ограничение, которое удерживало меньший вид изображения, заголовок сообщения, время публикации и содержимое публикации на заданном расстоянии от нижней части ячейки. Этот подход работает, и когда размер ячейки изменяется в методе heightForRowAtIndexPath, подпредставления перемещаются соответствующим образом. Проблема возникает, когда текст в содержимом сообщения больше одной строки. Высота ячейки регулируется правильно, но верхняя часть текстового представления остается в том же месте, увеличивается вниз и перетекает в следующую ячейку. Когда я размещаю ограничения для выравнивания четырех подвидов с верхней частью ячейки, я сталкиваюсь с проблемами, когда нет изображения, а содержимое сообщения больше, чем одна строка. В этом случае размер ячейки изменяется так, чтобы он был меньше ее исходного размера, а подпредставления остаются на расстоянии, заданном ограничением. Меньшее изображение, заголовок поста, время и содержание обрезаются и не отображаются. Это такая странная проблема с таким количеством разных случаев. Я работаю над этим почти два дня и действительно могу использовать чьи-то мысли о том, как решить эту проблему. Я надеюсь, что это не слишком запутанно, спасибо за помощь!


person ScottOBot    schedule 21.08.2013    source источник
comment
Где должно быть это маленькое квадратное изображение и двигаться? Должен ли он перекрывать этот более крупный вид изображения? Всегда ли на нем есть изображение или иногда оно тоже пустое?   -  person rdelmar    schedule 22.08.2013
comment
Кроме того, когда в представлении большого изображения нет изображения, вы хотите, чтобы эта нижняя панель была над другим содержимым? В верхней части клетки?   -  person rdelmar    schedule 22.08.2013
comment
Я отредактировал сообщение и добавил изображение того, как должна выглядеть ячейка без изображения. @rdelmar   -  person ScottOBot    schedule 22.08.2013
comment
Еще пара вопросов. Когда у вас есть большое изображение, маленькое изображение сверху частично перекрывает его? И что такое заголовок поста, время поста и контент поста — это 3 метки или смесь меток и текстовых представлений?   -  person rdelmar    schedule 22.08.2013


Ответы (2)


У меня есть один способ решить эту проблему, но я уверен, что есть много других. Я задал обоим представлениям изображения фиксированное ограничение по высоте. Маленькое представление изображения и верхняя метка (заголовок сообщения) имеют фиксированную высоту до верхней части ячейки — оба из них, а также ограничение по высоте для представления большого изображения имеют для них IBOutlets, поэтому их можно изменить в коде. Нижняя метка (Post Content) имеет количество строк, равное 0, и имеет IBOutlet для ограничения высоты (все метки имеют стандартную высоту в 21 пункт для начала). В коде я проверяю наличие изображения в каждом indexPath и соответствующим образом меняю ограничения.

- (void)viewDidLoad {
    UIImage *image1 = [UIImage imageNamed:@"House.tiff"];
    [super viewDidLoad];
    self.theData = @[@{@"pic":image1, @"post":@"short post"},@{@"post":@"short post"},@{@"pic":image1, @"post":@"Long long post with some extra stuff, and even some more"},@{@"post":@"Long long post with some extra stuff, and even some more"}];
    [self.tableView reloadData];
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return self.theData.count;
}

-(CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    CGFloat ivHeight = (self.theData[indexPath.row][@"pic"])? 215 : 0; // 215 is the fixed height of the large image view
    CGSize labelSize = [self.theData[indexPath.row][@"post"] sizeWithFont:[UIFont systemFontOfSize:17] constrainedToSize:CGSizeMake(152, CGFLOAT_MAX)];
    return 140 + ivHeight + labelSize.height; // the 140 was determined empirically to get the right spacing between the 3 labels and the bottom bar
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    RDCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
    cell.label.text = self.theData[indexPath.row][@"post"];
    cell.iv.image = self.theData[indexPath.row][@"pic"];
    if(self.theData[indexPath.row][@"pic"] == nil){
        cell.heightCon.constant = 0; // heightCon is the outlet to the large image view's height constraint
        cell.ivTopCon.constant = 8; // ivTopCon is the outlet to the small image view's spacing to the top of the cell
        cell.labelTopCon.constant = 8; // labelTopCon is the outlet to thetop label's spacing to the top of the cell
    }else{
        cell.heightCon.constant = 215; // this number and the following 2 are taken from the values in IB
        cell.ivTopCon.constant = 185;
        cell.labelTopCon.constant = 233;
    }
    CGSize labelSize = [self.theData[indexPath.row][@"post"] sizeWithFont:[UIFont systemFontOfSize:17] constrainedToSize:CGSizeMake(152, CGFLOAT_MAX)];
    cell.labelHeightCon.constant = labelSize.height;
    return cell;
}
person rdelmar    schedule 22.08.2013

Привет, @rdelmar, спасибо за решение! В конце концов я просто разработал две разные ячейки в файле раскадровки с разными идентификаторами повторного использования, но одним и тем же подклассом. Затем я проверил в методе cellForRowAtIndexPath, есть ли в ячейке содержимое или нет, и присвоил правильный идентификатор. Если это неправильный способ сделать это или вызовет проблемы в будущем, сообщите мне об этом в комментариях.

person ScottOBot    schedule 29.08.2013