UITableViewCell делает фон метки прозрачным при выделении - PullRequest
41 голосов
/ 03 июня 2010

У меня есть UIlabel на UITableViewCell, который я создал программно (то есть не перо или подкласс).

Когда ячейка подсвечивается (становится синей), все цвета фона UILabels становятся прозрачными. У меня есть 2 UILabels, где я не хочу, чтобы это было так. В настоящее время я использую UIImageViews за UILabel, чтобы он выглядел так, как будто цвет фона не меняется. Но это кажется неэффективным способом сделать это.

Как я могу остановить изменение цвета фона определенного UILabel при выделении UITableViewCell?

Ответы [ 10 ]

51 голосов
/ 02 марта 2014

Вам необходимо создать подкласс UITableViewCell и переопределить следующие два метода:

Objective-C:

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

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

Swift

override func setSelected(selected: Bool, animated: Bool) {
    let color = self.myLabel.backgroundColor
    super.setSelected(selected, animated: animated)
    self.myLabel.backgroundColor = color
}

override func setHighlighted(highlighted: Bool, animated: Bool) {
    let color = self.myLabel.backgroundColor
    super.setHighlighted(highlighted, animated: animated)
    self.myLabel.backgroundColor = color
}
46 голосов
/ 19 февраля 2014

Другой способ предотвратить изменение цвета фона при выделении - установить свойство backgroundColor для метки layer вместо самой метки.

#import <QuartzCore/QuartzCore.h>

...

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

    // Get a table cell
    UITableViewCell *cell = [tableView dequeueReusableCellForIdentifier:@"cell"];

    // Set up the table cell
    cell.textLabel.text = @"This is a table cell.";

    // If you're targeting iOS 6, set the label's background color to clear
    // This must be done BEFORE changing the layer's backgroundColor
    cell.textLabel.backgroundColor = [UIColor clearColor];

    // Set layer background color
    cell.textLabel.layer.backgroundColor = [UIColor blueColor].CGColor;

    return cell;
}

layer не зависит от выделения или выбора ячейки.

40 голосов
/ 19 октября 2010

Или подкласс метки, которую вы не хотите менять цвет:

@interface PersistentBackgroundLabel : UILabel {
}

- (void)setPersistentBackgroundColor:(UIColor*)color;

@end


@implementation PersistentBackgroundLabel

- (void)setPersistentBackgroundColor:(UIColor*)color {
    super.backgroundColor = color;
}

- (void)setBackgroundColor:(UIColor *)color {
    // do nothing - background color never changes
}

@end

Затем установите цвет один раз явно, используя setPersistentBackgroundColor :. Это предотвратит изменение цвета фона в любом месте без использования вашего собственного явного метода изменения цвета фона.

Преимуществом этого является также устранение четкого фона в метке во время переходов.

5 голосов
/ 31 марта 2015

Возможно, я ошибаюсь, но я не мог найти прямой переопределения существующего метода получения / установки в Swift. Основываясь на ответе пользователя user 479821, я нашел обходной путь, который, кажется, дает желаемые результаты. Я добавил аннотации IBDesignable / IBInspectable на случай, если вы используете раскадровку, которая отображает последний цвет в редакторе.

@IBDesignable
class PersistentBackgroundLabel: UILabel {
    @IBInspectable var persistentBackgroundColor: UIColor = UIColor.clearColor() {
    didSet {
        super.backgroundColor = persistentBackgroundColor
    }
    }

    override var backgroundColor: UIColor? {
    didSet {
        if backgroundColor != persistentBackgroundColor {
            backgroundColor = persistentBackgroundColor
        }
    }
    }
}
3 голосов
/ 06 декабря 2011

У меня та же проблема, и я думаю, что это своего рода ошибка в фреймворке UIKit. Слава Богу, я нашел обходной путь: порядок имеет значение !!! Просто следуйте последовательности:

