Подтвердить что ты не робот

Добавление subview больше, чем cellHeight, к UITableViewCell?

Я пытаюсь добавить subview в UITableViewCell и дизайн, из которого я работаю, от требований, чтобы этот конкретный subview (изображение) должен был быть больше, чем фактический UITableViewCell, и, таким образом, частично перекрывал своих братьев и сестер.

Итак, я настроил свою ячейку таблицы, сгенерировал мое изображение и добавил его в содержимое cellView:

// rowHeight for the UITableView is 45.0f

UIImage *image = [self createCellThumbnail: someImage];
UIImageView *thumbView = [[UIImageView alloc] initWithFrame: CGRectMake(150, -5, 55,55)];
thumbView.transform = CGAffineTransformMakeRotation(0.1f);
thumbView.image = image;

cell.clipsToBounds = NO;
cell.contentView.clipsToBounds = NO;

[cell.contentView addSubview: thumbView];

Пока изображение будет "переполняться" в ячейку под ним, верхняя часть изображения всегда обрезается, как показано здесь:

img

Кто-нибудь знает, возможно ли, что я пытаюсь сделать с текущим подходом?

Или я должен просто выяснить способ рисования этих изображений в UITableView после того, как все ячейки будут нарисованы (это не прокручиваемое табличное представление, так что это будет работать и будет довольно легко).

Обновление:

Также попробовали добавить следующие, безрезультатно:

cell.opaque = NO;
cell.contentView.opaque = NO;

cell.clearsContextBeforeDrawing = NO;
cell.contentView.clearsContextBeforeDrawing = NO;

cell.clipsToBounds = NO;    
cell.contentView.clipsToBounds = NO;
4b9b3361

Ответ 1

Кажется, что tableView отображает свою ячейку снизу вверх, поэтому ячейки над одной ячейкой перекрывают одну ячейку. Чтобы этого избежать, вам нужно установить backgroundColor всех ячеек в +[UIColor clearColor], чтобы вы не увидели эти проблемы с перекрытием.

Но установка backgroundColor для очистки в -tableView:cellForRowAtIndexPath: не имеет никакого смысла. UIKit делает много вещей с ячейкой перед тем, как нарисовать, так что это reset свойство backgroundColor ячейки.

Нам нужно установить backgroundColor в более позднем состоянии. К счастью, это -[UITableViewDelegate tableView:willDisplayCell:forRowAtIndexPath:], которое мы можем реализовать следующим образом:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    cell.backgroundColor = [UIColor clearColor];
}

Теперь мы устанавливаем backgroundColor непосредственно перед тем, как ячейка будет нарисована, и это будет работать.

Ответ 2

UPDATE:

Итак, я сделал еще несколько экспериментов, и следующее решение все еще работает без необходимости устанавливать фон ячейки прозрачным, это связано с перемещением z-порядка покрытой ячейки. Это работает с подсветкой и выбором другой ячейки (через соответствующие обратные вызовы), и если фон из двух клеток имеет разные цвета. Решение выглядит следующим образом (вы можете игнорировать методы didHighlight и didSelect, если они вам не важны):

(обратите внимание, что "покрытая строка" - это та, содержимое которой мы пытаемся сохранить видимой, и в моем случае ее содержимое немного переходит в строку выше, которая была обрезана)

-(void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section == 0 && indexPath.row == ROW_ABOVE_COVERED_ROW)
    {
        NSIndexPath * rowbelow = [NSIndexPath indexPathForRow:indexPath.row+1 inSection:indexPath.section];
        UITableViewCell* cell = [tableView cellForRowAtIndexPath:rowbelow];
        [cell.superview bringSubviewToFront:cell];
    }
}

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section == 0 && indexPath.row == ROW_ABOVE_COVERED_ROW)
    {
        NSIndexPath * rowbelow = [NSIndexPath indexPathForRow:indexPath.row+1 inSection:indexPath.section];
        UITableViewCell* cell = [tableView cellForRowAtIndexPath:rowbelow];
        [cell.superview bringSubviewToFront:cell];
    }
}

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == 0 && indexPath.row == COVERED_ROW)
    {
        [cell.superview bringSubviewToFront:cell];
        cell.contentView.superview.clipsToBounds = NO;
    }
}

ПРИМЕЧАНИЕ. Вы также должны установить цвет фона вашего содержимого, чтобы он очистился, или он примет bgcolor остальной части вашей ячейки, и поэтому, когда вам удастся довести ваш контент до передней части закрывающей ячейки, он будет возьмите цвет фона с ним и оставьте неприятный смотрящий блок в другой ячейке (в моем случае единственным моим содержимым были detailTextLabel и textLabel):

// in cellForRowAtIndexPath:
[cell setBackgroundColor:[UIColor redColor]]; //using red for debug
cell.detailTextLabel.backgroundColor = [UIColor clearColor];
cell.textLabel.backgroundColor = [UIColor clearColor];

Я надеюсь, что это поможет кому-то еще попробовать это....

ORIGINAL:

Для меня решение заключалось в использовании:

self.contentView.superview.clipsToBounds = NO;

Мои ячейки уже были прозрачными, но мой контент все еще был обрезанным. В моем случае я использовал пользовательскую ячейку, которая перемещает ее содержимое в layoutSubviews. Итак, layoutSubviews для моей пользовательской ячейки заводится следующим образом:

-(void)layoutSubviews
{
    [super layoutSubviews];
    self.contentView.frame = CGRectOffset(self.contentView.frame, 0, -11);
    self.contentView.superview.clipsToBounds = NO;
}

Я не знаю, будет ли это работать, если ячейка выше была непрозрачной или если ячейки были выделены при нажатии, будет ли это закрывать мой контент.

Однако мне не понадобилось сделать ячейку прозрачной снова в методе обратного вызова viewWillDisplayCell - сделать это в обычном cellForRowAtIndexPath было достаточно

Ответ 3

У меня была эта проблема, и я убедился, что мой собственный основной фон tableviewcell проверял клип-подпрограммы и решил проблему. Это было с пользовательской ячейкой таблицы, загруженной из xib. Не совсем такая же, но схожая ситуация.

Ответ 4

У меня на самом деле было обратное только вчера, я создал пользовательскую ячейку таблицы, и по какой-то причине я получил переполнение, которое я не хотел иметь. Моим решением было добавить следующий код в класс контроллера вида:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{  
    return 175;
}

Когда он соответствует высоте ячейки таблицы, не было перекрытия; когда он был слишком мал, было перекрытие. Имейте в виду, что я очень быстро поработал, поэтому я не уверен, что это очень хорошая идея.