Change UILabel based on UIButton control events

1.6k views Asked by At

I have a UIButton that has a default image, and another image for highlight/selected image. When pressing the button, the button's image changes to the highlighted, then to the selected if the touchUp was inside. The usual stuff.. All setup within IB.

However, I am trying to set a label over the button, in a very tricky place (not aligned, hard coded).

I tried adding a Label over the button in IB. Problem: I need the label's text color to change as the button's control state changes.

So, I created a UIButton subclass, added a UILabel Outlet, and by overriding the following methods:

- (void)touchesBegan/Moved/Cancelled/Ended:...;
- (void)setSelected:...

I was able to achieve what I want... BUT! When I quickly click the button, the change is not reflected. and sometimes it doesn't work properly... I even used asynchronous calls... No use.

So, I headed to the UIButton's titleLabel. I tried to use it with no luck.

So, I tried UIButton setTitle: forState:, no use ... Help?


Extra Details:

- (id)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self.titleLabel setFrame:CGRectMake(0, 0, 100, 100)];
        [self.titleLabel setText:@"THE TITLE LABEL"];
        [self.titleLabel setHidden:NO];

        [self.imageView setAlpha:0.2f];
        NSLog(@"%@", self.subviews);


        [self setTitle:@"DEFAULT!!" forState:UIControlStateNormal];
    }
    return self;
}

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

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

}

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

}

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

}

- (void)setSelected:(BOOL)selected {
    [super setSelected:selected];
    [self performSelector:@selector(check) withObject:nil afterDelay:0.1];
}

- (void)check {
    if (self.isSelected || self.state == UIControlStateHighlighted || self.state == UIControlStateSelected) {
        [_label setHighlighted:YES];
    } else {
        [_label setHighlighted:NO];
    }
}

OUTPUT:

(
    "<UIImageView: 0x8b24930; frame = (0 0; 243 39); clipsToBounds = YES; alpha = 0.2; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8b248e0>>",
    "<UIButtonLabel: 0x8b247a0; frame = (0 0; 100 100); text = 'THE TITLE LABEL'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8b25000>>"
)
2

There are 2 answers

0
Mazyod On BEST ANSWER

The best answer I found, after all these months, is to override:

- (CGRect)titleRectForContentRect:(CGRect)contentRect;

To position the label the way I want. This makes me able to make use of:

[self setTitleColor:[UIColor offWhiteColor] forState:UIControlStateNormal];
[self setTitleColor:[UIColor burntCarbonColor] forState:UIControlStateSelected];
[self setTitleColor:[UIColor burntCarbonColor] forState:UIControlStateHighlighted];

For the more curious:

- (CGRect)titleRectForContentRect:(CGRect)contentRect {
    CGSize margin = CGSizeMake(15.f, 5.f);
    CGRect clay = contentRect;
    clay = CGRectInset(clay, margin.width, 0.f);
    clay.origin.x += margin.width;
    clay.origin.y += margin.height;

    return clay;
}
1
piyush Bageria On

you need to set the background image for UIButton...may be you are setting the image propertry of button...that why your label is being overlapped by image....

[optionButtonOutlet  setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];

 [optionButtonOutlet setBackgroundImage:[UIImage imageNamed:@"[email protected]" ]forState:UIControlStateNormal];