找不到添加UIBarButtonItem的位置

时间:2013-03-15 16:28:11

标签: ios objective-c uinavigationcontroller uibarbuttonitem uipageviewcontroller

我在NavigationController中有一个UIPageViewController,UIPageViewController提供的一个ViewControllers需要能够在导航栏中添加一个“Save”按钮。

问题是我找不到导航栏的任何访问权限,因此我设置了一个断点并开始挖掘它,我似乎无法找到可以访问NavigationController或其属性的位置。

这是我发现的:

(lldb) po self.toolbarItems
    $9 = 0x00000000 <nil>

(lldb) po self.parentViewController
    $10 = 0x1e070bc0 <UIPageViewController: 0x1e070bc0>

(lldb) po self.parentViewController.toolbarItems
    $11 = 0x00000000 <nil>

(lldb) po self.parentViewController.navigationController
    $12 = 0x00000000 <nil>

(lldb) po self.parentViewController.view
    $13 = 0x1d585960 <_UIPageViewControllerContentView: 0x1d585960; frame = (0 0; 320 
    416); clipsToBounds = YES; opaque = NO; autoresize = W+H; layer = <CALayer: 
    0x1d5a1090>>

(lldb) po self.parentViewController.view.window
    $14 = 0x1e073750 <UIWindow: 0x1e073750; frame = (0 0; 320 480); layer = 
    <UIWindowLayer: 0x1e0756a0>>

(lldb) po self.parentViewController.view.window.rootViewController
    error: property 'rootViewController' not found on object of type 'id'
    error: 1 errors parsing expression

(lldb) po self.presentingViewController
    $15 = 0x00000000 <nil>

我已经尝试在我的VC和父VC中设置我的rightBarButtonItem,甚至尝试转到topViewController和rootViewController。

任何人都可以提供任何其他建议,以便我可以访问NavigationController吗?

3 个答案:

答案 0 :(得分:2)

您需要将它放在UIViewController子类

-(void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    self.parentViewController.navigationItem.rightBarButtonItem = ...
}

该解决方案的唯一问题是Apple可以随时更改UIPageViewController实现,以获得更多级别的视图控制器控制。更安全的解决方案是:

在UIViewController子类 .h 中添加:

@property (nonatomic, weak) UIPageViewController *pageViewController;
.m 中的

添加:

-(void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    _pageViewController.navigationItem.rightBarButtonItem = ...
}

然后不要忘记将pageViewController分配给适当位置的属性

myViewController.pageViewController = myPageViewController;

您可以在UIPageViewControllerDelegate方法中重置UIPageViewController navigationItem的属性,如下所示:

- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed {
    if (completed) {
        UIViewController *viewController = [pageViewController.viewControllers lastObject];
        if (![viewController isKindOfClass:[CustomBarButtonItemViewController class]]) {
            pageViewController.navigationItem.rightBarButtonItem = nil;
        }
    }
}

答案 1 :(得分:0)

使用另一种可能比parentViewController更可靠的方法。

因为它似乎嵌套在例如UIViewControllers中。 UIPageViewController无法通过

直接提供其UIBarButtonItem项
self.navigationItem

只是UINavigationController的直接子节点就可以做到。

但是嵌套的UIViewControllers可以通过

访问UINavigationController
self.navigationController

至少在viewWillAppear / viewDidAppear中 - 遗憾的是在viewDidLoad中为nil。

UINavigationController中最顶层的UIViewController绝对是嵌套UIViewController的parentViewController层次结构。

因此,使用UINavigationController的最顶层UIViewController设置navigationItems,而不是单步执行(可能更多)parentViewControllers:

[[[self.navigationController.viewControllers lastObject] navigationItem] setLeftBarButtonItem:barButton];

答案 2 :(得分:0)

我建议您创建一个方法来获取navItem,如下图所示。它总是可以在你的pageViewController的任何地方工作。

- (UINavigationItem*) getNavigationItem{
UIViewController* viewController = self;
do
{
    if ([viewController.parentViewController isKindOfClass:[UINavigationController class]])
        return viewController.navigationItem;

    viewController = viewController.parentViewController;
}
while (viewController.parentViewController);

return nil;

}

你可以这样使用它:

[self getNavigationItem].rightBarButtonItem = ...