2010-04-23 81 views
26

是否有任何方式以编程方式隐藏splitviewcontroller中的主视图。在我的应用程序中,第一个屏幕将是一个splitviewcontroller,我不需要为下一个屏幕分割视图。我可以如何实现这一点如何在UiSplitviewcontroller中隐藏iPad中的主视图

+0

当你说隐藏masterview,你的意思是在SplitViewController的左边创建一个空白的视图,或者你的意思是让DetailViewController在横向模式下填充100%的屏幕? – 2010-04-23 17:11:32

+0

第二种选择是让DetailViewController以任一模式(横向或纵向)填充屏幕的100%。 – i0707 2010-04-26 06:48:03

+0

任何解决方案呢?我正在尝试做同样的事情,我尝试以模态形式呈现,如: – 2011-01-21 07:06:30

回答

5

测试马特Gemmell创建一个名为 “MGSplitViewController” 一个优秀的定制splitViewController。它非常容易实现,经过严格评论,并且包含许多优秀的功能,这些功能在普通的splitViewController中没有找到(在横向视图中隐藏主视图,在横向视图中更改分割位置,允许用户在运行时更改流畅分割的大小,等等)。

信息和演示:http://mattgemmell.com/2010/08/03/mgsplitviewcontroller-updated/

直奔来源:https://github.com/mattgemmell/MGSplitViewController/

+1

用Xcode 6和iOS 8构建时要小心......看起来会炸毁构架 – whyoz 2014-11-10 19:03:28

0

虽然它不会有很好的转换(对不起),但可以通过将根视图设置为详细视图控制器的视图,然后使用UISplitView交换视图并将详细视图移动到UISplitView。 (实际上,您可能可以为视图交换(推/翻页等)设置动画效果,但在视图更改动画期间更改任何内容是个不错的主意,并且将详细视图移动到UISplitView的内部可能符合要求。)

0

不知道这是你想要的。举例来说,隐藏母版视图在横向模式下,当按钮被点击,你可以做以下(在选择方法)

UIViewController *master = [splitViewController.viewControllers objectAtIndex:0]; 
UIViewController *detail = [splitViewController.viewControllers objectAtIndex:1]; 

[master.view setFrame:CGRectMake(0, 0, 0, 0)]; 
detail.view.frame = splitViewController.view.bounds; // or use master and detail length 
+0

我试过这个,但它似乎不起作用。 – ericg 2011-03-24 21:41:33

+0

您是否看到任何尺寸更改。上面的代码确实对我有用。尝试手动设置detail.view.frame大小以查看大小更新。如果没有,我会明天发布一些细节代码。 – surajz 2011-03-26 20:49:55

3

试试这个:

splitVC.modalPresentationStyle = UIModalPresentationFullScreen; 
[splitVC presentModalViewController:[[splitVC viewControllers] objectAtIndex:1] animated:NO]; 

在4.2对我的作品!

这是另一个可行的技巧。 video link在这里。

+1

它肯定会隐藏主视图,但我似乎无法在调用presentModalViewController后将其返回。 – ericg 2011-03-24 21:40:10

+0

你试过dismissModalViewController吗? – 2011-03-25 12:17:31

+1

是的,它什么也没做。 – ericg 2011-03-25 15:20:06

25

在SDK 5.0中,他们为UISplitViewControllerDelegate添加了新的方法,可以轻松为您做到这一点。只是实现它像旁边,你不会看到主视图:

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

时,你可以看到它的唯一的地方是旋转 - 母版视图的一部分动画过程中是可见的。我已经用简单的方法解决了这个问题,只是在master中加载空白和黑色视图。

PS:不确定这是否是真实的i0707。但希望这对于现在有相同问题的其他人有用。

+2

请注意,当它的'delegate'属性发生改变时,分割视图控制器会调用此方法来处理所有方向如果您想切换行为,您可以强制通过调用旋转方法,你仍然需要触发显示/隐藏 – 2012-03-15 00:03:41

+0

@FrankSchmitt,你能澄清一下应该设置为nil吗?你可以添加一些示例代码吗? – Shmidt 2012-04-04 11:07:01

+1

Doesn我在SVC,主人的NC,主人的VC和详细视图的VC中都试过了。 – Chris 2012-04-13 11:58:15

0

这工作:

附加“隐藏”的方法,以您的按钮,例如:

UIBarButtonItem *hideButton = [[UIBarButtonItem alloc] initWithTitle:@"hide" 
             style: UIBarButtonItemStylePlain 
             target: self 
             action: @selector(hide:) 
           ]; 

[self.mainView.navigationItem setLeftBarButtonItem:hideButton]; 

在该代码中,“self.mainView”是在导航控制器视图控制器splitview的第二个视图 - 仅供参考。

hide方法看起来像这样。

