【问题标题】:Can't find where to add UIBarButtonItem找不到在哪里添加 UIBarButtonItem
【发布时间】:2013-03-15 16:28:10
【问题描述】:

我在 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 提供任何其他建议吗?

【问题讨论】:

  • 唯一正确的方法是self.navigationItem.rightBarButtonItem = ...。如果它对您不起作用,请确保您的 VC 在 NavigationController 层次结构中。
  • 谢谢马克,但棘手的部分是我的 UIPageViewController 在层次结构中,它正在加载我需要保存按钮的 VC。所以从技术上讲,我的 VC 不在层次结构中,但它是由不是的东西加载的。我可能不得不把按钮放在别的地方。

标签: ios objective-c uinavigationcontroller uibarbuttonitem uipageviewcontroller


【解决方案1】:

你需要把它放在 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;
        }
    }
}

【讨论】:

  • 我喜欢这个答案,我相信它会起作用,但我真的不希望 UIPageViewController 的每个页面都有按钮,所以我正在寻找一种方法来添加它并根据显示的页面将其删除。除非在加载后无法修改 NavBar,但我相信它是。
  • 好吧,虽然这不是我正在寻找的答案,但它是最好的解决方案。我认为添加一个协议来启用/禁用 UIPageViewController 中的按钮可能是必须要做的。感谢尼克的帮助!
  • 我编辑了我的答案以解决您的其他要求。您可以这样做,或者只是在您的其他 UIViewController 子类中覆盖“viewWillAppear”并将 rightBarButtonItem 设置为 nil 以删除按钮。
  • 不错!我喜欢它,它也是一个放置它的好地方。感谢尼克的更新!
【解决方案2】:

最后找到了另一种可能比 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];

【讨论】:

    【解决方案3】:

    我建议您创建一种方法来获取如下所示的 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 = ...
    

    【讨论】:

      猜你喜欢
      • 2017-06-29
      • 2017-07-19
      • 2016-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-18
      相关资源
      最近更新 更多