Градиентный слой в ячейке таблицы, предотвращающий появление цвета выбора

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

Единственная проблема заключается в том, что теперь, когда я выбираю ячейку таблицы, она не меняет цвет на стиль выбора, будь то синий или серый.

Код, который я использую для своего градиента,

UIView *view = [[UIView alloc] initWithFrame:cell.frame];
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = view.bounds;
gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor colorWithRed:0.3 green:0.3  blue:0.3 alpha:1.0] CGColor], (id)[[UIColor colorWithRed:0.28 green:0.28 blue:0.28 alpha:1.0] CGColor], nil];
[cell.layer insertSublayer:gradient atIndex:0];

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

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


person Andre C    schedule 25.12.2011    source источник
comment
Что ты делаешь с видом? Я предполагаю, что вы можете выбрать ячейку так, как хотите, когда удаляете этот код, верно?   -  person lbrndnr    schedule 25.12.2011
comment
Не могли бы вы просто анимировать непрозрачность слоя градиента при выборе строки? Существует метод делегата -tableView:DidSelectRowAtIndexPath: где вы получаете обратный вызов всякий раз, когда выбрана строка. (Вам также придется анимировать непрозрачность обратно в -tableView:didDeselectRowAtIndexPath: (обратите внимание на DEselect), чтобы получить правильный эффект)   -  person David Rönnqvist    schedule 25.12.2011


Ответы (2)


Когда выбран UITableViewCell, он вставляет фон выделения с индексом 0. В итоге он оказывается под вашим градиентом. Иерархия представлений выглядит так:

<MyTableViewCell: 0xd26fb80; baseClass = UITableViewCell; frame = (0 44; 320 44); autoresize = W; layer = <CALayer: 0xd26fc90>>
   | <UITableViewCellSelectedBackground: 0x6880810; frame = (0 0; 320 43); layer = <CALayer: 0x68855c0>>
   | <CAGradientLayer: 0xd26ecb0> (layer)
   | <UITableViewCellContentView: 0xd26fcc0; frame = (0 0; 320 43); opaque = NO; layer = <CALayer: 0xd26fd00>>
   | <UIView: 0xd26e8e0; frame = (0 43; 320 1); autoresize = W+TM; layer = <CALayer: 0xd26f1a0>>

Обратите внимание, что CAGradientLayer, который я вставил в нулевой индекс при создании ячейки, находится после UITableViewCellSelectedBackground, поэтому слой градиента визуально перекрывает выбранный фоновый слой.

Чтобы исправить это, создайте собственный подкласс UITableViewCell. Сделайте градиентный слой свойством или переменной вашего подкласса:

@implementation MyTableViewCell
{
    CAGradientLayer *_gradient;
}

- (void)initGradient
{
    _gradient = [CAGradientLayer layer];
    _gradient.opaque = YES;
    _gradient.frame = self.bounds;
    _gradient.colors = [NSArray arrayWithObjects:(__bridge id)[UIColor redColor].CGColor, (__bridge id)[UIColor blueColor].CGColor, nil];
    [self.layer insertSublayer:_gradient atIndex:0];
}

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) {
        [self initGradient];
    }
    return self;
}

- (void)awakeFromNib
{
    [self initGradient];
}

Переопределите setSelected:animated: в своем подклассе, чтобы показать или скрыть слой градиента в зависимости от того, выбрана ли ячейка:

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    [super setSelected:selected animated:animated];
    _gradient.hidden = selected;
}
person rob mayoff    schedule 25.12.2011
comment
Спасибо за Ваш ответ. Я реализовал части вашего кода и принял совет при создании собственного подкласса для UITableViewCell, но теперь, когда ячейка удерживается, еще не выбрана, просто удерживается, текст ячейки меняет цвет (выделенный цвет), но ячейка делает пока пользователь не уберет палец с ячейки. Для меня это не слишком большая проблема, но поскольку цвет текста похож на цвет ячейки, кажется, что текст на некоторое время исчезает... Есть идеи? - person Andre C; 26.12.2011
comment
Посмотрите на свойство highlightedTextColor UILabel. Если этого недостаточно, переопределите setHighlighted:animated: в своем подклассе UITableViewCell и делайте все, что вам нужно. - person rob mayoff; 27.12.2011

Я столкнулся с той же проблемой, и поскольку - (void)setSelected:animated: не всегда вызывался (например, когда пользователь удерживал ячейку и т. д.), я обнаружил, что этот метод работает намного лучше.

По сути, просто поместите свой градиент в файл cell.backgroundView.

UIView *cellBackgroundView = [[UIView alloc] initWithFrame:cell.bounds];
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = cellBackgroundView.bounds;
gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor colorWithRed:0.3 green:0.3 blue:0.3 alpha:1.0] CGColor], (id)[[UIColor colorWithRed:0.28 green:0.28 blue:0.28 alpha:1.0] CGColor], nil];

[cellBackgroundView.layer addSublayer:gradient];
cell.backgroundView = cellBackgroundView;

А затем установите selectedBackgroundView как хотите. таким образом, backgroundView ячейки обязательно будет полностью скрыт, слои и все такое. Это также работает с подклассами, замените cell. на self..

person James Linnell    schedule 27.08.2013