Как отключить сообщение "highlight subviews" для UIView/UIViewController в SDK для iOS?
Я хочу использовать выделение по умолчанию на UITableViewCell
, когда он прослушивается. Тем не менее, я не хочу, чтобы пользовательские подзаголовки (и их дочерние объекты) получали сообщение для обновления своих выделенных состояний и, следовательно, нарушали свойство backgroundColor
.
Edit
Под "subview" я подразумеваю любой подкласс UIView
, а не только UITableViewCell
s.
Возможно, эта гипотетическая ситуация лучше сформулирует то, что я ищу. У меня есть один UITableViewCell. Назовите его c. Затем я добавляю один UIView (назовем его v) в качестве подзаголовка c. Когда я нажимаю c, я хочу, чтобы c стал выделен (стандартный синий фон с белым цветом шрифта), но я не хочу, чтобы v стал подсвечен. Как это сделать?
Ответы
Ответ 1
Прежде всего, UITableView перечисляет все подзапросы и отправляет их выделенные сообщения.
Таким образом, даже если вы положите UILabel в своем представлении, независимо от того, насколько он глубок, он пересекает все представления (используя свойство subviews).
Одно решение может быть (это IOS4 +), переопределяя свойство subviews и функцию выделения чит-таблицы, что у нас нет подзонов. Для этого нам нужно определить вызывающего, и если это метод подсветки tableview, мы не должны возвращать никакие подпункты вообще.
Мы можем создать простой подкласс UIView и переопределить subviews, как показано ниже.
- (NSArray *)subviews{
NSString* backtrace = [NSString stringWithFormat: @"%@",[NSThread callStackSymbols]];
if ([backtrace rangeOfString:@"_updateHighlightColorsForView"].location!=NSNotFound)
return [super subviews];
return [[NSArray new] autorelease];
}
- callStackSymbols доступен после IOS4 +
- _updateHighlightColorsForView - это метод UITableView, отвечающий за выделение всех дочерних элементов
Ответ 2
У меня есть класс, который наследует от UITableViewCell
, поэтому я исправил его переопределение setSelected:animated
следующим образом:
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
//Reset highlighted status to all the childs that i care for.
[self.someChild setHighlighted:NO];
[self.someOtherChild setHighlighted:NO];
}
Ответ 3
Использовать UITableViewCellSelectionStyleNone в ячейках таблицы.
Смотрите документацию API Apple.
Ответ 4
Я решил эту проблему, переопределив -(void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated
как это (работает только если subview является подклассом UIControl):
-(void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated {
BOOL subviewWasEnabled = mySubview.enabled; //check if the view is enabled
mySubview.enabled = NO; //disable it anyways
[super setHighlighted:highlighted animated:animated];
mySubview.enabled = subviewWasEnabled; //enable it again (if it was enabled)
}
Ответ 5
Недавно я искал тот же подход, и, честно говоря, я не мог найти способ программно сделать это, поэтому я как бы обманул свой выход из этого.
Так как я подчеркиваю уважение к изображениям, я закончил с помощью UIImageView
подал весь кадр моего UIView
и присвоил ему пустое изображение и нарисовал остальную часть представления над UIImageView
.
Ваш UIView
будет по-прежнему выделен, но вы не сможете его увидеть, потому что будет пустое изображение выше!
Надеюсь, это поможет, я знаю, что это, вероятно, не самый лучший подход, но дал мне результаты, которые я хотел
Ответ 6
Переопределить метод -(void)setHighlighted:(BOOL)highlight;
в подклассе UIControl
, чтобы он ничего не делал. В случае подкласса UIButton
вы можете сделать:
- (void)setHighlighted:(BOOL)highlighted {
return;
}
Ответ 7
Я не хотел, чтобы какое-либо из подзонов было выделено. Мое решение состояло в том, чтобы установить selectionstyle в UITableViewCellSelectionStyleNone и имитировать поведение выбора по умолчанию следующим образом (переопределяя setSelected в пользовательском подклассе UITableViewCell):
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
int backgroundViewTag = 888;
UIView *backgroundView = [self viewWithTag:backgroundViewTag];
if (selected) {
if (!backgroundView) {
backgroundView = [[[UIView alloc] initWithFrame:self.bounds] autorelease];
backgroundView.tag = backgroundViewTag;
backgroundView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
backgroundView.backgroundColor = [UIColor blueColor];
backgroundView.alpha = 0.0;
[self insertSubview:backgroundView atIndex:0];
}
if (animated) {
[UIView animateWithDuration:0.5 animations:^{
backgroundView.alpha = 1.0;
}];
} else {
backgroundView.alpha = 1.0;
}
} else if (backgroundView) {
if (animated) {
[UIView animateWithDuration:0.5 animations:^{
backgroundView.alpha = 0.0;
} completion:^(BOOL finished) {
}];
} else {
backgroundView.alpha = 0.0;
}
}
[super setSelected:selected animated:animated];
}
Ответ 8
Может быть, мы можем изменить выделенное состояние subviews в соответствии со своим представлением по умолчанию.
Таким образом, даже если он изменится на выделенное состояние, он будет выглядеть в состоянии по умолчанию.
Не уверен, что он работает, можете ли вы описать subviews больше.
Ответ 9
Я думаю, вам нужно либо отключить subviews (вероятно, нежелательно), либо подкласс, чтобы подпункты переопределили это поведение.
Ответ 10
Может быть, если вы подклассифицируете ваш subview и переопределите метод setHighlighted, чтобы ничего не делать или переопределить выделенный метод для возврата всегда NO.
Но UIView не имеет выделенного состояния, какие дочерние элементы UIView вы добавляете в свою ячейку?
Ответ 11
Итак, возможно, что-то вроде этого:
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
m_colors = [[NSMutableArray alloc] init];
for (UIView *view in [cell.contentView subviews]) {
[m_colors addObject:view.backgroundColor];
}
return indexPath;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
for (int x = 0; x < [m_colors count]; ++x) {
[[[cell.contentView subviews] objectAtIndex:x] setBackgroundColor:[m_colors objectAtIndex:x]];
}
[m_colors release];
m_colors = nil;
}
Ответ 12
Просто разместите свои представления внутри UIButton, и они не обновляются при подсветке. Вы не можете сделать это с помощью xib раскадровки только в runtime.
UIButton *button = [[UIButton alloc] initWithFrame:0, 0, cellWidth, cellHeight];
[button addSubview:anyView]; // This view don't change his background color
[cell addSubview:button];