使隐藏/取消隐藏主视图控制器在纵向工作方式与纵向相同

我在一个简单的应用程序中使用分割视图控制器。 将所有内容保留为默认值即可。 换句话说,当按下后退button时,主视图控制器总是在横向上显示并且将纵向上的详细视图控制器覆盖。

我想要做的是使主视图控制器模仿风景相同的function,因为它在纵向。 换句话说,当设备处于横向模式时,我想隐藏主视图控制器,直到我点击后退button,然后我想要它覆盖详细视图控制器。

我想最好的办法是使用下面的代码:

- (BOOL)splitViewController:(UISplitViewController *)svc shouldHideViewController: (UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation { return self.bHideMaster; } 

这工作,它隐藏主视图控制器在横向模式。 然后我使用下面的代码使其重新出现:

  - (void)hideUnhidePagesController:(id)sender { [UIView beginAnimations:nil context:NULL]; [UIView setAnimationDuration:0.30f]; UISplitViewController* spv = self.splitViewController; // Change hide to unhide or vica versa self.bHideMaster= !self.bHideMaster; // Hide the button if master is visible if(self.bHideMaster) { self.navigationItem.leftBarButtonItem = self.pagesBarButton; } else { self.navigationItem.leftBarButtonItem = nil; } [spv.view setNeedsLayout]; [spv willRotateToInterfaceOrientation:self.interfaceOrientation duration:0]; [[self.splitViewController.viewControllers lastObject] view].frame = self.splitViewController.view.frame; [UIView commitAnimations]; } 

这几乎工作。 我有两个问题:

  1. 从隐藏到取消隐藏和取消隐藏主视图控制器的过渡不是animation化的,而且是非常严峻的。 我添加了animation代码(参见上面的内容),但它只animation了详细视图控制器而不是主视图控制器。 主人立即出现并消失(留下黑框消失),直到详细视图控制器滑过。

  2. 这也显示了我的第二个问题。 我想要主视图控制器重叠细节视图控制器,当它出现在横向模式,离开细节视图控制器。 相反,它调整了详细视图控制器的大小(与我在开始之前在横向模式下相同)。 我希望主视图控制器以与在纵向模式下相同的方式进行交互:主控人员在细节控制器顶部滑动,并在select某个项目时滑回。

如果我可以解决问题2,那么我不必担心问题1.好像应该有一个分割视图控制器中的方法,将从左侧(重叠细节视图控制器)在主控中滑动。 它在肖像模式下,所以代码必须在那里。 如何在横向模式下调用相同的代码?

谢谢!

———编辑1 ———

我重构了hideUnhidePagesController并越来越近。 窗口现在覆盖纵向和横向。 如果主设备在旋转中可见,则仍存在问题。 它变得混乱,并颠倒了预期的行为。 我在做这个工作。 这里修改后的代码:

  - (void)hideUnhidePagesController:(id)sender { // Change hide to unhide or vica versa self.bMasterIsHidden= !self.bMasterIsHidden; NSArray *controllers = self.splitViewController.viewControllers; UIViewController *rootViewController = [controllers objectAtIndex:0]; UIView *rootView = rootViewController.view; CGRect rootFrame = rootView.frame; if(self.bMasterIsHidden) { rootFrame.origin.x -= rootFrame.size.width; } else { rootFrame.origin.x += rootFrame.size.width; } [UIView beginAnimations:@"hideUnhideView" context:NULL]; rootView.frame = rootFrame; [UIView commitAnimations]; } 

在ios 8.0中

 self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryHidden; 

隐藏主视图

为了得到你描述的效果,我不得不将下面的代码添加到我的DetailViewController中。

 - (BOOL)splitViewController:(UISplitViewController *)svc shouldHideViewController: (UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation { return YES; } 

然后,我的分割视图在纵向和横向模式下的工作方式相同。

我正在input我最终使用的代码。 希望这可以帮助别人。

 // *************************************************************************************************** // // hideUnhideMasterViewControllerButtonPressed // // *************************************************************************************************** - (void)hideUnhideMasterViewControllerButtonPressed:(id)sender { if([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { [self.navigationController popViewControllerAnimated:YES]; } else { if(bMasterIsHidden) [self hideMasterViewController:NO]; else [self hideMasterViewController:YES]; } } // *************************************************************************************************** // // hideMasterViewController // // *************************************************************************************************** - (void)hideMasterViewController:(BOOL)bHideMaster { // Change hide to unhide or vica versa self.bMasterIsHidden= !self.bMasterIsHidden; NSArray *controllers = self.splitViewController.viewControllers; UIViewController *rootViewController = [controllers objectAtIndex:0]; UIView *rootView = rootViewController.view; CGRect rootFrame = rootView.frame; if(bHideMaster) { if(self.tapRecognizer) { rootFrame.origin.x -= rootFrame.size.width; [self.view removeGestureRecognizer:self.tapRecognizer]; self.tapRecognizer = nil; } } else { rootFrame.origin.x += rootFrame.size.width; self.tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapRecognized:)]; self.tapRecognizer.numberOfTapsRequired = 1; [self.view addGestureRecognizer:self.tapRecognizer]; self.tapRecognizer.delegate = self; } // Log resulting frame NSString *hiddenString = self.bMasterIsHidden ? @"YES" : @"NO"; NSLog(@"Page=%@ Class=%@ MasterIsHidden=%@ Origin(x,y)=(%f, %f) Size(width,height)=(%f, %f)", self.pageDefinition.pageName, [self class], hiddenString, rootFrame.origin.x, rootFrame.origin.y, rootFrame.size.width, rootFrame.size.height); [UIView beginAnimations:@"hideUnhideView" context:NULL]; rootView.frame = rootFrame; [UIView commitAnimations]; } 

也许我来不及回答这个问题,但是这里是解决scheme..

您可以从每个方向更改的方法中获取您的masterviewcontroller的引用

 -(BOOL)splitViewController:(UISplitViewController *)svc shouldHideViewController:(UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation { myVCForPopOverController = vc; //always hide the controller return YES; } 

现在你可以从任何barbutton项目点击显示这个“myVCForPopOverController”。

 -(void)onBarButtonClick:(id)sender { if(!self.popOverController.popoverVisible) { self.popOverController = [[UIPopoverController alloc]initWithContentViewController:myVCForPopOverController]; [self.popOverController presentPopoverFromBarButtonItem:showDetailsBarButton permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES]; self.popOverController.passthroughViews = nil; } else { [self.popOverController dismissPopoverAnimated:YES]; } } 

我已经实现了这个,它的工作原理。