0

我在 NavigationController 中有一个 UIPageViewController,并且 UIPageViewController 提供的 ViewController 之一需要能够向导航栏添加一个“保存”按钮。

问题是我找不到对导航栏的任何访问权限,因此我设置了一个断点并开始对其进行挖掘,但我似乎无法找到对 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 提供任何其他建议吗?

4

3 回答 3

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 导航项的属性,如下所示:

- (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;
        }
    }
}
于 2013-03-15T17:15:35.443 回答
0

最终得到了另一种可能比 parentViewController 更可靠的方法。

因为它似乎嵌套在 UIViewControllers 中,例如 UIPageViewController 无法通过直接贡献其 UIBarButtonItem 项

self.navigationItem

只有 UINavigationController 的直接孩子可以做到这一点。

但是嵌套的 UIViewControllers 可以通过访问 UINavigationController

self.navigationController

至少在 viewWillAppear / viewDidAppear 中 - 不幸的是 viewDidLoad 中为零。

UINavigationController 中最顶层的 UIViewController 肯定在嵌套 UIViewController 的 parentViewController 层次结构中。

因此,不要使用 UINavigationController 的最顶层 UIViewController 来设置导航项,而不是步进到(也许更多)parentViewControllers:

[[[self.navigationController.viewControllers lastObject] navigationItem] setLeftBarButtonItem:barButton];
于 2013-12-30T10:29:41.327 回答
0

我建议您创建一种方法来获取如下所示的 navigationItem。无论您的 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 = ...
于 2016-07-14T08:44:23.957 回答