How to disable “highlight subviews” message for UI

2019-03-13 02:10发布

I want to use the default highlight on a UITableViewCell when it is tapped. However, I do not want custom subviews (and their subviews) to receive the message to update their highlighted states and therefore disrupt the backgroundColor property.

Edit
By "subview" I mean any UIView subclass, not just UITableViewCells.

Perhaps this hypothetical situation will better articulate what I'm looking for: I have one UITableViewCell. Call it c. I then add one UIView (call it v) as a subview of c. When I tap c, I want c to become highlighted (standard blue background with white font color), but I do not want v to become highlighted. How do I make this happen?

12条回答
聊天终结者
2楼-- · 2019-03-13 02:36

Use UITableViewCellSelectionStyleNone on the table cells.

See the apple API documentation.

查看更多
做个烂人
3楼-- · 2019-03-13 02:38

May be we can change the highlighted state of subviews to match their default view.

That way even if it changes to highlighted state it will look to be in default state.

Not sure if it works, can you describe subviews more.

查看更多
Summer. ? 凉城
4楼-- · 2019-03-13 02:38

I think you need to either disable the subviews (likely undesirable) or subclass the subviews to override this behavior.

查看更多
Animai°情兽
5楼-- · 2019-03-13 02:41

Maybe if you subclass your subview and override the setHighlighted method to do nothing or override the highlighted method to return always NO.

But UIView doesn't have the highlighted state, what kind of UIView childs you add to your cell ?

查看更多
家丑人穷心不美
6楼-- · 2019-03-13 02:42

First of all, UITableView enumarates all the subviews, and sends them highlight messages.

So even if you put a UILabel in your view, no matter how deep it is, it traverses all views (by using subviews property).

One solution can be (which is IOS4+), overriding subviews property, and cheat tableview's highlight function that we do not have any subviews. To do that we need to determine the caller, and if it is tableview's highlight method, we should return no subviews at all.

We can create a simple UIView subclass and override subviews like below.

- (NSArray *)subviews{
    NSString* backtrace = [NSString stringWithFormat: @"%@",[NSThread callStackSymbols]];
    if ([backtrace rangeOfString:@"_updateHighlightColorsForView"].location!=NSNotFound)
        return [super subviews];   

    return [[NSArray new] autorelease];
}
  • callStackSymbols is available after IOS4+
  • _updateHighlightColorsForView is the UITableView's method, responsible for highlighting all children
查看更多
\"骚年 ilove
7楼-- · 2019-03-13 02:45

I solved this problem by overriding -(void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated like this (only works if the subview is a subclass of 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)
}
查看更多
登录 后发表回答