- (void)tableView:(UITableView *)t willDisplayCell:(UITableViewCell*)c forRowAtIndexPath:(NSIndexPath *)i {
UIColor *bgc = [UIColor redColor];
// Set up the cell in following order:
c.textLabel.backgroundColor = bgc;
c.backgroundColor = bgc;
c.textLabel.text = @"foo";
}

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

Это не было случайным поведением, это произошло в первый раз, когда клетки были повторно использованы, ни когда они были созданы, ни когда они были повторно использованы повторно. С обходным путем он всегда работает нормально.

2 голосов
/ 03 июля 2015

Установить цвет фона для label.layer.backgroundColor это можно исправить.

Кажется, что ячейка изменит фоновый цвет UILabel при выделении.

1 голос
/ 05 февраля 2014

Я просто создаю флаг в подклассе UILabel, чтобы отключить изменение цвета фона после awakeFromNib или init. Это позволяет начальному цвету, установленному в раскадровке, вступить в силу. И нам не нужно вызывать никаких дополнительных методов.

@implementation MWPersistentBGLabel {
    BOOL disableBackgroundColorChange;
}

- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self setup];
    }
    return self;
}

- (void)awakeFromNib {
    [super awakeFromNib];
    [self setup];
}

- (void)setup {
    // disable background color change after setup is called
    disableBackgroundColorChange = YES;
}

// if we ever have to change the color later on, we can do so with this method
- (void)setPersistentBackgroundColor:(UIColor*)color {
    [super setBackgroundColor:color];
}

- (void)setBackgroundColor:(UIColor *)color {
    if (!disableBackgroundColorChange) {
        [super setBackgroundColor:color];
    }
    // do nothing - background color never changes
}

@end
0 голосов
/ 18 марта 2013

Я не мог получить принятый ответ на работу; не то, чтобы я думал, что ответ неправильный (отнюдь нет - похоже, это правильный путь), но когда я писал свое первое приложение для iOS, моя голова уже кружилась с подклассами. Поэтому я решил обмануть.

Допустим, пользовательская ячейка контролировалась классом TableViewCell. Я создал файл пикселя .png правильного цвета фона и создал объект UIImageView в своей пользовательской ячейке. Я использовал инспектор Атрибутов, чтобы установить изображение по умолчанию и использовал «Масштабировать до заливки». Для большей визуальной привлекательности я добавил следующее в пользовательские атрибуты среды выполнения в инспекторе удостоверений:

KeyPath                Type         Value
layer.cornerRadius     Number       4
layer.masksToBounds    Boolean      YES

Вуаля, закругленные углы по дешевке.

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

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

cell.deviceDetailBackground.image = [UIImage imageNamed:@"detailBackground2.png"];

Где 'cell' - это воплощение моей пользовательской ячейки в методе cellForRowAtIndexPath, созданном с использованием TableViewCell *cell;. Нет данных для отображения?

cell.deviceDetailBackground.image = nil;

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

0 голосов
/ 03 июня 2010

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

0 голосов
/ 03 июня 2010

В моих приложениях мне нужно было изменить синий цвет стиля выбора uitableviewcell, поэтому мне пришлось настроить представление uiimage, когда я щелкаю ячейку, которая выделяется как Imageview. И я удалил выделенную ячейку, когда вернулся в представление. И я не мог ясно понять твою проблему. Так что, просто учитывая мой код и попробуйте этот,

   cellForRowAtIndexPath Method:

CGRect a=CGRectMake(0, 0, 300, 100);
UIImageView *bImg=[[UIImageView alloc] initWithFrame:a];
bImg.image=[UIImage imageNamed:@"bg2.png"]; 
[bImg setContentMode:UIViewContentModeScaleToFill];
cell.selectedBackgroundView=bImg;
[bImg release];


   -(void)viewWillAppear:(BOOL)animated {
  [super viewWillAppear:YES];

  NSIndexPath *deselect = [self.tableView indexPathForSelectedRow];
  [self.tableView deselectRowAtIndexPath:deselect animated:NO];

   }

Best Of Luck

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