selectedBackgroundView на UITableViewCell применяется ко всем представлениям в ячейке - PullRequest
4 голосов
/ 29 октября 2010

У меня отображается ячейка таблицы, которая показывает изображение пользователя, имя и текст. Изображение пользователя имеет размер 50x50, но я хочу, чтобы вокруг него была рамка, поэтому я установил вид для центрирования изображения и установил рамку на 52x52, а затем установил цвет фона этого вида на цвет моей границы. Это показывает 1 пиксель границы вокруг изображения.

Я также хочу показать 30-пиксельную рамку справа от ячейки, когда ячейка выбрана. Я попытался сделать это, создав UIView размером с рамку ячейки, а затем добавив подпредставление для этого представления с UIView шириной и цветом фона, которые я хотел бы. Затем я устанавливаю это представление для selectedBackgroundView ячейки.

Проблема здесь в том, что selectedBackgroundView ячейки применяется к фону всех представлений внутри ячейки. Поэтому, когда я выбираю ячейку, для «границы» изображений устанавливается выбранный цвет фона ячейки, а остальные 30-пиксельные «рамки», которые я добавляю, также меняются на этот цвет фона.

Код внутри моей ячейкиForRowAtIndexPath:

cell = (UserCellView *) currentObject;

UIView *c = [[UIView alloc ] initWithFrame:CGRectMake(0, 0, 30, cell.frame.size.height)];
c.backgroundColor = [[UIColor alloc] initWithRed:64/255.0 green:64/255.0 blue:64/255.0 alpha:1.0];

UIView *v = [[UIView alloc ] initWithFrame:cell.frame];             
v.backgroundColor = [[UIColor alloc] initWithRed:35/255.0 green:35/255.0 blue:35/255.0 alpha:1.0];              

[v addSubview:c];       

cell.selectedBackgroundView = v;

[c release];
[v release];

Ответы [ 5 ]

10 голосов
/ 10 марта 2011

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

Iсделал что-то вроде этого:

@interface TestView : UIView {
}
@end
@implementation TestView
-(void)setBackgroundColor:(UIColor*)c {
  // Breakpoint here.
  NSLog("setBackgroundColor: %@",c);
  [super setBackgroundColor:c];
}
@end

...

UIView * v = [[[UIView alloc] initWithFrame:(CGRect){{0,0},{20,20}}] autorelease];
v.backgroundColor = [UIColor magentaColor];
UIView * v2 = [[[TestView alloc] initWithFrame:(CGRect){{5,5},{10,10}}] autorelease];
v2.backgroundColor = [UIColor yellowColor];
[v addSubview:v2];
cell.selectedBackgroundView = v;

Конечным результатом является то, что -setBackgroundColor: вызывается из -[UITableViewCell _setOpaque:forSubview:] при выборе представления с чем-то вроде UIDeviceWhiteColorSpace 0 0 (то есть [UIColor clearColor]).

Или, другими словами, цвет фона некоторых из подпредставлений устанавливается на [UIColor clearColor], пока ячейка выбрана, что позволяет selectedBackgroundView просвечивать.Я думаю это происходит потому, что общая оптимизация заключается в том, чтобы дать textLabel / detailTextLabel цвет фона таблицы (например, белый), чтобы он рисовался быстрее, но это означает, что цвет фона должен быть сброшен, когда ячейка

Самое простое решение - использовать вместо этого изображение: изображение 1 на 1 пиксель правильного цвета в UIImageView будет работать, если немного грязно.(У меня была эта проблема при рисовании пользовательских разделительных линий с UIViews высотой 1 пиксель, поэтому я просто включил разделитель в фоновое изображение.)

Альтернативное решение - использовать вместо этого CALayer: добавить подслой 52x52к слою UIImageView и установите цвет фона подслоя.Я почти уверен, что UITableViewCell просто обходит иерархию представления, поэтому он должен игнорировать пользовательские слои.(Большим недостатком слоев является то, что они не имеют автоматического размера, что делает их неподходящими для моих целей, и означает, что правая граница 30px не будет иметь автоматического размера.)

Обходной путь - это создать подкласссоответствующие представления и игнорировать -setBackgroundColor:, если оно равно [UIColor clearColor].

1 голос
/ 15 мая 2013

Сначала добавьте это в ваш файл

#import <QuartzCore/QuartzCore.h>

Затем превратите ваш взгляд в изображение с помощью ...

    UIView *rowView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 1.0, 60.0)];
    rowView.backgroundColor = [UIColor colorWithRed:35/255.0 green:35/255.0 blue:35/255.0 alpha:1.0];        

    UIGraphicsBeginImageContext(rowView.bounds.size);
    [rowView.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *yourImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

Затем вместо добавления UIViewв вашу ячейку просто добавьте UIImageView с "yourImage".

1 голос
/ 06 марта 2013

Простое, но неприятное в обслуживании решение - переопределить setSelected: animated: и setHighlighted: animated: с реализациями, переустанавливающими различные фоны, которые вы хотите.Что-то вроде:

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    [super setSelected:selected animated:animated];
    self.childView.backgroundColor = [UIColor blueColor]; // whichever you want
}
0 голосов
/ 25 сентября 2013

Простым решением, если затронутый вид может быть пользовательским подклассом, является переопределение -setBackgroundColor:

- (void)setBackgroundColor:(UIColor *)color
{
    // Ignore requests and do nothing
}

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

- (void)setColor:(UIColor *)color
{
    [super setBackgroundColor:color];
}

(или, возможно, может напрямую сообщать базовый CALayer)

0 голосов
/ 29 октября 2010

вам нужно будет настроить contentView ячеек и обработать делегат tableView:cellForRowAtIndexPath

См. Публикацию здесь

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