What's wrong with my checkbox drawing?
I have built a UIButton subclass which is very simple. Everything works (for example, I get awaited events, drawRect method is called when I await, etc.), but my image is not being drawn. I have verified that my image is not zero and that my images are different.
the code:
-(void)awakeFromNib {
[super awakeFromNib];
[self addTarget:self action:@selector(buttonClick) forControlEvents:UIControlEventTouchUpInside];
self.state=YES;
}
-(void) buttonClick {
self.state = !self.state;
[self setNeedsDisplay];
}
-(void)drawRect:(CGRect)rect {
UIImage *img = nil;
if (self.state) {
img = [self backgroundImageForState:UIControlStateSelected];
}
else {
img = [self backgroundImageForState:UIControlStateNormal];
}
[img drawInRect:rect];
}
Checking the value of 'img' before it is drawn:
Printing description of img:
<UIImage: 0x52a710>
(gdb) continue
Printing description of img:
<UIImage: 0x52a5d0>
Background images are set in the NIB. If I change the selected state in IB, I can see that the image is displayed correctly. I am also getting the correct image from the call (which I am not doing if I am trying to get an imageForState that is not set in the NIB).
The reason for subclassing is because I need a checkbox. UIButton doesn't, and UISwitch is horribly ugly for all but the most utilitarian.
Thoughts?
Thanks.
t
Edit: Added all the code for the subclass
a source to share
Just because UIImage is not null does not mean that it contains image data.
Check the case of the file name.
I've done this several times:
@ "CheckBox.png" and @ "checkbox.png" are two different iPhone names.
It seems like you can do a little early optimization too.
I wouldn't dive into drawRect: for my first option.
Use a UIButton subclass (you only need a subclass to track the state). Set the button to IB and place it wherever you want. Connect the button to the below method and just swap images for click:
- (IBAction)toggle:(id)sender{
MyButtonSubClass *aButton = (MyButtonSubClass*)sender;
[aButton toggleChecked];
if(aButton.checked)
[aButton setImage:checkedImage forState:UIControlStateNormal];
else
[aButton setImage:uncheckedImage forState:UIControlStateNormal];
}
Optional, you cannot subclass UIButton and track state in controller
a source to share
Where are you setting backgroundImageForState? Are you sure this is the correct image? iPhone OS can provide you with a transparent (blank) image by default.
Secondly, I would not use the passed "rect" parameter to draw the image. It just tells you what area he wants you to redraw, not something else. Use instead
CGRectMake(0, 0, img.size.width, img.size.height)
or something similar.
Finally, why are you making your own drawing? I did something very similar and you absolutely don't need to subclass and implement drawRect
. UIButton has an extremely rich set of options built in for images, including "highlighted" and "selected" images that will automatically draw upon user interaction. Let us know what you need to do.
a source to share