views:

1724

answers:

2

I'm adding a custom background image to my UINavigationBar by overriding the drawRect via a category.

- ( void )drawRect:( CGRect )rect{
    [[UIImage imageNamed:@"navbar.png"] drawInRect:CGRectMake( 0, self.frame.size.height-44, self.frame.size.width, 44 )];
}

This solution seems to work fine, until you try to make use of navigationitem.prompt property. Instead of doing a smooth animation of presenting the prompt, it does it abruptly.

Are there any suggestions on how to remedy this ? Or an alternative way of setting a background image.

PS. I'm trying to avoid just adding a background image as a subview because of the way things rearrange when views push/pop. And I'd hate to sendSubviewToBack in every view's viewDidAppear.

TIA!

EDIT: I also tried method swizzling, which would work fine if I could just let my image stretch, but since the image isn't stretchable, I need to figure out how to tap into the animation that happens to do a shift instead of a stretch.

EDIT: see my hacky answer below

A: 

So very "hacky", but this is the closest I can get it to do what I want...

Basically when method swizzling, simply letting the image stretch wasn't working well for me because I also had rounded corners. So instead I made the corners a separate transparent img and add it as a subview so they wouldn't get affected by the stretch animation.

So my category now looks like this..

#import "UINavigationBar+custom.h"

#define cornersTag 1

@implementation UINavigationBar (UINavigationBarCategory)

-(void)setCornersIfNeeded{
 UIImageView *corners = (UIImageView*)[self viewWithTag:cornersTag];
 if(!corners){
  UIImage *img = [[UIImage imageNamed:@"navbar_corners.png"] stretchableImageWithLeftCapWidth:10 topCapHeight:0];
  corners = [[[UIImageView alloc] initWithImage:img] autorelease];
  corners.frame = CGRectMake(0, 0, self.frame.size.width, img.size.height);
  corners.tag = cornersTag;
  [self addSubview:corners];
 }
}

- (void)customDrawRect:( CGRect )rect{
 [self customDrawRect:rect];
 [[UIImage imageNamed:@"navbar.png"] drawInRect:rect]; 
 [self setCornersIfNeeded];
}

@end

for more on method swizzling... http://www.cocoadev.com/index.pl?MethodSwizzling and http://stackoverflow.com/questions/1637604/method-swizzle-on-iphone-device/1637693#1637693

dizy
I'm not sure I understand why you need a second image and all to prevent the image from being stretched... you're doing all the drawing, don't you control the aspect ratio at which it's being drawn? Or is the issue that the image always needs to fill the view, but the view can exist in different shapes? (Also, be careful, because the rect passed to drawRect may *not* be the full frame/bounds of the view.)
Sixten Otto
If I have an image with round corners and I let it stretch, the corners get distorted. If I don't let it stretch and would just like it to slide down, well that's something I can't get it to do. It seems like it draws the expanded state frame once, but stretches it down to the collapsed state, and then animates the expand stretching it back to the original expanded draw. In what situation may the rect not be full frame/bounds ? If It's working properly for me, should I still be worried ?
dizy
A: 

I am a beginner with Objective C, and I also am interested in having my own custom image for my navigation bar. I am wondering where you would put the above code in my code?

Jon