为什么xcode单视图模板不需要设置rootviewcontroller?

why xcode single view template don't need to set rootviewcontroller?

据我所知,如果我们想显示 UIWindow,我们需要执行以下步骤:

  1. create UIWindow
  2. load mian.storyboard and instantiate view controller
  3. set the controller to UIWindow's root viewcontroller, then make UIWindow show

类似于以下代码:

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    //创建窗口对象
    self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
    //创建窗口的根控制器,并且赋值
    UIViewController *rootVc = [[UIViewController alloc]init];
    self.window.rootViewController = rootVc;
    //显示窗口
    [self.window makeKeyAndVisible];
    return YES;
}

或使用故事板初始化

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


    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];


    UIStoryboard *stroyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];


    UIViewController *vc = [stroyboard instantiateInitialViewController];

    self.window.rootViewController = vc;

    [self.window makeKeyAndVisible];

    return YES;
}

但是在模板中,我没有看到那些代码,是不是我忽略了什么?

那是非常古老的代码。 Xcode 有不同的流程来加载初始 window。您不再需要该代码,如果您想知道,可以通过检查 plist 查看它是如何开始加载的。在 plist 中有一个名为 "Main Storyboard file base name" 的 属性 又名“"UIMainStoryboardFile",如果设置了这个,那么它将通过那里加载。

供参考,这是您以编程方式显示自己的初始视图控制器的方式(忽略 IB 视图控制器)

Programmatically set the initial view controller using Storyboards

当您选择 单一视图模板 时,一些事情会在幕后自动发生。

  • 在您的 IB 中,View ControllerUI 获取 Is Initial View Controller 属性 检查。这意味着这个视图控制器是根视图控制器。

  • 然后你在上图中看到,你的视图控制器得到一个Object ID。此 ID 与 storyboard.xml 文件的 initialViewController 属性 匹配。如果您右键单击故事板文件和 select 源代码 ,您将看到如下内容:

    <?xml version="1.0" encoding="UTF-8"?>
    <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB"
    version="3.0" toolsVersion="12118" systemVersion="16F73"
    targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES"
    useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
    
    ...
    ...
    
    </document>
    

基本上就是这样,模板连接了您之前需要从代码编写的设置。现在你不必了。这些都发生在单一视图模板的幕后。

执行这个流程:Select YourProject->TARGETS->General->Deployment Info->Main Interface ,有一个选择文本文件。

如果您选择了 Storyboard.storyboard ,那么 StoryBoard 会自动进行初始化。 Select Storyboard.storyboard 在你的项目中 Open As->Source Code 可以在情节提要中看到这段代码 XML :

    <objects>
        <viewController id="BYZ-38-t0r" customClass="ViewController" customModuleProvider="" sceneMemberID="viewController">
            <layoutGuides>
                <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
                <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
            </layoutGuides>
            <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
                <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
                <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
            </view>
        </viewController>
        <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
    </objects>

Xcode 只需使用 XML 配置自动初始化。

如果您清除选择文本字段,Xcode 将不会自动初始化 window 和 ViewController,那么您应该使用该代码手动初始化 UIWindow。