Search code examples
iosios6uibuttonsubclass

I am subclassing UIButton to create my own custom button look, however it is not redrawing on all touch events


I am trying to create a button subclass which colours a button (when it is selected) dependent on whether it is the correct answer to a multiple choice question.

I am doing this like so: In my UIViewController:

- (IBAction)answerQuestion:(id)sender {
    QGPrettyButton *answerButton;
    if ([sender isKindOfClass:[UIButton class]]) {
        answerButton = (QGPrettyButton *)sender;
        answerButton.isCorrectAnswer = [self.quizGame checkAnswer:self.currentQuestion answer:answerButton.titleLabel.text];
        [self performSelector:@selector(removeQuestion) withObject:nil afterDelay:TIME_TO_SHOW_CORRECT_ANSWER];
    }
}

In the setter method for isCorrectAnswer:

- (void)setIsCorrectAnswer:(BOOL)isCorrectAnswer
{
    self.selected = YES;
    [self setNeedsDisplay];
    [self performSelector:@selector(returnToUnselected) withObject:nil afterDelay:TIME_TO_SHOW_CORRECT_ANSWER];
    _isCorrectAnswer = isCorrectAnswer;
}

- (void)returnToUnselected
{
    self.selected = NO;
    [self setNeedsDisplay];
}

And in my draw method for QGPrettyButton:

CGFloat hue = UNSELECTED_HUE;
CGFloat saturation = UNSELECTED_SATURATION;

if (self.state == UIControlStateHighlighted) {
    hue = HOVERED_HUE;
    saturation = HOVERED_SATURATION;
}
if (self.state == UIControlStateSelected) {
    hue = self.isCorrectAnswer ? CORRECT_HUE : INCORRECT_HUE;
}

Overriding touch :

-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesBegan:touches withEvent:event];
    [self setNeedsDisplay];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesMoved:touches withEvent:event];
    [self setNeedsDisplay];

}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesCancelled:touches withEvent:event];
    [self setNeedsDisplay];
    [self performSelector:@selector(hesitateUpdate) withObject:nil afterDelay:0.1];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesEnded:touches withEvent:event];
    [self setNeedsDisplay];
    [self performSelector:@selector(hesitateUpdate) withObject:nil afterDelay:0.1];
}

This is all working fine if you mouse down on the button and release again, but if you tap it really quickly the IBAction is called but the colour of the button is not set and it just flashes quickly white then back to the unselected colour...


Solution

  • You can try the highlighted property of a UIView.

    If you want it to be highlighted do:

    self.highlighted = YES;
    

    and vice versa.