使隐藏/取消隐藏主视图控制器在横屏模式下与竖屏模式相同。

5
我正在使用分割视图控制器来开发一个简单的应用程序。默认情况下一切正常。换句话说,主视图控制器在横屏时始终显示,并在按下返回按钮时在纵向模式下覆盖详细视图控制器。
我想做的是让主视图控制器在横屏模式下与纵向模式下的功能相同。换句话说,当设备处于横屏状态时,我希望主视图控制器被隐藏,直到我按下返回按钮,然后我希望它覆盖详细视图控制器。
我认为实现这个最好的方法是使用以下代码:
 - (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. 主视图控制器从隐藏到未隐藏和未隐藏到隐藏的过渡没有动画效果,太过生硬。我添加了动画代码(见上文),但只能为详细视图控制器提供动画效果,而不能为主视图控制器提供。主控制器立即出现和消失(在消失时留下黑色框),直到详细视图控制器滑动过去。

  2. 这也显示出我的第二个问题。我希望主视图控制器在横向模式下重叠于详细视图控制器,使详细视图控制器保持不变。相反,在详细视图控制器中会重新调整大小(与我开始之前的横向模式相同)。我希望主视图控制器在纵向模式下的交互方式与之相同:主控制器从顶部滑入并在选择项目时滑回。

如果我能解决问题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];
 }
4个回答

15

在iOS 8.0中

self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryHidden;

隐藏主视图


1
如果您仍希望左滑手势打开菜单(但希望在执行segue时隐藏Master),则此工作作为一个侧面提示,您可以执行以下操作:'self.spliViewController?.presentsWithGesture= true',这将添加手势,但仍然隐藏主视图。 - Rugdr

6
为了达到您所描述的效果,我不得不将以下代码添加到我的DetailViewController中。
- (BOOL)splitViewController:(UISplitViewController *)svc shouldHideViewController:
(UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation
{
    return YES;
}

那么我的分屏视图在竖屏和横屏模式下都能正常工作。


是的,@Nunrey,但它只是隐藏了masterViewController。当移动到下一个视图控制器时如何取消隐藏? - Sushil Sharma

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];
}

1
也许我回答有些晚了,但是这里有解决方法...
你可以在每次方向改变时从该方法中获取你的主视图控制器的引用。
-(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];
    }
}

我已经实现了这个功能,它可以正常工作。


(iOS9中已经弃用) splitViewController:(UISplitViewController *)svc shouldHideViewController: - zonabi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接