-2

I have been mainly working with storyboard until I recently moving to only creating controller with code.

I followed our coding standard to create some subview in the loadView() function, inside which, the first line is super.loadView().

From what I observed, after I called super.loadView(), the frame of self.view is already set correctly with the viewController itself, which is exactly the frame of the viewController.

My more experience colleagues are saying this was 100% not working in the old days that it should give u CGRectZero instead and probably I should not rely on it.

I want to hear more suggestion from other people.

Here is my sample project setup: 1. create a simple proj 2. add a button in the first VC 3. create second VC by code, override loadView() function in second VC, call super.loadView() there and print self.view.bounds next line 4. self.present or use navigation controller from VC1 in the button action to present or push to VC2 5. it always give me correct frame of the second VC.

Please let me know.

----------- Edit -------------

To clarify my question, I know the lifecycle functions like viewDidLayoutSubviews or layoutSubViews to return the correct view. I am NOT asking these.

My question is why loadView() IS returning me the CORRECT frame now.

Developer Sheldon
  • 2,140
  • 1
  • 11
  • 17
  • Might help you to read http://www.apeth.com/iOSBook/ch19.html#_view_controller_and_view_creation. But in general the short answer is: a view loads at the size that comes from the storyboard or whatever, and is sized by its parent as it is placed into the view hierarchy. – matt May 07 '19 at 01:38
  • @matt I think your comment that is sized by its parent makes sense to me. do we have a support doc from Apple when is this happening? – Developer Sheldon May 07 '19 at 01:42
  • 1
    It doesn't matter when. What you need to know is that it doesn't necessarily have its "real" size in `loadView` or `viewDidLoad` but it certainly does by `viewWillLayoutSubviews` and `viewDidAppear`. In other words, just stick to putting the right code in the right place and all will be well. – matt May 07 '19 at 02:11

2 Answers2

2

Unfortunatelly I cannot give any insights as to what is happening under the hood - what I can do though, is tell you that according to the documentation you shouldn’t be calling super.loadView() :

You can override this method in order to create your views manually. If you choose to do so, assign the root view of your view hierarchy to the view property. The views you create should be unique instances and should not be shared with any other view controller object. Your custom implementation of this method should not call super.

(Emphasis mine)

Losiowaty
  • 7,911
  • 2
  • 32
  • 47
  • I dont think it creates view for me if I am not calling super.loadView. – Developer Sheldon May 07 '19 at 01:28
  • 1
    But... the whole idea of overriding the `loadView()` method is to create the view yourself! It even says so in the documentation, the second sentence in the quoted part. I’m sorry but from this comment it seems that you are trying to use this not for what it was intended to. – Losiowaty May 07 '19 at 01:32
  • That is the idea. I am adding a bunch subviews on the default `self.view`, so that `super.view` is useful to me. – Developer Sheldon May 07 '19 at 01:35
  • 2
    You should be doing that in `viewDidLoad`, not `loadView`. – matt May 07 '19 at 01:37
  • 1
    I agree with @matt (and the docs) - if you want to simply add subviews to `self.view` you should do so in `viewDidLoad()`. – Losiowaty May 07 '19 at 01:46
0

1) I have been mainly working with storyboard until I recently moving to only creating controller with code.

I followed our coding standard to create some subview in the loadView() function, inside which, the first line is super.loadView().

  • Since you are using xibs, use viewDidLoad over loadView because of If you use Interface Builder to create your views and initialize the view controller, you must not override this method. as stated in loadView in Apple Docs.

2) My more experience colleagues are saying this was 100% not working in the old days that it should give u CGRectZero instead and probably I should not rely on it.

I want to hear more suggestion from other people.

  • The proper frame for the viewController.view will be when viewWillLayoutSubviews is called. As for its subviews, viewDidLayoutSubviews is what you will need
  • view frame inside loadView and viewDidLoad are Nib frame size. Your colleagues are correct that it will not return a proper size. This is noticeable upon running an iPad app with viewcontroller presented modally, or run your app on different screen size as contrast to what the device is in xib

ALSO, this question is directly related to yours: Why am I having to manually set my view's frame in viewDidLoad?