UISplitView button missing after detail replace segue
我有一个主要的iPad详细信息界面,该界面设置了情节提要,以提供详细视图控制器上的替换设置。这可以很好地替换细节控制器,但是在某些情况下,缺少用于显示主控制器的条形按钮。
如果我在纵向模式下执行segue,则会丢失bar按钮,因为从未调用
当缺少按钮时,我可以将iPad旋转到横向,然后再回到纵向,然后按钮就会出现。
在
中
1 2 3 4 5 6 7 8 | UINavigationController *nav = [segue destinationViewController]; UIViewController *destinationViewController = nav.topViewController; if ([destinationViewController conformsToProtocol:@protocol(UISplitViewControllerDelegate)]) { self.splitViewController.delegate = destinationViewController; } else { self.splitViewController.delegate = nil; } |
在详细信息控制器中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #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; } |
看完iOS8日复一日课程,即splitViewController第18章,我终于破解了它。
对我来说,发生的事情与此线程相似。最初,SpliViewController使DetailViewController显示\\'Expand \\'按钮。发生争执之后,这将消失。
因此,最初的想法是我的SplitViewController onViewLoad()接触了DetailViewController。重新创建DetailViewController时,不会重现此自定义行为。
这是我的情节提要,以便您可以更轻松地识别代码中的对象:
请注意,主控制器和详细控制器都具有导航控制器(我知道这是让他们与导航栏一起工作的方式,虽然我是iOS的业余爱好者,但我真的不知道)。
因此,在逐块注释一些代码之后,在TopStuffSpliViewController中,我找到了导致此行为的代码行:
1 2 | let detailNavVC = self.childViewControllers.last as! UINavigationController detailNavVC.topViewController!.navigationItem.leftBarButtonItem = self.displayModeButtonItem() |
现在只需要在DetailController每次加载时重新创建此行为即可:
1 2 3 4 5 | override func viewDidLoad() { super.viewDidLoad() .... if (self.navigationController?.splitViewController?.collapsed == false { self.navigationItem.leftBarButtonItem = self.navigationController?.splitViewController?.displayModeButtonItem()} |
请注意,如果忽略if语句,您还将在iPhone 4S之类的单个详细信息控制器屏幕上隐藏后退按钮!
就是这样,它现在可以按预期工作了!
我遇到了同样的情况,并且解决了是否将barButton值从当前的detailViewController(将被替换)传递到prepareForSegue方法中的目标detailViewController(即替换的那个)中的问题。
步骤为:
将barButton作为属性存储在UISplitViewDelegate方法中
因此,在DetailViewControllers中添加:
1 | @property (nonatomic, strong) UIBarButtonItem *rootPopoverButtonItem; |
在委托方法中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | -(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将显示它。
1 | [self.navigationItem setLeftBarButtonItem:self.rootPopoverButtonItem animated:YES]; |
现在在主视图控制器中的prepareForSegue ...中包括以下内容...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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协议,则还有其他方法(更优雅)可用。但这看起来工作量太大,而且超出了功能。