Drawing on top of image/title on a UIButton

Discussion in 'iOS Programming' started by wyattbiker, Aug 8, 2009.

  1. wyattbiker macrumors member

    Joined:
    Mar 7, 2009
    #1
    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
    
    
     
  2. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #2
    UIButtons have a backgroundImage property, as well. Perhaps try using that instead?
     
  3. wyattbiker thread starter macrumors member

    Joined:
    Mar 7, 2009
    #3
    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.
     
  4. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #4
  5. wyattbiker thread starter macrumors member

    Joined:
    Mar 7, 2009
    #5
    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.
     
  6. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #6
    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.
     
  7. wyattbiker thread starter macrumors member

    Joined:
    Mar 7, 2009
    #7
    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.
     
  8. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #8
    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.

    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.
     
  9. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #9
    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.
     
  10. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #10
    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
    
     

Share This Page