Jimmery
Jimmery

Reputation: 10139

Identical View Controllers Displaying Differently

I have two child view controllers, that as far as I can tell are identical, however one of them is acting unexpectedly.

The two child view controllers are called MenuLoggedInViewController and MenuLoggedOutViewController. Their container view controller has the following code:

override func viewDidLoad() {
    super.viewDidLoad()

    // i comment out one of these two lines to produce the different results:
    self.masterView = MenuLoggedOutViewController(nibName: "MenuLoggedOutViewController", bundle: nil)
    // self.masterView = MenuLoggedInViewController(nibName: "MenuLoggedInViewController", bundle: nil)

    self.detailView = RootViewController(nibName: "RootViewController", bundle: nil)
    self.masterViewFrame = CGRectMake(0, 0, self.view.frame.width, 50)
    self.detailViewFrame = CGRectMake(0, 50, self.view.frame.width, self.view.frame.height - 50)
    self.addChildViewController(masterView!)
    self.addChildViewController(detailView!)
    self.view.addSubview(masterView!.view)
    self.view.addSubview(detailView!.view)

    masterView!.view.frame = masterViewFrame
    // masterView!.view.bounds = masterViewFrame // - i tried this and it made no difference
    detailView!.view.frame = detailViewFrame
}

The MenuLoggedInViewController and MenuLoggedOutViewController have pretty much identical template code in their swift files:

override func viewDidLoad() {
    super.viewDidLoad()
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

I have not touched the .xib files except to change the background colour. After going through the settings for the .xib files they seem to all be the same. I don't go near the storyboard if I can help it, so I am not too familiar with it. But I spent a long time double checking all the values for the two .xib files and there is no difference between them that I can detect other than the background colour.

<code>MenuLoggedInViewController</code> produces this:

As you can see, the black MenuLoggedInViewController fits snuggly against the white view controller beneath. This is intended.

<code>MenuLoggedOutViewController</code> produces this:

The grey background is the colour of the containing view controller. As you can see the black MenuLoggedOutViewController only goes so far down.

Can anyone explain to me, despite being virtually identical and called with virtually identical code, why the MenuLoggedOutViewController doesn't display properly?

It should be noted that MenuLoggedOutViewController corrects itself if the screen is rotated to the side and then back again to portrait. Then MenuLoggedOutViewController looks like it should (like MenuLoggedInViewController).

Upvotes: 3

Views: 67

Answers (1)

Rob
Rob

Reputation: 438122

It's hard to tell precisely what is going on. If you really want, I'd suggest using NSStringFromCGRect and examining the various frame values and I suspect you'd see what's going on.

But the key conceptual problem is that this code is adjusting the frame values in viewDidLoad, but the frame value is not reliable at that point. I'd suggest either:

  • Move the adjustment of child frame values to viewWillLayoutSubviews. At that point, the main view's frame is reliable.

  • If using auto-layout, don't set the frame values at all, but rather set setTranslatesAutoresizingMaskIntoConstraints to false for these two child views and then add constraints (which you can do in viewDidLoad), whose VFL would effectively be:

    V:|[master(50)][detail]|
    H:|[master]|
    H:|[detail]|
    

As a final, unrelated detail, when calling addChildViewController, after you're done adding the child views, don't forget to call didMoveToParentViewController for each of those child view controllers.

Upvotes: 2

Related Questions