Search code examples
swiftuiviewscaleframeuiwindow

Why did Swift NOT load this view properly, while Objective-C did?


I tried programming in Swift, but I failed to execute a simple program. Just few lines of code to create a window with an empty view.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.


    self.window = UIWindow(frame: CGRect(x: 0.0, y: 0.0, width: 640.0, height: 960.0))

    let viewController = UIViewController()

    let view = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 640.0, height: 960.0))

    view.backgroundColor = UIColor.white

    viewController.view = view

    self.window?.rootViewController = viewController

    self.window?.makeKeyAndVisible()

    return true

}

This code produced a view that does not fill the screen. I tried the bound of the screen, frame, and scale, with fail unfortunately.

But when I tried the following in Objective-C, it run as expected:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.

self.window = [[UIWindow alloc] initWithFrame:CGRectMake(0.0, 0.0,640.0,960.0)];

UIViewController *viewController = [[UIViewController alloc] init];

UIView* view = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0,640.0,960.0)];

[view setBackgroundColor:[UIColor whiteColor]];

viewController.view = view;

[self.window setRootViewController:viewController];

[self.window makeKeyAndVisible];

return YES;

}


Solution

  • I can't explain why the Objective-C code works as you expect. But I do know what's wrong with the Swift code:

    Just few lines of code to create a window with an empty view

    But what you're doing is not how to do that; here is your code with some injected commentary:

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        self.window = UIWindow(frame: CGRect(x: 0.0, y: 0.0, width: 640.0, height: 960.0))
        // wrong; there is no need to frame the window
        // and if you do frame it, it must be framed to the actual screen size
    
        let viewController = UIViewController()
        let view = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 640.0, height: 960.0))
        view.backgroundColor = UIColor.white
        viewController.view = view
        // wrong; you must never assign a view controller a view like this...
        // except in the view controller's own `loadView` method
    
        self.window?.rootViewController = viewController
        self.window?.makeKeyAndVisible()
        return true
    }
    

    So, modifying as needed:

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        self.window = UIWindow()
        let viewController = UIViewController()
        viewController.view.backgroundColor = .white
        self.window?.rootViewController = viewController
        self.window?.makeKeyAndVisible()
        return true
    }
    

    And behold, a minimal correctly constructed empty window app with no storyboard (or at least, if it has a storyboard, it ignores it).