UINavigationBar的drawRect未在iOS 5.0中调用

tt.*_*lew 19 iphone background uinavigationbar ios ios5

我已经覆盖了UINavigationBar的drawRect以显示自定义背景(放置在类别或调配中).在iOS 5中,它不起作用.我该怎么办?

Man*_*nni 26

为UINavigationBar设置自定义背景也支持iOS5和iOS4!

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/


如您所知,在iOS 5问世之前,我们使用drawRect覆盖来AppDelegate进行自定义UINavigationBar.但是要知道,iOS 5为我们提供了一些新的样式方法(旧的方法不起作用).

如何使用程式化构建适用于iOS 4和iOS 5的应用程序UINavigationBar

你必须要做到这两点!

AppDelegate使用此代码:

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

viewDidLoadiOS5的方法中(在您的视图实现中):

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

如果你看到,我们在这里询问navbar是否会响应ToSelector以避免iOS4崩溃!


Nic*_*ood 12

这是一个适用于iOS4和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
Run Code Online (Sandbox Code Playgroud)


Ser*_*ost 11

尝试阅读iOS 5.0发行说明

在iOS 5中,UINavigationBar,UIToolbar和UITabBar实现已更改,因此除非在子类中实现,否则不会调用drawRect:方法.已重新实现drawRect的应用程序:在任何这些类的类别中将发现未调用drawRect:方法.UIKit进行链接检查以防止在iOS 5之前链接的应用程序中调用该方法,但在iOS 5或更高版本上不支持此设计.


tt.*_*lew 8

有一些可能的解决方案:

最快的解决方案对于我们最懒的人:

@interface MyNavigationBar : UINavigationBar

@end

@implementation MyNavigationBar

- (void)drawRect:(CGRect)rect {

}

@end

@implementation UINavigationBar (BecauseIMLazyHacks)
/*
 Another Ugly hack for iOS 5.0 support
*/
+ (Class)class {
  return NSClassFromString(@"MyNavigationBar");
}

-(void)drawRect:(CGRect)rect {

  CGContextRef context = UIGraphicsGetCurrentContext();
  CGContextTranslateCTM(context, 0, self.frame.size.height);
  CGContextScaleCTM(context, 1.0, -1.0);

  CGContextDrawImage(context, CGRectMake(0, 0, 
  self.frame.size.width, self.frame.size.height), barBackground.CGImage);      

}
@end
Run Code Online (Sandbox Code Playgroud)

再次.它有效,但你不应该这样做.

另一种方式,正如WWDC'11中所建议的那样,重写UINavigationBar(Create MyNavigationBar)并从xib初始化UINavigationController,如下所示:

http://www.iosdevnotes.com/2011/09/custom-uinavigationbars-techniques/

最后,使用iOS5.0和iOS5.0的逻辑流程切换 - 尽可能使用新的API.

类别是错误的路径,Swizzling是错误的路径.(他们只是在你耳边窃窃私语:"把自己带到黑暗面.这是你保存应用程序的唯一方法.")

  • drawRect代码应该在MyNavigationBar实现上,而不是在Category中. (3认同)