UINavigationBar's drawRect is not called in iOS 5.0

后端 未结 7 1690
清歌不尽
清歌不尽 2020-11-28 07:59

I\'ve overrided(placed in category, or swizzled) UINavigationBar\'s drawRect to show custom background. In iOS 5 it\'s not working. What should I do?

相关标签:
7条回答
  • 2020-11-28 08:04
    @implementation UINavigationBar (MyCustomNavBar)
    
    - (void)setBackgroudImage:(UIImage*)image
    {
        CGSize imageSize = [image size];
        self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, imageSize.height);
        UIImageView *backgroundImage = [[UIImageView alloc] initWithImage:image];
        backgroundImage.frame = self.bounds;
        [self addSubview:backgroundImage];
        [backgroundImage release];
    }
    @end
    

    The above swizzling will allow you to set any custom background image for the UINavigationBar(iOS5 & iOS4).

    0 讨论(0)
  • 2020-11-28 08:04

    After iOS 5 - (void)drawRect:(CGRect)rect is not called while we create category for UINavigationBar but you can call -(void)awakeFromNib and add all the code that you want to add.

    0 讨论(0)
  • 2020-11-28 08:07

    Try to read iOS 5.0 Release Notes

    In iOS 5, the UINavigationBar, UIToolbar, and UITabBar implementations have changed so that the drawRect: method is not called unless it is implemented in a subclass. Apps that have re-implemented drawRect: in a category on any of these classes will find that the drawRect: method isn't called. UIKit does link-checking to keep the method from being called in apps linked before iOS 5 but does not support this design on iOS 5 or later.

    0 讨论(0)
  • 2020-11-28 08:08

    Here's a less-ugly solution that works for both iOS4 and 5:

    @implementation UINavigationBar (CustomBackground)
    
    - (UIImage *)barBackground
    {
        return [UIImage imageNamed:@"top-navigation-bar.png"];
    }
    
    - (void)didMoveToSuperview
    {
        //iOS5 only
        if ([self respondsToSelector:@selector(setBackgroundImage:forBarMetrics:)])
        {
            [self setBackgroundImage:[self barBackground] forBarMetrics:UIBarMetricsDefault];
        }
    }
    
    //this doesn't work on iOS5 but is needed for iOS4 and earlier
    - (void)drawRect:(CGRect)rect
    {
        //draw image
        [[self barBackground] drawInRect:rect];
    }
    
    @end
    
    0 讨论(0)
  • 2020-11-28 08:22

    Setting custom background for UINavigationBar to support iOS5 and iOS4 too!

    http://www.mladjanantic.com/setting-custom-background-for-uinavigationbar-what-will-work-on-ios5-and-ios4-too/

    http://rogchap.com/2011/06/21/custom-navigation-bar-background-and-custom-buttons/


    As you know, until iOS 5 came out, we used drawRect override in AppDelegate to customize UINavigationBar. But know, iOS 5 give us some new method for styling (and old doesn’t work).

    How to build app that will work on iOS 4 and iOS 5 with stylized UINavigationBar?

    You must to do both!

    In AppDelegate use this code:

    @implementation UINavigationBar (UINavigationBarCategory)
    - (void)drawRect:(CGRect)rect {
    UIImage *img = [UIImage imageNamed:@"navbar.png"];
    [img drawInRect:rect];
    }
    @end
    

    and in viewDidLoad method for iOS5 (in your view implementation):

    if ([self.navigationController.navigationBar respondsToSelector:@selector( setBackgroundImage:forBarMetrics:)]){
    [self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"navbar.png"] forBarMetrics:UIBarMetricsDefault];
    }
    

    If you see, here we are asking if navbar will respondToSelector to avoid crash on iOS4!

    0 讨论(0)
  • 2020-11-28 08:23

    Follow this link to make your code compatible with iOS4, 5 and 6.

    You just have to make in Photoshop or other software a rectangular with the size of 320x44 or 640x88 (for retina display) and import it to your project

    In AppDelegate use this code (in the header between #import and @implementation AppDelegate):

    @implementation UINavigationBar (CustomImage)
    - (void)drawRect:(CGRect)rect {
        UIImage *image = [UIImage imageNamed:@"top_bar.png"];
        [image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
    }
    @end
    

    In viewDidLoad use this code for iOS5 and iOS6:

    #if defined(__IPHONE_5_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_5_0
        if ([self.navigationController.navigationBar respondsToSelector:@selector( setBackgroundImage:forBarMetrics:)]){
            [self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"top_bar.png"] forBarMetrics:UIBarMetricsDefault];
        }
    #endif
    
    0 讨论(0)
提交回复
热议问题