隐藏/取消隐藏主视图控制器在横向中与纵向相同

时间:2013-05-03 06:30:22

标签: ios uisplitviewcontroller ipad

我在一个简单的应用程序中使用拆分视图控制器。将所有内容保留为默认设置正常。换句话说,主视图控制器始终以横向显示,并在按下后退按钮时以纵向覆盖详细视图控制器。

我想要做的是让主视图控制器在横向上模仿与纵向相同的功能。换句话说,当设备处于横向状态时,我希望隐藏主视图控制器,直到我点击后退按钮,然后我希望它覆盖详细视图控制器。

我认为最好的方法是使用以下代码:

 - (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有效。我有两个问题:

  1. 从隐藏到取消隐藏和取消隐藏主视图控制器的过渡不是动画的,而且非常明显。我添加了动画代码(见上文)但它只动画了详细视图控制器而不是主视图控制器。主人立即出现并消失(留下黑框消失),直到细节视图控制器滑过。

  2. 这也显示了我的第二个问题。我希望主视图控制器在横向模式下显示时与详细视图控制器重叠,使详细视图控制器保持原样。相反,它调整了细节视图控制器的大小(与我在开始之前在横向模式下的工作方式相同)。我希望主视图控制器以与纵向模式相同的方式进行交互:主视图在细节控制器的顶部滑动,并在选择项目时滑出。

  3. 如果我能解决问题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 个答案:

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

我已经实现了这个并且它有效。