如何以模态方式呈现标准 UIViewController

Posted

技术标签:

【中文标题】如何以模态方式呈现标准 UIViewController【英文标题】:How to present a standard UIViewController modally 【发布时间】:2011-02-18 20:32:02 【问题描述】:

我正在尝试以模态方式呈现标准的ViewController,但不知道该怎么做。视图控制器将具有最终触发解除操作的按钮,因此我不需要将其包装在 NavigationController 中。另外,我以编程方式完成所有这些工作,没有 .xibs。

这是我正在使用的代码:

- (void)viewDidAppear:(BOOL)animated 
    NSLog(@"view did appear within rootviewcontroller");
    WelcomeViewController *welcome = [[WelcomeViewController alloc] init];
    [self presentModalViewController:welcome animated:true];
    [welcome release];

问题是我没有设置 WelcomeViewController's 视图,所以 loadView 没有运行,这意味着没有内容被绘制到屏幕上。

我发现的每个示例,包括 Apple 的示例,都使用 .xib 来初始化 ViewController,使用 NavigationController 添加 RootViewController,或者两者都使用。我的理解是在这两种情况下都会自动为您调用 loadView。 http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/ModalViewControllers/ModalViewControllers.html#//apple_ref/doc/uid/TP40007457-CH111-SW3

在哪里配置我的WelcomeViewController's 视图?就在分配/初始化之后? WelcomeViewController's init 方法里面?

谢谢!

【问题讨论】:

【参考方案1】:

在哪里配置 WelcomeViewController 的视图?

覆盖子类中的loadView 方法。见View Controller Programming Guide for iOS。

【讨论】:

感谢您的回复,但这并不能真正回答我的问题。我已经覆盖了 loadView,但它没有被调用。 loadView 永远不应该被直接调用,只有在“请求视图属性但当前为 nil 时”才被调用。所以我的实际问题是,我在哪里/如何请求视图属性? 你没有。当一个视图控制器出现时,UIKit 会请求该视图。如果它还不存在,您的 loadView 会被调用。 Sheesh...在我测试不同解决方案的过程中,我一定搞砸了一些东西并混淆了代码。如果我只是以模态方式呈现它而不做任何其他事情,我现在看到 loadView 被调用。那么就在 loadView 中,我将分配/初始化一个通用 UIView,并将其设置为 self.view,对吗? 是的,没错。您可以使用任何您喜欢的可扩展视图,但通用的 UIView 是最常见的。【参考方案2】:

这是一个简单的示例,说明如何在不使用 NIB 的情况下进行操作:

在您的 AppDelegate didFinishLaunchingWithOptions: 中,您创建自定义视图控制器的实例并将其添加为窗口的子视图(非常标准)。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

    RootViewController *vc = [[RootViewController alloc] initWithNibName:nil bundle:nil];
    [self.window addSubview:vc.view];
    [self.window makeKeyAndVisible];
    return YES;

创建vc 实例时,您使用指定的初始化程序,它将在视图控制器的新实例上调用。您无需指定任何 nib,因为您将在方法内进行自定义初始化:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) 
        [self.view setBackgroundColor:[UIColor orangeColor]];
        UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
        [label setBackgroundColor:[UIColor clearColor]];
        [label setNumberOfLines:2];
        [label setText:@"This is the vc view with an\norange background and a label"];
        [label setTextColor:[UIColor whiteColor]];
        [label setTextAlignment:UITextAlignmentCenter];
        [self.view addSubview:label];
        [label release];
    
    return self;

【讨论】:

抱歉代码格式化。从 iPad 发布的内容最终会忽略我的换行符?? 感谢您的回复。不确定我是否清楚,(我会回去编辑我的问题)但我正在以编程方式做所有事情,没有.xib。因此,我需要知道在哪里设置 VC.view,因为我没有加载 nib 或添加到导航控制器的 rootViewController 属性来自动为我执行此操作。如果我在分配/初始化后立即设置视图,我可以弹出一个模式,但不会调用 loadView。 @djibouti33 代码用一个简单的例子编辑。现在看看是否有意义。 感谢罗格。我将您的代码插入我的代码中,RootVC 的 loadView 最终被反复调用。我实际上使用吉姆的建议解决了这个问题。我只是展示了 WelcomeViewController,loadView 会自动调用。然后,在 loadView 中,我创建了一个通用 UIView 并将 self.view 分配给它。这工作得很好,并且 loadView 只被调用一次。另外,由于我没有使用 .xibs,我可以只调用 init 而不是调用 initWithNibName:bundle: 与 nil。感谢您的帮助!

以上是关于如何以模态方式呈现标准 UIViewController的主要内容,如果未能解决你的问题,请参考以下文章

如何在所有其他视图之前以模态方式呈现“启动视图”?

如何检查视图控制器是不是以模态方式呈现或推送到导航堆栈上?

在选项卡栏控制器中选择时以模态方式呈现视图控制器

应用程序尝试以模态方式呈现拆分视图控制器(我的应用程序中没有拆分视图)

如何以模态方式呈现 VC,然后转到嵌入在导航控制器中的 VC

如何在保持导航栏存在的同时以模态方式呈现视图控制器。 (对于设置视图控制器)