Добавление 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;
Ответы
Ответ 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;
}
Когда он соответствует высоте ячейки таблицы, не было перекрытия; когда он был слишком мал, было перекрытие. Имейте в виду, что я очень быстро поработал, поэтому я не уверен, что это очень хорошая идея.