2

The situation

I add a view (loaded by a view controller) to another view. After having added it, the view has a size equal to (0,0). I don't understand why and I would like to know.

I know how to solve this problem (with constraints, either created automatically with view.translatesAutoresizingMaskIntoConstraints = YES either created "by hand").

What I really want is understanding why, in this case, it does not work.

Code

Code of my main View Controller

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIView *mainView;
@property (nonatomic, strong, readwrite) ColorViewController * colorVC ;
@end

@implementation ViewController

+ (void)fillView:(UIView *)bigView
        withView:(UIView *)view
{
    view.translatesAutoresizingMaskIntoConstraints = NO ;
    //     view.translatesAutoresizingMaskIntoConstraints = YES ;

    view.frame = bigView.bounds ;

    [bigView addSubview:view] ;
}


- (void)viewDidLoad
{
    [super viewDidLoad];

    self.colorVC = [ColorViewController new] ;

    [ViewController fillView:self.mainView
                    withView:self.colorVC.view] ;
}


@end

The associated storyboard enter image description here Capture d’écran 2015-04-30 à 17.25.32.png

Code of ColorViewController

@implementation ColorViewController

- (void)viewDidLoad {
    [super viewDidLoad];


    CGFloat hue = ( arc4random() % 256 / 256.0 );  //  0.0 to 1.0
    CGFloat saturation = ( arc4random() % 128 / 256.0 ) + 0.5;  //  0.5 to 1.0, away from white
    CGFloat brightness = ( arc4random() % 128 / 256.0 ) + 0.5;  //  0.5 to 1.0, away from black
    UIColor *color = [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:1];

    self.view.backgroundColor = color ;
}


@end

Its XIB

enter image description here

Log

If I log the view (of ColorViewController), I get:

2015-04-30 17:33:58.329 TEST_SUBVIEWS[51745:602214] <UIView: 0x7b4191e0; frame = (-179 -236; 0 0); autoresize = RM+BM; layer = <CALayer: 0x7b418ce0>>

The strangest things

  • What is really strange in this is that if I remove the only object in the above XIB (the UILabel), then, everything works well.

  • Also, if I create the view with [UIView new] and then use the same method to add it to the "main view", then everything works well.

Strange?

Link to a minimal non-working example on github

https://github.com/colasjojo/ToyProjectForIssueWithSize

Colas
  • 3,473
  • 4
  • 29
  • 68
  • I don't understand your code. Why are you making `newView` and then throwing it away? And what is `self.mainView`? Is it the same as `self.view`? – matt Apr 30 '15 at 16:42
  • Sorry, `newView` is useless, I will remove it. `self.mainView` is an `IBoutlet` from the storyboard. `self.view` is totally unrelated. It belongs to `ColorViewController`. – Colas Apr 30 '15 at 16:52
  • 1
    Yup, got it (by looking at the github project, good idea putting that up) – matt Apr 30 '15 at 16:57
  • When you embed a view controller's view in another view controller, you need to tell both view controllers - so that appropriate layout/touch related messages are forwarded to the child. See "Implementing a Custom Container View Controller" in [this Apple Documentation](https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/CreatingCustomContainerViewControllers/CreatingCustomContainerViewControllers.html) – pbasdf Apr 30 '15 at 17:00
  • But I am not implementing a Custom Container View Controller !!!! – Colas Apr 30 '15 at 17:02
  • 1
    You are putting one VC's view as a subview of another VC, so I think you will need to use the `addChildViewController` and `didMoveToParentViewController` type handoff described in that document. – pbasdf Apr 30 '15 at 17:08
  • http://stackoverflow.com/questions/29973948/shall-i-really-use-addchildviewcontroller-when-i-add-a-view-to-another-view – Colas Apr 30 '15 at 17:16

1 Answers1

5
view.translatesAutoresizingMaskIntoConstraints = NO ;

That means: "Use auto layout to set my size and position." But you have no auto layout constraints, so you get nonsense when layout occurs. Thus the inserted view never appears.

You also ask about the presence / absence of the label and how it affects this result. It isn't just a label. It's any subview. It's because the presence of subviews affects how auto layout operates. With no subviews, auto layout seems to say, "okay, nothing to do here". Thus, you do see the inserted view in the right place, but that's sort of an accident (just dumb luck, if you see what I mean).

view.translatesAutoresizingMaskIntoConstraints = YES;

That means: use my frame to make constraints. Thus, when layout happens, we do have constraints and the inserted view view appears where you expect.

In your case, you are best off saying nothing in your code about translatesAutoresizingMaskIntoConstraints, because you have not applied any explicit constraints to your views, so you are given implicit constraints derived from the frame, which is what you want. Alternatively, you could turn off auto layout entirely - it is turned on in both your nibs.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • OK, but how do you explain that if your remove the `UILabel` from the `XIB` of `ColorViewController`, then it works? – Colas Apr 30 '15 at 17:03
  • By the way, do you know some good documents explaining stuff about `translatesAutoresizingMaskIntoConstraints`? Thanks! – Colas Apr 30 '15 at 17:04
  • Added more about the label to my answer. – matt Apr 30 '15 at 17:10
  • I do know a good explanation of auto layout but modesty prevents me from mentioning it. :) – matt Apr 30 '15 at 17:17
  • 1
    Meaning you are an Apple developer and created this system? – Colas Apr 30 '15 at 17:17
  • No, I've never worked for Apple (or anyone), and I think Ken Ferry created auto layout. He is smarter than I am! Trust me on that one. – matt Apr 30 '15 at 17:18
  • So, what does your modesty prevent you to tell me? – Colas Apr 30 '15 at 19:26
  • Another remark: if I add an empty view, in the same way, but the view is created by `[UIView new]` and not *via* a controller, I don't have the problem... – Colas May 01 '15 at 09:09