Подвид UITableViewCell исчезает при выделении ячейки - PullRequest
173 голосов
/ 19 июля 2011

Я реализую табличное представление с выбором цвета, где пользователь может выбрать, скажем, 10 цветов (зависит от продукта). Пользователь также может выбрать другие параметры (например, емкость жесткого диска, ...).

Все параметры цвета находятся в собственном разделе таблицы.

Я хочу отобразить небольшой квадрат слева от textLabel, показывающий фактический цвет.

Прямо сейчас я добавляю простой квадрат UIView, присваиваю ему правильный цвет фона, например:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:RMProductAttributesCellID];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:RMProductAttributesCellID] autorelease];
        cell.indentationWidth = 44 - 8;

        UIView *colorThumb = [[[UIView alloc] initWithFrame:CGRectMake(8, 8, 28, 28)] autorelease];
        colorThumb.tag = RMProductAttributesCellColorThumbTag;
        colorThumb.hidden = YES;
        [cell.contentView addSubview:colorThumb];
    }

    RMProductAttribute *attr = (RMProductAttribute *)[_product.attributes objectAtIndex:indexPath.section];
    RMProductAttributeValue *value = (RMProductAttributeValue *)[attr.values objectAtIndex:indexPath.row];
    cell.textLabel.text = value.name;
    cell.textLabel.backgroundColor = [UIColor clearColor];

    UIView *colorThumb = [cell viewWithTag:RMProductAttributesCellColorThumbTag];
    colorThumb.hidden = !attr.isColor;
    cell.indentationLevel = (attr.isColor ? 1 : 0);

    if (attr.isColor) {
        colorThumb.layer.cornerRadius = 6.0;
        colorThumb.backgroundColor = value.color;
    }

    [self updateCell:cell atIndexPath:indexPath];

    return cell;
}

Прекрасно отображается без проблем.

Моя единственная проблема заключается в том, что когда я выбираю «цветную» строку во время анимации выделения с переходом в синий цвет, мой пользовательский UIView (colorThumb) скрывается. Он снова становится видимым сразу после окончания анимации выбора / отмены выбора, но это приводит к появлению уродливого артефакта.

Что я должен сделать, чтобы исправить это? Разве я не вставляю подпредставление в нужном месте?

(Ничего особенного в didSelectRowAtIndexPath нет, я просто изменяю аксессуар ячейки на флажок или ничего и отменяю выбор текущего indexPath).

Ответы [ 21 ]

222 голосов
/ 31 декабря 2014

UITableViewCell изменяет цвет фона всех вложенных видов при выделении или выделении ячейки. Эту проблему можно решить, переопределив setSelected:animated и setHighlighted:animated ячейки Табличного представления и сбросив цвет фона представления.

В Задаче C:

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
   UIColor *color = self.yourView.backgroundColor;        
   [super setSelected:selected animated:animated];

    if (selected){
        self.yourView.backgroundColor = color;
    }
}

