首页 文章

详细信息替换segue后,UISplitView按钮丢失

提问于
浏览
6

我有一个主题细节iPad界面设置与故事板,以在细节视图控制器上提供替换segue . 这可以很好地替换细节控制器,但在某些情况下缺少显示主控制器的条形按钮 .

如果我在纵向中执行segue,则会缺少bar按钮,因为从不调用 willHideViewController: 委托方法 . 当从主服务器调用 prepareForSegue: 时,我将委托设置为新的详细信息控制器 .

当按钮丢失时,我可以将iPad旋转到横向然后再回到纵向,然后会出现按钮 .

prepareForSegue:

UINavigationController *nav = [segue destinationViewController];
    UIViewController *destinationViewController = nav.topViewController;
    if ([destinationViewController conformsToProtocol:@protocol(UISplitViewControllerDelegate)]) {
        self.splitViewController.delegate = destinationViewController;
    }
    else {
        self.splitViewController.delegate = nil;
    }

在细节控制器中:

#pragma mark - Split view

- (void)splitViewController:(UISplitViewController *)splitController willHideViewController:(UIViewController *)viewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)popoverController
{
    barButtonItem.title = NSLocalizedString(@"MasterButton", @"Master");
    [self.navigationItem setLeftBarButtonItem:barButtonItem animated:YES];
    self.masterPopoverController = popoverController;
}

- (void)splitViewController:(UISplitViewController *)splitController willShowViewController:(UIViewController *)viewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem
{
    // Called when the view is shown again in the split view, invalidating the button and    popover controller.
    [self.navigationItem setLeftBarButtonItem:nil animated:YES];
    self.masterPopoverController = nil;
}

2 回答

  • 0

    我遇到了同样的情况,我通过将当前的detailViewController(正在被替换)中的barButton值传递给prepareForSegue方法中的目标detailViewController(替换的那个)来解决 .

    步骤是:

    • 将barButton存储为UISplitViewDelegate方法中的属性

    因此,在DetailViewControllers中添加:

    @property (nonatomic, strong) UIBarButtonItem *rootPopoverButtonItem;
    

    并在委托方法中:

    -(void)splitViewController:(UISplitViewController *)svc willHideViewController:
    (UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem *)barButtonItem
     forPopoverController:(UIPopoverController *)pc
    {
         barButtonItem.title = @"Master";
         [self.navigationItem setLeftBarButtonItem:barButtonItem animated:YES];
         self.rootPopoverButtonItem = barButtonItem; //Storing the barButton
         self.masterPopoverController = pc;
    
    }
    
    -(void)splitViewController:(UISplitViewController *)svc willShowViewController:
    (UIViewController *)aViewController 
    invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem
    {
    
       // Called when the view is shown again in the split view, invalidating the button and popover controller.
    
        [self.navigationItem setLeftBarButtonItem:nil animated:YES];
        self.rootPopoverButtonItem = nil;  //Storing the barButton
        self.masterPopoverController = nil;
    
    }
    
    • 现在在你的 - (void)viewDidLoad中读取存储的值并显示 . 如果barButton显示在正被替换的viewController中,则当前VC将显示它 .
    [self.navigationItem setLeftBarButtonItem:self.rootPopoverButtonItem animated:YES];
    
    • 现在在主视图控制器中包含prepareForSegue中的以下内容...
    UISplitViewController *splitViewController = (UISplitViewController *)self.view.window.rootViewController;
          UINavigationController *currentNavigationController = [splitViewController.viewControllers lastObject];
          UINavigationController *navigationController = [segue destinationViewController];
    
          DetailViewController *destinationDetailViewController=(DetailViewController *)[navigationController topViewController];
          DetailViewController *currentDetailViewController =(DetailViewController *)[currentNavigationController topViewController];
    
          splitViewController.delegate = destinationDetailViewController;//Needed for passing the delegate
    
          if(currentDetailViewController.rootPopoverButtonItem !=nil)
          {
    
          destinationDetailViewController.rootPopoverButtonItem = currentDetailViewController.rootPopoverButtonItem;
    
          }
    

    这不是一种优雅的方法..但对我来说没有太大的开销 . 如果您可以使用SubstitutableDetailViewController协议,还有其他方法(更优雅)可用 . 但它看起来像是太多的工作,而且超越了能力 .

  • 0

    在看了iOS8 Day by Day课程后,我终于破解了它,即splitViewController chapter 18.

    我遇到的情况与此线程相似 . 最初,SpliViewController使DetailViewController显示'Expand'按钮 . 经过一段时间后,这将消失 . 所以最初的想法是我的SplitViewController, onViewLoad() 触及了DetailViewController . 重新创建DetailViewController后,将无法再现此自定义行为 . 这是我的故事板,因此您可以更轻松地识别代码中的对象:
    enter image description here
    请注意主控制器和细节控制器都有导航控制器(我知道这是如何让他们用导航条表现的,我真的不知道我是iOS的爱好者 .

    所以在逐块注释一些代码之后,在_2582377中我发现了导致这种行为的代码行:

    let detailNavVC = self.childViewControllers.last as! UINavigationController
        detailNavVC.topViewController!.navigationItem.leftBarButtonItem = self.displayModeButtonItem()
    

    现在只需要在DetailController加载的每个时间重新创建此行为:

    override func viewDidLoad() {
            super.viewDidLoad()
    ....
    if (self.navigationController?.splitViewController?.collapsed == false {
        self.navigationItem.leftBarButtonItem = self.navigationController?.splitViewController?.displayModeButtonItem()}
    

    小心,如果你忽略if语句,你也会隐藏iPhone 4S等单细节控制器屏幕上的后退按钮!就是这样,它现在按预期工作!

相关问题