-(void)hide:(id)sender 
{ 
    UIViewController *masterController = [self.viewControllers objectAtIndex:0]; 

    CGRect selfFrame = self.view.frame; 
    CGFloat aWidth = masterController.view.frame.size.width; 

    UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; 

    [UIView beginAnimations:nil context:NULL]; 
    [UIView setAnimationDuration:0.30f]; 

    if(orientation == UIDeviceOrientationLandscapeLeft) 
    { 
     selfFrame.size.height += aWidth; 
     selfFrame.origin.y -= aWidth; 
    } 
    else if(orientation == UIDeviceOrientationLandscapeRight) 
    { 
     selfFrame.size.height += aWidth; 
    } 

    [self.view setFrame:selfFrame]; 

    [UIView commitAnimations]; 

} 

这是出发点,显然更多的逻辑需要做照顾旋转,再次展示了它,等...

我希望这有助于。

与iOS5的和Xcode的4.3

+0

对我不起作用 – kinghomer 2012-10-19 11:34:30

3

上面我没有工作的代码,但是,当我试图

CGRect selfFrame = self.splitViewController.view.frame; 

它没有。所以....这对我的作品。(此代码应该在你detailviewcontroller)

-(void)hideMaster { 
    UIViewController *masterController = GetAppDelegate().masterController; 

    CGRect selfFrame = self.splitViewController.view.frame; 
    CGFloat aWidth = masterController.view.frame.size.width; 

    UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; 

    [UIView beginAnimations:nil context:NULL]; 
    [UIView setAnimationDuration:0.30f]; 

    if(orientation == UIDeviceOrientationLandscapeLeft) 
    { 
     selfFrame.size.height += aWidth; 
     selfFrame.origin.y -= aWidth; 
    } 
    else if(orientation == UIDeviceOrientationLandscapeRight) 
    { 
     selfFrame.size.height += aWidth; 
    } 

    [self.splitViewController.view setFrame:selfFrame]; 

    [UIView commitAnimations]; 

    } 

为了让这个需要旋转:

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation duration:(NSTimeInterval)duration 
{ 
    [super willAnimateRotationToInterfaceOrientation:interfaceOrientation duration:duration]; // not sure if needed 
    //By the time this method is called the bounds of the view have been changed 
    [UIView beginAnimations:nil context:NULL]; 
    [UIView setAnimationBeginsFromCurrentState:YES]; 

    if (UIInterfaceOrientationIsPortrait(interfaceOrientation)) { 
     if (masterIsHidden) { 
      [self showMaster]; 
     } 
    } else { 
     if (self.editing) { 
      [self hideMaster]; 
     } 
    } 
     [UIView setAnimationDuration:duration]; 
    [UIView commitAnimations]; 
} 
+1

对我不起作用 – kinghomer 2012-10-19 11:56:08

+0

这对我很好用。输入editMode时,我在详细视图中使用它。我创建了一个showMaster方法,将主宽度保存在iVar中,然后在hideMaster中反转+ =和 - +符号。我的实现还使用masterIsHidden iVar来防止隐藏已隐藏的视图。 – 2014-06-04 16:36:57

5

由SplitViewController提供的BarButtonItem是关键以编程方式隐藏主视图控制器。

此代码是危险的!但优雅:)

导入目标C消息库

#import <objc/message.h> 

下,得到一个处理当事件被触发由SplitViewController提供

- (void)splitViewController:(UISplitViewController *)splitController willHideViewController:(UIViewController *)viewController withBarButtonItem:(UIBarButtonItem *)barButtonItem 
      forPopoverController:(UIPopoverController *)popoverController 
    { 
     barButtonItem.title = @"Master"; 
     [self.navigationItem setLeftBarButtonItem:barButtonItem animated:YES]; 

     //Obtain handle to BarButtonItem 
     [self setMasterButtonItem:barButtonItem]; 
    } 

那么的UIBarButtonItem应该触发自动解除主视图控制器即

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 

你可以做到这一点

objc_msgSend(self.masterButtonItem.target, self.masterButtonItem.action); 
+5

这实际上是一个很好的解决方案,与其他一些想法相比,应该是相对“安全”的。你甚至可以跳过'objc_msgSend()'并且调用'[[UIApplication sharedApplication] sendAction:masterBarButtonItem.action::masterBarButtonItem.target from:nil forEvent:nil]'。 – jrc 2013-03-15 19:09:05

7

同杰克的答案,但一个班轮。过去到 - (void)setDetailItem:(id)newDetailItem {...}来解散主。

[[UIApplication sharedApplication] sendAction: self.navigationItem.leftBarButtonItem.action 
              to: self.navigationItem.leftBarButtonItem.target 
             from: nil 
            forEvent: nil]; 
+0

我搜索了几个小时解决这个问题,这正是我需要的。谢谢! – gplocke 2014-02-14 02:45:41

+0

在正确的时间非常有帮助。你保存了我的2小时研究:) – Nirav 2014-12-21 16:39:19

+0

这是我找到的一个特别优雅的解决方案!在我的例子中,我懒惰地实例化了一个自定义栏按钮项,并且这个解决方案在将它与仅由UISplitViewController委托方法返回的'barButtonItem'中的动作和目标复制相结合时为我做了窍门:-) – 2015-04-16 05:25:12