我有一个主题细节iPad界面设置与故事板,以提供详细视图控制器上的替换segue。这可以很好地替换细节控制器,但在某些情况下缺少显示主控制器的条形按钮。
如果我在纵向中执行segue,则会丢失条形按钮,因为永远不会调用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;
}
答案 0 :(得分: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协议,还有其他方法(更优雅)可用。但它看起来像是太多的工作,而且超出了能力范围。
答案 1 :(得分:0)
在查看iOS8 Day by Day课程后,我终于破解了它,即splitViewController chapter 18.
发生在我身上的事情与此线程类似。最初SpliViewController使DetailViewController显示'展开'按钮。经过一段时间后,这将消失。 所以最初的想法是我的SplitViewController, onViewLoad(),触及了DetailViewController。重新创建DetailViewController后,将无法再现此自定义行为。 这是我的故事板,因此您可以更轻松地识别代码中的对象: 请注意主控制器和细节控制器都有导航控制器(我知道这是你如何使用导航栏来表现他们的行为,我真的不知道我是iOS的爱好者)。
因此,在逐块评论某些代码之后,在 TopStuffSpliViewController 中,我找到了导致此行为的代码行:
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等单细节控制器屏幕上的后退按钮! 就是这样,它现在按预期工作!