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

4 回答 4

15

在 iOS 8.0 中

self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryHidden;

隐藏主视图

于 2015-05-20T13:16:24.243 回答
6

为了获得您描述的效果,我必须将以下代码添加到我的 DetailViewController。

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

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

于 2013-07-21T00:34:05.040 回答
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];
}
于 2013-09-08T22:02:26.167 回答
1

Maybe I am too late to answer this but... here is the solution..

You can get the reference of your masterviewcontroller from the method in every orientation change

-(BOOL)splitViewController:(UISplitViewController *)svc shouldHideViewController:(UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation {
    myVCForPopOverController = vc;

    //always hide the controller
    return YES;
}

now you can show this "myVCForPopOverController" from any barbutton items click.

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

I have implemented this and it works.

于 2013-10-30T12:07:50.210 回答