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

Posted

技术标签:

【中文标题】iOS——如何控制模态视图控制器的大小?【英文标题】:iOS -- how do you control the size of a modal view controller? 【发布时间】:2010-11-20 03:12:56 【问题描述】:

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

编辑:我在模态视图控制器中有以下内容。没用。

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

【问题讨论】:

【参考方案1】:

您可以修改视图控制器的框架,但如果您使用 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 以帮助用户了解正在发生的事情。 Half-sheets 在 iPhone 上往往是 UIActionSheets,所以请朝那个方向思考。

【讨论】:

+1,很好的解决方案!只是一个快速的:最后一行缺少左括号“[”。 这是一个聪明的答案。但是,我认为如果您开始旋转设备并期望此视图能够正常运行,您将会把头发拉出来。这就是为什么 Apple 引入了一个 API 来处理这个问题。它被称为容器视图,它允许您拥有一个 VC,它是任意数量的其他 VC 的容器。非常非常强大的api。查找 UIViewController 包含。将包含您可以将属于单独 VC 的尽可能多的视图带到屏幕上,或者以您认为合适的方式移动它们。【参考方案2】:

很好,上面接受的答案解释了一个很好的技巧来呈现感觉像 ModalViews 的子视图,但是如果它是 iPad 怎么办,我确实可以给它一个不覆盖整个屏幕的 modalViewController。

如果是 iPad,我不认为底视图会被卸载。 (因为有一些选项可以让我们在 iPad 上呈现 modalView,但不会覆盖整个屏幕)

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.

【讨论】:

【参考方案3】:

我会在@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,它似乎确实做了正确的事情并保持模态视图居中。

【讨论】:

很好,但是当这样的视图关闭时调用父视图的哪个方法?例如,父视图 viewdidappear 将不会被调用.. 这对我来说效果很好。我见过的自定义大小的模态视图的最佳解决方案。太糟糕了,你不能用 segues 来做(据我所知。我做了一些实验)。 嗨,bugloaf,我也做了同样的事情,它仅适用于 ViewControllers,但对于带有导航的 ViewControllers 则不然。请回答我的问题@***.com/questions/15802633/…

以上是关于iOS——如何控制模态视图控制器的大小?的主要内容,如果未能解决你的问题,请参考以下文章

ios:如何关闭模态视图控制器,然后弹出推送的视图控制器

如何在 iOS 中显示小型模态视图控制器?

如何使用 iOS 7 自定义转换在顶部呈现半模态视图控制器

iOS:模态视图控制器如何记住它的属性?

如何以模态方式将视图添加到不在视图层次结构中的另一个视图 iOS

iOS - 半透明模态视图控制器