我在一个简单的应用程序中使用拆分视图控制器。将所有内容保留为默认设置正常。换句话说,主视图控制器始终以横向显示,并在按下后退按钮时以纵向覆盖详细视图控制器。
我想要做的是让主视图控制器在横向上模仿与纵向相同的功能。换句话说,当设备处于横向状态时,我希望隐藏主视图控制器,直到我点击后退按钮,然后我希望它覆盖详细视图控制器。
我认为最好的方法是使用以下代码:
- (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];
}
此ALMOST有效。我有两个问题:
从隐藏到取消隐藏和取消隐藏主视图控制器的过渡不是动画的,而且非常明显。我添加了动画代码(见上文)但它只动画了详细视图控制器而不是主视图控制器。主人立即出现并消失(留下黑框消失),直到细节视图控制器滑过。
这也显示了我的第二个问题。我希望主视图控制器在横向模式下显示时与详细视图控制器重叠,使详细视图控制器保持原样。相反,它调整了细节视图控制器的大小(与我在开始之前在横向模式下的工作方式相同)。我希望主视图控制器以与纵向模式相同的方式进行交互:主视图在细节控制器的顶部滑动,并在选择项目时滑出。
如果我能解决问题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];
}
答案 0 :(得分:13)
在ios 8.0中
self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryHidden;
隐藏主视图
答案 1 :(得分:6)
要获得您描述的效果,我必须将以下代码添加到DetailViewController中。
- (BOOL)splitViewController:(UISplitViewController *)svc shouldHideViewController:
(UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation
{
return YES;
}
然后我的分割视图在纵向和横向模式下的工作方式相同。
答案 2 :(得分:1)
我正在使用我最终使用的代码。希望这有助于其他人。
// ***************************************************************************************************
//
// 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];
}
答案 3 :(得分:1)
也许我来不及回答这个问题,但......这是解决方案..
您可以在每个方向更改中从方法获取masterviewcontroller的引用
-(BOOL)splitViewController:(UISplitViewController *)svc shouldHideViewController:(UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation {
myVCForPopOverController = vc;
//always hide the controller
return YES;
}
现在您可以从任何按钮项目中单击显示此“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];
}
}
我已经实现了这个并且它有效。