2013-07-29 3 views
5

У меня есть два контроллера вида, родительский и дочерний.Ограничения автоопределения и контроллер дочернего представления

Таким образом, в методе viewDidLoad я делаю следующее:

ChildViewController* childViewController = [[ChildViewController alloc] init]; 

[self addChildViewController:childViewController]; 

// ChildViewController sets his own constraints in viewDidLoad 
[self.view addSubview:childViewController.view]; 

[childViewController didMoveToParentViewController:self]; 

// 
// setup constraints to expand childViewController.view to 
// fill the size of parent view controller 
// 

Так в основном то, что происходит, что updateViewConstraints вызывается ChildViewController Перед ограничениями родительского контроллера применяются, поэтому на самом деле self.view.frame == CGRectZero, точно так же, как я указал в изготовленный под заказ loadView способ в ChildViewController.

translatesAutoresizingMaskIntoConstraints все установлено на NO для всех просмотров.

Каков правильный способ установки ограничений в этом случае, так что ChildViewController обновляет свои ограничения после родительского?

Текущий журнал обоих контроллеров довольно сложно, я не понимаю, как updateViewConstraints может быть вызван до viewWillLayoutSubviews:

App[47933:c07] ChildViewController::updateViewConstraints. RECT: {{0, 0}, {0, 0}} 
App[47933:c07] ParentViewController::updateViewConstraints 
App[47933:c07] ChildViewController:viewWillLayoutSubviews. RECT: {{0, 0}, {984, 454}} 
App[47933:c07] ChildViewController:viewDidLayoutSubviews. RECT: {{0, 0}, {984, 454}} 
+0

Вам нужно показать код, в котором вы фактически добавляете свои ограничения, иначе сложно сказать, что не так. – Maarten

+0

@Maarten Я решил проблему и ответил ниже, не уверен, что это решение, которое я искал, кажется неправильным, но оно работает. Извините, что я не могу опубликовать код, это слишком много кода ... – Andy

ответ

1

Согласно the following link, я переместил создание ограничений на viewWillLayoutSubviews, это место, где границы вида установлены правильно. Я чувствую, что этот ответ пропускает объяснение того, почему обновление контроллера восходящего контроллера Childview вызывает вызовы родительского контроля, или, может быть, это просто ошибка в моем коде, но это решение решает проблему ...

1
  1. Я думаю, что метод layoutIfNeeded будет работать только если вы раньше называли setNeedsLayout. Если вместо этого вы используете setNeedsLayout, система будет знать, что она будет обновляться в соответствующее время. Попытайтесь изменить это в своем коде.

  2. Когда вы добавляете ограничения в представление, это представление должно автоматически компоновать свои подпрограммы снова, чтобы учесть новые ограничения. Не нужно будет звонить setNeedsLayout, если что-то не изменилось с тех пор, как вы добавили ограничения. Вы добавляете ограничения в представление, и если да: добавляете ли вы их в правильное представление?

  3. Одна вещь, вы можете попробовать это подкласс UIView так, что вы видите сообщение журнала всякий раз, когда ChildViewController.view или ParentViewController.view выполняет свежий макет:

    -(void) layoutSubviews { 
        [super layoutSubviews]; 
        NSLog(@"layoutSubviews was called on the following view: %@", [view description]); 
    } 
    

Может быть, покажет что-то о том, когда ваши взгляды (или не являются) компоновкой своих подзонов.

+0

Правильно, layoutIfNeeded ничего не меняет, если setNeedsUpdateConstraints ранее не использовался. Это мой лог в данный момент: ChildViewController :: updateViewConstraints. RECT: {{0, 0}, {0, 0}} ParentViewController :: updateViewConstraints ChildViewController_view :: layoutSubviews – Andy

+0

Итак, сначала обновлен контроллер для детей, затем родительский. Все ограничения созданы в viewDidLoad, поэтому я не совсем понимаю, как это возможно. – Andy

3

У меня такая же ситуация, когда я добавляю дочерний контроллер к видимому контроллеру (всплывающее окно).

Я определяю контроллер детского вида в построителе интерфейса. Метод viewDidLoad просто вызывает setTranslatesAutoresizingMaskIntoConstraints: NO

Затем я определяю этот метод на дочернем контроллере, который принимает параметр UIViewController, который является родительским. Этого метод добавляет себя к данному контроллеру вида материнского и определяет свои собственные ограничения:

- (void) addPopupToController:(UIViewController *)parent { 
    UIView *view = [self view]; 
    [self willMoveToParentViewController:parent]; 
    [parent addChildViewController:self]; 
    [parent.view addSubview:view]; 
    [self didMoveToParentViewController:parent]; 

    NSArray *horizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[view]-0-|" 
                      options:0 
                      metrics:nil 
                       views:NSDictionaryOfVariableBindings(view)]; 
    [parent.view addConstraints:horizontalConstraints]; 

    NSArray *verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[view]-0-|" 
                      options:0 
                      metrics:nil 
                      views:NSDictionaryOfVariableBindings(view)]; 
    [parent.view addConstraints:verticalConstraints]; 
} 

затем внутри родительского UIViewController (тот, который уже отображается), когда я хочу показать мой ребенок всплывающего контроллер представления он называет :

PopUpNotificationViewController *popup = [[self storyboard] instantiateViewControllerWithIdentifier:@"NotificationPopup"]; 
[popup addPopupToController:self]; 

вы можете определять любые ограничения вы хотите на просмотр контроллера дочернего при добавлении его мнению родительского контроллера.

Смежные вопросы