带有自定义 NavigationBar 的 UINavigationController

Posted

技术标签:

【中文标题】带有自定义 NavigationBar 的 UINavigationController【英文标题】:UINavigationController with custom NavigationBar 【发布时间】:2013-06-05 12:35:54 【问题描述】:

我正在尝试使用自定义的NavigationBar 创建一个UINavigationController

我创建了一个类 (myNavBar),它继承自 UINavigationBar

我这样称呼我的navigationController

UINavigationController *navControl = [[UINavigationController alloc] initWithNavigationBarClass:[myNavBar class] toolbarClass:[UIToolbar class]];
[navControl pushViewController:myVewController animated:NO];

但我收到此错误:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Cannot call setItems:animated: directly on a UINavigationBar managed by a controller.'

我的代码有什么问题。

更新

这是 myNavigationBar 类:

#import <UIKit/UIKit.h>

@interface myNavBar : UINavigationBar

-(void)initNavBarButtons:(UIViewController*)sender;

@end


---------------------------------------------------


#import "myNavBar.h"

@implementation myNavBar

    UIButton *menuButton;
    UIButton *searchButton;


- (id)initWithFrame:(CGRect)frame

    self = [super initWithFrame:frame];
    if (self) 
        // Do any additional setup
    
    return self;



-(void)initNavBarButtons:(UIViewController*)sender

    [menuButton addTarget:sender action:@selector(revealMenu:) forControlEvents:UIControlEventTouchUpInside];
    [searchButton addTarget:sender action:@selector(revealSearch:) forControlEvents:UIControlEventTouchUpInside];



- (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize

    //UIGraphicsBeginImageContext(newSize);
    UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
    [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;


-(id)init
   self = [super init];
    return self;



// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect

    [self setFrame:rect];

    //[self setBarStyle:UIBarStyleBlack];

    menuButton = [UIButton buttonWithType:UIButtonTypeCustom];
    menuButton.frame = CGRectMake(0, 0, 25, 22);
    [menuButton setCenter:CGPointMake(25, self.center.y)];
    [menuButton setBackgroundImage:[UIImage imageNamed:@"menuButton.png"] forState:UIControlStateNormal];
    [self setHidden:NO];
    [self addSubview:menuButton];

    UIImageView *zblogo = [[UIImageView alloc] initWithImage:[self imageWithImage:[UIImage imageNamed:@"minilogo.png"] scaledToSize:CGSizeMake(200, 25)]];
    UINavigationItem *navI = [[UINavigationItem alloc] init];
    [self setItems:[NSArray arrayWithObject:navI]];

    [self.topItem setTitleView:zblogo];

    searchButton = [UIButton buttonWithType:UIButtonTypeCustom];
    searchButton.frame = CGRectMake(0, 0, 20, 20);
    [searchButton setCenter:CGPointMake(self.bounds.size.width - 25, self.center.y)];
    [searchButton setBackgroundImage:[UIImage imageNamed:@"boutonRecherche.png"] forState:UIControlStateNormal];

    [self addSubview:searchButton];



@end

也许我在这里做错了什么?

更新

现在我的 NavigationController 已很好地实例化,但我仍然遇到问题: 如果我写

UINavigationController *navController = [[UINavigationController alloc] initWithNavigationBarClass:[myNavBar class] toolbarClass:nil];
[navController setViewControllers:@[vc] animated:NO]

我在酒吧的初始化中所做的一切都被删除了,并且

UINavigationController *navController = [[UINavigationController alloc] initWithNavigationBarClass:[myNavBar class] toolbarClass:nil];
[navController pushViewController:vc animated:NO]

我的导航栏出现一个“后退按钮”,单击它可以看到我的自定义。

我已经阅读了这个主题:Why does using setViewControllers remove everything from the UINavigationController's nav bar?,但它并没有真正帮助我。

我怎样才能保留最初设置的导航栏?

【问题讨论】:

你的myVewController 里面有另一个UINavigationBar 吗? 不要在drawRect 中做任何事情!添加视图或设置框架不应该在drawRect中放入init 我已经从 drawRect 中删除了代码,现在我的导航栏中没有任何内容,无论我将代码放入 init 中,还是放入 initWithFrame: 中。这两种方法永远不会被调用... 当子类化 UIView 时,您应该覆盖 initWithFrame:initWithCoder:。应该调用其中之一。 没错。当我的视图从情节提要加载时调用 initWithCoder,并且在 Identy 检查器中将 navigationBar 设置为 myNavBar,当我使用 initWithNavigationBarClass: 时调用 initWithFrame。虽然我设法在 initWithCoder: 中设置了我的 titleView,但我没有在 initWithFrame 中。 【参考方案1】:

是否必须将 nil 放入第二个参数(工具栏一)才能使用默认参数?

来自文档:

指定您要使用的自定义 UIToolbar 子类,或指定 nil 以使用标准 UIToolbar 类。

更新,检查后我认为问题更多地指向这个方向,请检查这些链接:

How to add Button in UINavigationController

Adding BarButtons to a UINavigationBar after presenting a modal view controller

【讨论】:

不,它不能解决问题。 我只是尝试做一个像你这样的空项目,它对我有用,这让我觉得问题出在另一个地方。这里缺少一些信息。继续尝试一个空项目。【参考方案2】:

如果你只是想把图片放在你的导航栏中,那么试试这个 .. 在你的 AppDelegate 的 didFinishLaunching 方法中

if ([self.navCtrl.navigationBar respondsToSelector:@selector(setBackgroundImage:forBarMetrics:)] ) 
        UIImage *image = [UIImage imageNamed:@"YourImage.png"];
        [self.navCtrligationController.navigationBar setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];
    

【讨论】:

不,我不只是包含图像。我正在做一个带有滑动菜单的应用程序。我正在使用 ECSlidingViewController。所以我用情节提要构建了我的应用程序,使用情节提要 ID(和恢复 ID)来调用我的控制器。它们每个都有一个顶部显示的导航栏。菜单是一个 TableView,它的 didSelectRowAtIndexPath 方法调用了我要显示的控制器。特别是,我想展示的其中一个是带有推送转换的表格。

以上是关于带有自定义 NavigationBar 的 UINavigationController的主要内容,如果未能解决你的问题,请参考以下文章

带有按钮的自定义 UINavigationController

微信小程序自定义navigationBar

在 Swift 中设置自定义 NavigationBar 的最简单方法是啥?

iOS NavigationBar 导航栏自定义

iPhone - NavigationBar 自定义背景 [重复]

自定义 NavigationBar 中的 UISearchBar