Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

wyattbiker

macrumors member
Original poster
Mar 7, 2009
42
4
I made a custom button and added an image using IB. In my code I use drawRect: to draw a line on the button's context.

The problem I have is the line is drawn behind the image.

I am trying to figure if there is something I should be doing to draw on top of the image (or on the image itself). Same thing happens if I just have a title on the button. The line is drawn behind.

Any ideas or functions to look at would be appreciated. Here is the code I use to draw a line.

Code:

Code:
@implementation UIButtonX  // subclass of UIButton

-(void)drawRect:(CGRect)rect{
     CGContextRef ctx=UIGraphicsGetCurrentContext();
     CGContextSetStrokeColorWithColor(ctx,[ UIColorredColor].CGColor);
    CGContextBeginPath(ctx); 
     CGContextSetLineWidth(ctx, 3.0);
    CGContextMoveToPoint(ctx,rect.origin.x, rect.origin.y);
    CGContextAddLineToPoint(ctx, rect.size.width,rect.size.height);
    CGContextDrawPath(ctx,kCGPathStroke);
}

@end
 
UIButtons have a backgroundImage property, as well. Perhaps try using that instead?

I had tried. It is actually worse. The image blocks everything.

I just discovered this happens even if I write to a UIView with an image or any controls. The drawing takes place behind them.

I am thinking perhaps I should be writing to the context of the image and not the button. But I dont know how to get the image context.
 
Have you looked at this

https://forums.macrumors.com/threads/561572/

Also, Three20 might have something for this

http://groups.google.com/group/three20

BTW, the button undoubtedly has a label that draws the title.

From reading the first link, it sounds like the only way to do this is get the image off the button in a bitmap structure, draw on it, convert back as an image and set it back in to the button. Not quite what I hoped for since it is a lot of work.

This same problem happens with UIViews. If you add an image to a view you cannot then draw on top of it (or at least I cant figure out how).

Took a quick look at Three20 but don't know if they have anything. I will have to look further.
 
From reading the first link, it sounds like the only way to do this is get the image off the button in a bitmap structure, draw on it, convert back as an image and set it back in to the button.

Not sure why you think that. The code in that link is almost the same as yours except he strokes a path and you're drawing a path.
 
Not sure why you think that. The code in that link is almost the same as yours except he strokes a path and you're drawing a path.

Yes, and my code, just like his, works fine. The problem though is that the image is shown on top of my drawing (in his case he happens to be using title instead of image).

It's very easy to try and see. Take any ole project you have lying around and subclass a button and put the code I posted in the subclass. Make sure button has an image attached to it.
 
I had tried. It is actually worse. The image blocks everything.
A background image blocks everything but a regular image doesn't? Forgive me, but that sounds totally backwards. If I get a chance I may look into this further. Perhaps this is worthy of bug-submission if that's the case.

I just discovered this happens even if I write to a UIView with an image or any controls.
How are you adding your image or controls to your UIView? Thru addSubview:? I would expect them to draw over top since they would probably get called after your main view is drawn.
 
OK, I assumed you were trying to draw underlined text. My mistake.

So you're adding an image to a button and want the image to have a line on it. Either draw the line on the image before you give it to the button, which is how I'd do it or add your own class as a subview to the button. This class will draw the image and then draw the line onto the image.

The button has either a label or imageview as subviews. That they draw after the button draws makes total sense. I doubt there's anything you can do about that. You could conceivably adjust the alpha of the image you're adding so your line shows through it, but that might not look good.
 
Okay, did some investigating. And, wyattbiker, you're right. Even setting the background image doesn't work. It seems that drawRect: gets called before any of the other drawing bits of a button (background image, image, title). Anyways, if you add the image drawing into your drawRect:, you should be golden. Here's the code for what I got working:
Code:
@implementation UIButtonX

-(void)drawRect:(CGRect)rect{
    CGContextRef ctx=UIGraphicsGetCurrentContext();

    UIImage *image = [UIImage imageNamed:@"image.jpg"];
    [image drawInRect:self.bounds];
	
    CGContextSetStrokeColorWithColor(ctx,[UIColor redColor].CGColor);
    CGContextBeginPath(ctx); 
    CGContextSetLineWidth(ctx, 3.0);
    CGContextMoveToPoint(ctx,rect.origin.x, rect.origin.y);
    CGContextAddLineToPoint(ctx, rect.size.width,rect.size.height);
    CGContextDrawPath(ctx,kCGPathStroke);
}

@end
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.