1

I subclassed UIButton in my app and there are many times when the highlight color stays even when I'm done pressing down the button. I can't figure out exactly what causes this since it only seems to happen by chance, but it seems to happen about 50% of the time. I'm very sure that this is reproducible. I often get this to happen when I have a button in a UITableViewCell and I click on it while the table view is still scrolling.

Is there something wrong with the way I'm overriding the setHighlighted method in the subclass? This is my implementation:

@implementation SCPFormButton

- (id)initWithFrame:(CGRect)frame label:(NSString *)label
{
    self = [super initWithFrame:frame];
    if (self) {
        UILabel *buttonLabel = [[UILabel alloc] init];
        buttonLabel.attributedText = [[NSAttributedString alloc] initWithString:[label uppercaseString] attributes:kButtonLabelAttributes];
        [buttonLabel sizeToFit];
        buttonLabel.frame = CGRectMake(kMaxWidth / 2 - buttonLabel.frame.size.width / 2, kStandardComponentHeight / 2 - buttonLabel.frame.size.height / 2, buttonLabel.frame.size.width, buttonLabel.frame.size.height);
        [self addSubview:buttonLabel];

        self.backgroundColor = kFormButtonColorDefault;
    }
    return self;
}

- (void)setHighlighted:(BOOL)highlighted
{
    self.backgroundColor = highlighted ? kFormButtonColorHighlighted : kFormButtonColorDefault;
    [self setNeedsDisplay];
}

@end
Matthew Quiros
  • 13,385
  • 12
  • 87
  • 132

2 Answers2

5

I would try to call super in your setHighlighted override. Indeed, Apple docs for UIControl state:

Specify YES if the control is highlighted; otherwise NO. By default, a control is not highlighted. UIControl automatically sets and clears this state automatically when a touch enters and exits during tracking and when there is a touch up.

So, it seems there is some kind of state handling going on in UIControl associated with this.

If this does not help, I would try to add a log trace so you can check which state the button is in when the touch is handled.

sergio
  • 68,819
  • 11
  • 102
  • 123
  • Why, of course. Can't believe I didn't think of that. I put it in my code and will see if this bug still ever shows up. – Matthew Quiros Jan 28 '14 at 08:59
  • The problem seems to be gone but I have to press long on the button before it gets highlighted. Quick presses don't show the highlighting animation, though it triggers the action. Is there anything else I've missed? – Matthew Quiros Jan 29 '14 at 17:02
  • Would you put an NSLog inside of `setHighlighted` and check whether it is called in case of short press? possibly you could need to detect a touch down (as opposed to touch up) and deal with the highlighted state from there... – sergio Jan 29 '14 at 17:34
  • The problem about long-pressing happens whenever I have a `UIButton` inside a `UITableViewCell` but not when it is contained within the main view of the view controller. Any suggestions? – Matthew Quiros Feb 09 '14 at 12:28
  • Never mind, found a discussion here: http://stackoverflow.com/questions/788085/uibutton-delayed-state-change – Matthew Quiros Feb 09 '14 at 12:35
0

You are missing the call to super. But, anyway, subclassing UIButton is not recommended, I would try to do it using setBackgroundImage:forState instead.

Odrakir
  • 4,254
  • 1
  • 20
  • 52
  • I don't see any problem with subclassing UIButton as any of default UIKit classes, can you elaborate this please ? – Macistador Sep 24 '15 at 09:04