IOS: использование UIAppearance для определения пользовательского цвета UITableViewCell

Если я устанавливаю атрибут backgroundColor в сгруппированном UITableViewCell, цвет фона успешно изменяется. Отлично.

Но я бы хотел использовать UIAppearance для изменения цвета фона на всех моих UITableViewCells, поэтому я могу сделать это в одном месте и повредить изменение. Здесь мой код:

[[UITableViewCell appearance] setBackgroundColor:[UIColor colorWithRed:30.0/255.0 green:30.0/255.0 blue:30.0/255.0 alpha:1.0]];

UITableViewCell реализует UIAppearance и UIAppearanceContainer, поэтому я бы подумал, что это сработает. Но это не так. Я также пытался использовать -[UITableViewCell appearanceWhenContainedIn:(Class)], и это тоже не работает.

Любые идеи?

Ответ 1

Обновление (2013/7/8) - Это исправлено в новых версиях iOS. Однако стоит знать, ориентированы ли вы на iOS 6 или ниже.

Вы можете обвинить Apple в этом, и это на самом деле довольно из них. Технически backgroundColor не настраивается через внешние прокси.

Из документации Apple:

Для поддержки настройки внешнего вида класс должен соответствовать протоколу UIAppearanceContainer, а соответствующие методы доступа должны быть отмечены с помощью UI_APPEARANCE_SELECTOR.

Если мы перейдем к классу типа UIBarButtonItem и посмотрим на свойство tintColor, мы увидим следующее:

@property(nonatomic,retain) UIColor *tintColor UI_APPEARANCE_SELECTOR;

Итак, поскольку он отмечен тегом UI_APPEARANCE_SELECTOR, мы знаем, что он работает с UIAppearance.

Здесь, где Apple особенно значимо: в UIView, backgroundColor не имеет тега селектора видимости, но все же работает с UIAppearance. Согласно всей документации Apple, она не должна, но все же это делает!

Это дает неверное впечатление, что он будет работать для всех подклассов UIView, включая UITableView. Это произошло раньше, в этом предыдущем ответе SO

Итак, нижняя строка заключается в том, что backgroundColor не должен работать вообще с UIAppearance, но по какой-то причине он работает на UIView. Не гарантируется работа над подклассами UIView, и он не работает вообще на UITableView. Извините, я не мог дать вам более положительный ответ!

Ответ 2

Вы можете создать свой собственный подкласс UITableViewCell, который соответствует UIAppearance и пометить пользовательский сеттер с помощью UI_APPEARANCE_SELECTOR. Затем установите ячейку backgroundColor в надклассе из вашего настраиваемого сеттера.

В приложении appDelegate

[[CustomCell appearance] setBackgroundCellColor:[UIColor redColor]];

В подклассе UItableView

@interface CustomCell : UITableViewCell <UIAppearance>

@property (nonatomic, weak) UIColor *backgroundCellColor UI_APPEARANCE_SELECTOR;

@implementation CustomCell

@synthesize backgroundCellColor;

-(void)setBackgroundCellColor:(UIColor *)backgroundColor
{
    [super setBackgroundColor:backgroundColor];
}

Я использую ARC в этом примере.

Ответ 3

Без подкласса! Выполнение этого в подклассе, вероятно, НЕ является лучшей практикой, особенно если вы хотите поразить все фоны tableView. Это много подкласса. Много потенциальных ошибок. Действительно беспорядок. Лучший способ сделать это - использовать категорию. Вам нужно будет установить его как для tableViewCell, так и для tableView. Я просто продемонстрирую одно для ячейки. Свойство на tableView, которое вы должны сделать, это свойство backgroundColor. NB. Я предлагаю свои методы с помощью "sat".

//.h

    #import <UIKit/UIKit.h>

@interface UITableViewCell (Appearance)<UIAppearance>
@property (strong, nonatomic) UIColor *satBackgroundColor UI_APPEARANCE_SELECTOR;
@end

//.m

#import "UITableViewCell+Appearance.h"

@implementation UITableViewCell (Appearance)

- (UIColor *)satBackgroundColor
{
    return self.backgroundColor;
}

- (void)setSatBackgroundColor:(UIColor *)satBackgroundColor
{
    self.backgroundColor = satBackgroundColor;
}


@end

Теперь в вашем приложении appDelegate или в каком-либо классе менеджера вы импортируете категорию и просто вызываете ее так, как если бы у нее был встроенный прокси-сервер.

UITableViewCell *cell = [UITableViewCell appearance];
cell.satBackgroundColor = [UIColor orangeColor];

Итак, теперь просто сделайте одно для свойства background стола tableView. Простой.

Ответ 4

Я использовал для этого категорию. Ниже приведен пример кода В файле .h напишите

*@interface UITableViewCell (MyCustomCell)
@property (nonatomic, weak) UIColor *backgroundCellColor UI_APPEARANCE_SELECTOR;
@end*

В файле .m напишите

*@dynamic backgroundCellColor;
-(void)setBackgroundCellColor:(UIColor *)backgroundColor
{
    [super setBackgroundColor:backgroundColor];
}*

Это сработало для меня.:) Спасибо Нейту!!!