iOS - 如何控制模态视图控制器的大小?

30

我正在展示一个模态视图控制器。如果有影响的话,它是从底部向上滚动的。我如何控制它占据屏幕的哪一部分?

编辑:我在模态视图控制器中使用以下代码,但似乎没有帮助。

- (void)viewDidLoad {
    TestResultView *trv = [[TestResultView alloc]initWithTest: [Model m].currentTest];
    self.view = trv;
    trv.frame = CGRectMake(0, 320, 320, 160);
    [trv release];
    [super viewDidLoad];
}
3个回答

38

您可以修改视图控制器的框架,但如果您使用UIViewController的-presentModalViewController:animated:方法,则在您的模态视图动画进入屏幕后(这假定您正在使用iPhone),背景视图将被卸载,您将看到一个白色屏幕,而不是背景视图。iOS认为您的模态视图控制器将是全屏视图控制器,并转储其他视图以节省内存。

如果您真的想在部分屏幕上显示视图,则应将UIView(没有UIViewController)作为子视图添加到当前UIViewController的视图中,然后自己将其动画显示在屏幕上。我认为在将要呈现该视图的UIViewController类中,可以尝试以下代码:

// Add the view as a subview and position it offscreen just below the current view
UIView *myHalfView = [[UIView alloc] initWithFrame:someAppropriateFrame];
[self.view addSubview:myHalfView];
CGRect offScreenFrame = myHalfView.bounds;
offScreenFrame.origin = CGPointMake(0.0, CGRectGetMaxY(self.view.frame));

// Now animate the view upwards
[UIView beginAnimations:nil context:nil];
// Move the view upwards the height of your sliding view so it's entirely onscreen
myHalfView.center = CGPointMake(myHalfView.center.x, myHalfView.center.y - myHalfView.bounds.size.height);
[UIView commitAnimations];
[myHalfView release];
为了得到额外加分,你可以通过设置逐渐淡入视图。
myHalfView.alpha = 0.0;

在UIView动画块之前,进行设置

myHalfView.alpha = 1.0;

在动画中心属性之后的块内。

完成后,可以执行类似但相反的操作将视图滑出屏幕。您可以向UIView动画块添加animationDidStop选择器,以便在视图滑出屏幕时获得通知,以便从视图层次结构中删除它。

从美学角度来看,您还应该小心处理此操作,因为上滑视图是标准行为,如果您的视图看起来像普通视图但在中途停止,用户可能会感觉(即使是短暂的)应用程序已经冻结。他们会弄清楚,但是如果不小心处理,这会给您的应用程序留下不良印象。主要是避免使用包括UINavigationController在内的标准全屏提示,以帮助用户了解发生了什么。在iPhone上,半页通常是UIActionSheet,因此应朝着这个方向思考。


1
+1,很好的解决方案!只是一个快速提醒:最后一行缺少左方括号 "["。 - pille
3
这是一个聪明的答案。不过,如果你开始旋转设备并期望这个视图表现良好,你可能会抓狂。这就是为什么苹果推出了一个处理这个问题的 API。它被称为容器视图,可以让你有一个 VC 作为其他任意数量的 VC 的容器。非常强大的 API。查一下 UIViewController Containment。使用容器视图,您可以将属于不同 VC 的许多视图带到屏幕上,或根据需要移动它们。 - SmileBot

26

很好,上面被接受的答案解释了一个很好的技巧,可以呈现感觉像ModalViews的subViews,但如果是iPad呢?我确实可以给它一个不覆盖整个屏幕的modalViewController。

在iPad的情况下,我不认为底部视图会被卸载。(因为有选项可以在iPad上呈现模态视图,而不覆盖整个屏幕)

最终,ModalViewController本身就是一个控制器,就像任何其他控制器一样,具有根视图,如果我们能够获取它,就可以编辑其属性。

这里是如何获得自定义ModalView框架的方法:

MyViewController *viewController = [[MyViewController alloc] init];
viewConroller.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentModalViewController:viewController animated:YES];
    //superView of viewController's view is modalViewController's view, which we were after
viewController.view.superview.frame = CGRectMake(x,y,w,h);
    //x y w h - can have desired values.

20

我想补充一下@dsaw的答案,即模态视图的父视图在横向模式下似乎没有旋转其坐标系统。这是我在自己的应用中使用的代码:

MyViewController* modalVC = [[MyViewController alloc] init];        
modalVC.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentModalViewController:modalVC animated:NO];
CGRect r = CGRectMake(self.view.bounds.size.width/2 - 236,
                      self.view.bounds.size.height/2 - 130,
                      472, 260);
r = [self.view convertRect:r toView:modalVC.view.superview.superview];
modalVC.view.superview.frame = r;

虽然父视图本身可能不会随着 iPad 旋转,但如果我在显示模态视图后旋转 iPad,它似乎会做正确的事情并保持模态视图居中。


1
很好,但是当这样的视图消失时,父视图的哪种方法被调用?例如,父视图的viewDidAppear方法将不会被调用... - user944351
这对我很有效。这是我见过的最好的自定义大小模态视图解决方案。可惜你不能用segue来实现它(据我所知,我做了一些尝试)。 - Philippe Sabourin
嗨,bugloaf,我也做了同样的事情,对于仅包含ViewControllers的情况运行良好,但是对于带有导航的ViewControllers则不行。请回答我的问题@http://stackoverflow.com/questions/15802633/presenting-a-view-controller-of-custom-size-with-navigation。 - Satheesh

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