工具栏中的UIBarButton用于UINavigationController,它是拆分VC的详细视图

时间:2012-07-25 20:48:24

标签: objective-c uinavigationcontroller uisplitviewcontroller uitoolbar

我有一个Split VC作为我的应用程序的入口点。细节VC是一个UINavigationController,我想总是隐藏主VC,以便我只能在工具栏的弹出窗口中使用它。

我的问题是我无法将barButtonItem从主VC放入我的详细VC中。工具栏始终为空(我必须使用self.toolbarHidden = NO;强制显示它,因为顶部有导航栏。)

我在UINavigationController(实际细节VC)中有以下代码:

-(void) setBarButtonItem:(UIBarButtonItem *)barButtonItem {
  NSLog(@"adding toolbar button: %@", barButtonItem.title);

  UIToolbar *toolbar = [self toolbar];

  NSMutableArray *toolbarItems = [toolbar.items mutableCopy];

  if (_barButtonItem) [toolbarItems removeObject:_barButtonItem];

  if (barButtonItem) [toolbarItems insertObject:barButtonItem atIndex:0];

  _barButtonItem = barButtonItem;
}

我错过了什么吗?我也尝试将其插入导航栏而不是工具栏,但它也没有显示在那里。请询问我在评论中未提供的任何信息。

1 个答案:

答案 0 :(得分:0)

如果其他人试图做同样的事情,我将离开一个实现,在splitViewController中将UINavigationController作为Detail VC,并在导航到显示/隐藏时让每个视图控制器顶部的按钮主VC:

您的详细信息VC必须实现以下协议(因此您需要@synthesize barButtonItem):

@protocol SplitViewBarButtonItemPresenter <NSObject>
@property (nonatomic, strong) UIBarButtonItem *barButtonItem;
@end

您需要获取并保留从willHideViewController传递的barButtonItem:在您的Detail VC中,但您必须在Master VC中执行此操作。在主VC中使用以下内容:

- (BOOL) splitViewController:(UISplitViewController *)sender
    shouldHideViewController:(UIViewController *)vc
               inOrientation:(UIInterfaceOrientation)orientation {

    return YES;
}

- (void)splitViewController:(UISplitViewController *)svc
     willHideViewController:(UIViewController *)aViewController
          withBarButtonItem:(UIBarButtonItem *)barButtonItem
       forPopoverController:(UIPopoverController *)pc {

    barButtonItem.title = self.title;

    [self splitViewBarButtonItemPresenter].barButtonItem = barButtonItem;

}

- (void)splitViewController:(UISplitViewController *)svc
     willShowViewController:(UIViewController *)aViewController
          withBarButtonItem:(UIBarButtonItem *)barButtonItem
       forPopoverController:(UIPopoverController *)pc {

    [self splitViewBarButtonItemPresenter].barButtonItem = nil;

}

- (id <SplitViewBarButtonItemPresenter>) splitViewBarButtonItemPresenter {

    id detailVC = [self.splitViewController.viewControllers lastObject];

    if ((![detailVC isKindOfClass:[MainDetailVC class]]) || (![detailVC conformsToProtocol:@protocol(SplitViewBarButtonItemPresenter)])) {

        detailVC = nil;
    }

    return detailVC;
}

在您希望按钮显示的每个视图控制器中,使用以下代码(如果它们都是相同的类型,您也可以将它放在一个类中并从中继承):

-(void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    UIBarButtonItem *newBtn = [[UIBarButtonItem alloc]
            initWithTitle:@"Show Master MC" // might want a better title
            style:UIBarButtonItemStylePlain
            target:self action:@selector(forceOpenMasterVC)];

    self.navigationItem.rightBarButtonItem = newBtn;

}

-(void)forceOpenMasterVC {
    [((MainDetailVC *) self.navigationController) forceOpenMasterVC];
}

然后在您的Detail VC中,使用以下内容:

#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
// Above line is needed because of self.barButtonItem.action
// It doesn't leak as far as I can tell

-(void)forceOpenMasterVC {
    // Grab the Master VC
    UIViewController * vc = [[self.splitViewController viewControllers] objectAtIndex:0];

    if (self.barButtonItem) {
        [self.barButtonItem.target
            performSelector:self.barButtonItem.action
            withObject: self.barButtonItem];
    }
}

如果有人有更好的方法,请加入。