-(void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated{
    UIColor *color = self.yourView.backgroundColor;        
    [super setHighlighted:highlighted animated:animated];

    if (highlighted){
        self.yourView.backgroundColor = color;
    }
}

В Swift 3.1:

override func setSelected(_ selected: Bool, animated: Bool) {
    let color = yourView.backgroundColor         
    super.setSelected(selected, animated: animated)

    if selected {
        yourView.backgroundColor = color
    }
}

override func setHighlighted(_ highlighted: Bool, animated: Bool) {
    let color = yourView.backgroundColor
    super.setHighlighted(highlighted, animated: animated)

    if highlighted {
        yourView.backgroundColor = color
    }
}
121 голосов
/ 19 июля 2011

Это связано с тем, что ячейка табличного представления автоматически меняет цвет фона всех представлений внутри представления содержимого для выделенного состояния. Вы можете рассмотреть создание подкласса UIView для рисования вашего цвета или использование UIImageView с пользовательским растянутым изображением размером 1x1 px.

42 голосов
/ 27 января 2016

Нашел довольно элегантное решение вместо того, чтобы возиться с методами выделения / подсветки tableViewCell.Вы можете создать подкласс UIView, который игнорирует установку его цвета фона на чистый цвет.

Swift 3/4:

class NeverClearView: UIView {
    override var backgroundColor: UIColor? {
        didSet {
            if backgroundColor != nil && backgroundColor!.cgColor.alpha == 0 {
                backgroundColor = oldValue
            }
        }
    }
}

Swift 2:

class NeverClearView: UIView {
    override var backgroundColor: UIColor? {
        didSet {
            if CGColorGetAlpha(backgroundColor!.CGColor) != 0 {
                backgroundColor = oldValue
            }
        }
    }
}

Obj-C версия:

@interface NeverClearView : UIView

@end

@implementation NeverClearView

- (void)setBackgroundColor:(UIColor *)backgroundColor {
    if (CGColorGetAlpha(backgroundColor.CGColor) != 0) {
        [super setBackgroundColor:backgroundColor];
    }
}

@end
9 голосов
/ 03 мая 2016

Для Swift 2.2 это работает

cell.selectionStyle = UITableViewCellSelectionStyle.None

и причина объясняется @ Андрей

Это потому, что ячейка табличного представленияавтоматически изменяет цвет фона всех представлений в представлении содержимого для выделенного состояния.

9 голосов
/ 13 ноября 2012

Другим способом решения проблемы является заполнение представления градиентом базовой графики, например:

CAGradientLayer* gr = [CAGradientLayer layer];
gr.frame = mySubview.frame;
gr.colors = [NSArray arrayWithObjects:
                     (id)[[UIColor colorWithRed:0 green:0 blue:0 alpha:.5] CGColor]
                     ,(id)[[UIColor colorWithRed:0 green:0 blue:0 alpha:.5] CGColor]
                     , nil];

gr.locations = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0],[NSNumber numberWithFloat:1],nil];

[mySubview.layer insertSublayer:gr atIndex:0];
7 голосов
/ 08 января 2016

Вы можете cell.selectionStyle = UITableViewCellSelectionStyleNone;, затем установите backgroundColor на - (void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath

7 голосов
/ 02 ноября 2015

Вдохновленный Yatheesha B L х ответ Я создал категорию / расширение UITableViewCell, которое позволяет включать и выключать эту «функцию» прозрачности.

Swift

let cell = <Initialize Cell>
cell.keepSubviewBackground = true  // Turn  transparency "feature" off
cell.keepSubviewBackground = false // Leave transparency "feature" on

Objective-C

UITableViewCell* cell = <Initialize Cell>
cell.keepSubviewBackground = YES;  // Turn  transparency "feature" off
cell.keepSubviewBackground = NO;   // Leave transparency "feature" on

KeepBackgroundCell совместим с CocoaPods. Вы можете найти его на GitHub

3 голосов
/ 25 апреля 2017

Вдохновленный ответом Yatheesha BL * 1002. **.Итак, мы не будем вызывать супер метод.

В Swift:

override func setSelected(selected: Bool, animated: Bool) {    
    if(selected)  {
        contentView.backgroundColor = UIColor.red 
    } else {
        contentView.backgroundColor = UIColor.white
    }
}

override func setHighlighted(highlighted: Bool, animated: Bool) {
    if(highlighted) {
        contentView.backgroundColor = UIColor.red 
    } else {
        contentView.backgroundColor = UIColor.white
    }
}
3 голосов
/ 02 августа 2018

В каждом случае это Септы, чтобы избежать получения серого цвета для всех элементов в ячейке (если вы используете настраиваемую ячейку табличного представления):

  1. Установить selectionStyleв .none ? selectionStyle = .none

  2. Переопределить этот метод.

    func setHighlighted (_ выделено: Bool, animated: Bool)

  3. Вызовите супер, чтобы воспользоваться преимуществами суперустановки.

    super.setВыделено (выделено, анимировано: анимировано)

  4. Делайте любую логику подсветки, какую хотите.

    override func setHighlighted(_ highlighted: Bool, animated: Bool) {
          super.setHighlighted(highlighted, animated: animated)
          // Your Highlighting Logic goes here...
    }
    
3 голосов
/ 22 октября 2014

UITableViewCell по какой-то причине изменяет backgroundColor всех подпредставлений при выделении.

Это может помочь:

DVColorLockView

Используйте что-то подобное, чтобы UITableView не мог изменить цвет вашего вида во время выделения.

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