Search code examples
iosobjective-cimessage

Adding childViewController does not include basic settings like background color


Background: I am following Apple's example on making a iMessage app, where I am to present a childViewController (subclass UIViewController) to the MSMessagesAppViewController.

I am doing everything as basic as possible. In my childViewController, this is what I do in viewWillAppear

//ChildViewController.m

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    self.view.backgroundColor = [UIColor blueColor]; //! this does not show

    UILabel *middleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
    middleLabel.text = @"this is the childView"; //! however, this shows up
    middleLabel.center = CGPointMake(self.view.center.x, self.view.frame.size.height*0.20);
    [self.view addSubview:middleLabel];

}

And then in my MSMessagesAppViewController, this is what I do in willBecomeActiveWithConversation (which is basically the same as viewWillAppear)

- (void)willBecomeActiveWithConversation:(MSConversation *)conversation
{
     [super willBecomeActiveWithConversation:conversation];
     UIViewController *viewController;
     viewController = [[UIStoryboard storyboardWithName:@"MainInterface" bundle:nil] instantiateViewControllerWithIdentifier:@"childViewController"];
     [self addChildViewController:viewController];


     viewController.view.frame = self.view.bounds;
     viewController.view.translatesAutoresizingMaskIntoConstraints = NO;
     viewController.view.center = self.view.center;
     [self.view addSubview:viewController.view];

     [viewController didMoveToParentViewController:self];

}

As you can see, nothing special, and yet the issue I am running is the background will not become yellow colored, although I set it in my childViewController.

Edit

Additional tests show that gesture recognizers in the ChildViewController also somehow becomes disabled, and the same with UIButtons.

For those curious, the source code is on Github.


Solution

  • The key reason here is the code below:

    viewController.view.frame = self.view.bounds;
    viewController.view.translatesAutoresizingMaskIntoConstraints = NO;
    viewController.view.center = self.view.center;
    

    For some reasons, it is not correct.

    1. The bounds of self.view will change, it will not always be the previous self.view.bounds. The frame of the view of your childViewController will not be self.view.bounds.

    2. Since 1 is not correct, viewController.view.translatesAutoresizingMaskIntoConstraints = NO; and viewController.view.center = self.view.center; will make something even worse. Your view of the child view controller will not be at the position as you think.

    3. If you do not understand, you can try delete viewController.view.translatesAutoresizingMaskIntoConstraints = NO; and viewController.view.center = self.view.center; and set some other frame to viewController.view.frame to test it.

    4. Gesture recognizers are disabled is in the same reason that you set a wrong frame.

    Useless codes:

    viewController.view.center = self.view.center;
    

    If viewController.view.frame == self.view.bounds, it is useless to set their center equal. CGRect actual determines the center of a position.

    Solution:

    Use auto layout to set the position of viewController.view or get the actual frame of your views frame.