0

I have a UIToolbar containing 2 UIBArButton items. The toolbar is inside a UITableViewCell, and it fades in when the user selects a cell. The problem is that when the cell get's highlighted, it calls highlight on the barButtonItems as well, and they stay highlighted until the user manually tap the button once, and then it goes back to standard highlighting.

Is there a way to unhighlight the UIBarButtonItems manually?

I tried the overriding the cell's setSelected: and setHighlighted methods, and have tried calling both setSelected: and setHighlighted on the subviews as well, as shown below, and it doesn't seem to work. highlighted is called on 1 UIToolbarBackground and 2 UIToolbarTextButtons. Any ideas?

@implementation CustomCell

// I also tried doing this in setHighlighted: & setHighlighted:animated
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
   [super setSelected:selected animated:animated];

   for (UIView *view in self.toolbar.subviews)
   {
      if ([view respondsToSelector:@selector(setHighLighted:)])
      {
         [view performSelector:@selector(setHighLighted:) withObject:[NSNumber numberWithBool:NO]];
      }  
   }
}


@end
aryaxt
  • 76,198
  • 92
  • 293
  • 442
  • Hm wondering if the bar button items are not highlighted but selected? could be worth a shot – Carl Veazey Sep 28 '12 at 16:39
  • If you don't get an answer to this in a few hours, make a small demo project that shows the toolbar in one cell and demonstrates the problem, and add it to DropBox public folder or equiv.. Then the community can play with it and find a solution for you. – David H Sep 28 '12 at 16:40
  • I tried setSelected:, that wasn't the case :( – aryaxt Sep 28 '12 at 16:41
  • And you did verify that some of the subviews are getting `setHighLighted` called on them? – Carl Veazey Sep 28 '12 at 16:53
  • YES it's calling highlighted on UIBarButtonItems – aryaxt Sep 28 '12 at 17:14
  • Well since `UIBarButtonItem` is neither a `UIView` subclass (hence wouldn't be be in the `subviews` array), nor does it respond to `setHighlighted:`, that particular scenario is not happening. In fact I just noticed - you are asking if any of the subviews respond to `setHighLighted:` when the UIKit spelling of it doesn't have a capital "l". Furthermore, the setHighlighted methods on e.g. UIControl take a `BOOL` not `NSNumber` so it's not a good idea to call `performSelector:withObject:` for this method. cont'd... – Carl Veazey Sep 28 '12 at 17:21
  • I think it would be helpful for you to debug this and give us some details on whether that branch of the `if` statement is being taken, and what the view hierarchy of your `UIToolbar` instance is - it may give you a clue. SOrry to not notice these earlier - I'm taking too many mental shortcuts today! – Carl Veazey Sep 28 '12 at 17:22

2 Answers2

1

You are asking the toolbar's subviews if they respond to the selector setHighLighted: but all the UIKit classes that implement such a feature would respond to setHighlighted: (note the lowercase "l"). Here's an idea for you to try, I hope it works!

- (void)setHighlighted:(BOOL)highlighted
{
    [super setHighlighted:highlighted];

    for (UIView *view in self.toolbar.subviews)
    {
        if ([view respondesToSelector:@selector(setHighlighted:)])
        {
            ((UIControl *)view).highlighted = highlighted;
        }
    }
}

A couple of things I changed - only overriding setHighlighted: as the animated method should call this at the appropriate time. Also got rid of the performSelector: in favor of casting to UIControl. Not 100% true but should get us compiling.

Hope this helps!

Carl Veazey
  • 18,392
  • 8
  • 66
  • 81
  • That was a typo in the question, my code was correct, and this didn't solve the problem – aryaxt Sep 28 '12 at 17:34
  • @aryaxt so that branch of the if statement is indeed taken? That is, the `performSelector:withObject:` is indeed called? When you implemented my solution was that branch ever taken? – Carl Veazey Sep 28 '12 at 17:36
  • Yep it called highlighted on 1 UIToolbarBackground and 2 UIToolbarTextButtons, I think something is setting it back to highlighted after we unhighlight it – aryaxt Sep 28 '12 at 17:39
0

Finally got it to work:

Category:

@implementation UIToolbar (Additions)

- (void)setHighlighted:(BOOL)highlighted
{
    for (UIView *view in self.subviews)
    {
        for (UIView *subview in view.subviews)
        {
            if ([subview isKindOfClass:[UIButton class]])
            {
                ((UIButton *)subview).highlighted = highlighted;
            }
        }
    }
}

@end

Cell:

- (void)setSelected: (BOOL)selected animated: (BOOL)animated
{
    [super setSelected:selected animated:animated];

    [self.toolbar setHighlighted:NO];
}
aryaxt
  • 76,198
  • 92
  • 293
  • 442
  • Excellent, so I guess the buttons are a couple of levels deep in the view hierarchy? What's interesting is - how did they get highlighted in the first place in a way that the inverse wouldn't happen? – Carl Veazey Sep 28 '12 at 20:44
  • Exactly, I knew they weren't on the top level, but I was expecting the "chain of command" behavior. In my code I ended up writing a recursive method to ensure that every single view in the tree receives the call. – aryaxt Sep 28 '12 at 20:50