Search code examples
iosuiviewuiviewcontrolleraddsubview

In iOS, is there a difference between adding a view as a subview versus assigning a view to the view property?


I'm trying to make sense of any ambiguities in iOS programming so I've seen tutorials where developers assign their main view to the view property of the viewController like so:

let sceneView = ARSCNView(frame: self.view.frame)
view = sceneView

However I've also seen developers add their main view as a subview to the view property like so:

let sceneView = ARSCNView(frame: self.view.frame)
view.addSubView(sceneView)

Are these two processes identical or are they different?


Solution

  • They are not identical but functionally they are similar. Here's a demonstration of the difference:

    override func viewDidLoad() {
        super.viewDidLoad()
    
        self.view.backgroundColor = UIColor.blue
        let sceneView = UIView(frame: self.view.frame)
        sceneView.backgroundColor = UIColor.red
        self.view.addSubview(sceneView)
    }
    

    In the debugger:

    subview

    Compare to replacing:

    override func viewDidLoad() {
        super.viewDidLoad()
    
        self.view.backgroundColor = UIColor.blue
        let sceneView = UIView(frame: self.view.frame)
        sceneView.backgroundColor = UIColor.red
        self.view = sceneView
    }
    

    In the debugger:

    subview

    So you see that though it's hidden by the subview, the original blue view is still in the view hierarchy when sceneView is added as a subview. When you replace the view though, the original blue view is no longer part of the view hierarchy at all.

    Note: If you want to set the view in loadView() instead of replacing in viewDidLoad() as rmaddy suggested something like this would work. The trick is getting the proper frame -- if you're in a Navigation Controller for example the frame will be different.

    override func loadView() {
        let sceneView = UIView(frame: UIScreen.main.bounds)
        sceneView.backgroundColor = UIColor.red
        self.view = sceneView
    }