Почему рамка просмотра childViewController случайно изменяется системой после updateViewConstraints

Я создал пользовательский контейнер viewController, используя модель «родитель-потомок». В родительском я создаю дочерний элемент следующим образом:

 // Show Friends view of childs' controller AddFriendViewController
    self.friendVC = [[AddFriendViewController alloc] init];
    [self addChildViewController:self.friendVC];
    self.friendVC.view.frame = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height);
    [self.view addSubview:self.friendVC.view];
    [self.friendVC didMoveToParentViewController:self];

А затем в дочернем (frienVC) «loadView» я инициализировал дочерний вид следующим образом, а также создал UIView (topBarView), который буду отображать на дочернем VC:

- (void)loadView {
    self.view = [[UIView alloc]init];
    self.view.backgroundColor = [UIColor colorWithHex:SCREEN_ADDFRIENDVIEWCONTROLLER_COLOR];

    // Create topBar view
    self.topBarView = [[UIView alloc] init];
    [self.containerView addSubview:self.topBarView];
}

Теперь я использую ограничения автоматического макета, чтобы расположить «topBarView» в дочернем представлении. И я заметил кое-что очень странное. В « updateViewConstraints », где я установил положение и размер «topBarView», кадр дочернего представления равен (0,0,320,568), что совершенно правильно. Но в методе "viewDidAppear:", который вызывается ПОСЛЕ метода "updateViewConstraints", кадр просмотра дочернего элемента внезапно изменился на (284,160,0,0), что является ПОЛНОСТЬЮ случайным кадром.

Почему система устанавливает кадр дочернего кадра просмотра после вызова метода updateViewConstraints?


person malena    schedule 24.08.2015    source источник


Ответы (1)


Я нашел проблему. Похоже, что установка «фрейма» для представления childViewController не является безопасным способом установки положения и размера представления дочернего элемента, поскольку он сбрасывается системой, если в дочернем vc используются ограничения для установки других представлений внутри него. По какой-то причине «кадр» сбрасывается на какой-то случайный кадр с шириной 0 и высотой 0 в контроллере дочернего представления, и поэтому дочернее представление vc никогда не отображается. Путем проб и ошибок я обнаружил, что использование ограничений для установки всех позиций и размеров UIViews работает. Поэтому вместо установки «фрейма» дочернего контроллера представления в родительском контроллере представления я использую ограничения следующим образом:

    self.friendVC = [[AddFriendViewController alloc] init];

    [self addChildViewController:self.friendVC];
    [self.view addSubview:self.friendVC.view];
    [self.view setTranslatesAutoresizingMaskIntoConstraints:NO];

    NSDictionary *viewsDictionary = @{ @"cview":self.self.friendVC.view};

    [self.view addConstraints:[NSLayoutConstraint
                               constraintsWithVisualFormat:@"H:|[cview]|"
                               options:0 metrics:nil
                               views:viewsDictionary]];
    [self.view addConstraints:[NSLayoutConstraint
                               constraintsWithVisualFormat:@"V:|[cview]|"
                               options:0 metrics:nil
                               views:viewsDictionary]];

    [self.friendVC didMoveToParentViewController:self];

Затем в дочернем vc в методе loadView я просто выделяю память и инициализирую представление. Здесь нет необходимости устанавливать размер дочернего представления, потому что это то, что родитель делает с ограничениями. Автоматическое изменение размера также необходимо отключить для вида Child и всех остальных представлений внутри него.

(void)loadView {
self.view = [[UIView alloc]init];
self.view.backgroundColor = [UIColor 
colorWithHex:SCREEN_ADDFRIENDVIEWCONTROLLER_COLOR];

[self.view setTranslatesAutoresizingMaskIntoConstraints:NO];

Затем в «viewDidAppear», когда дочернее представление загрузится и появится, рекомендуется добавить дополнительные UIView в дочернее представление, снова используя ограничения вместо установки «фреймов».

- (void)viewDidAppear:(BOOL)animated {

//Add topBarView constraints

self.topBarView = [[UIView alloc] init];
[self.view addSubview:self.topBarView];
[self.topBarView setTranslatesAutoresizingMaskIntoConstraints:NO];

NSDictionary *viewsDictionary = @{ @"topBarView":self.topBarView};

NSDictionary *metrics = @{@"topBarHeight":[NSNumber numberWithFloat:SCREEN_ADDFRIENDVC_TOPBAR_HEIGHT]};


NSArray *topBarView_V = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[topBarView(==topBarHeight)]" options:0 metrics:metrics views:viewsDictionary];

NSArray *topBarView_H = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[topBarView]|" options:0 metrics:metrics views:viewsDictionary];

[self.view addConstraints:topBarView_V];
[self.view addConstraints:topBarView_H];




self.topBarView.backgroundColor = [UIColor colorWithHex:SCREEN_ADDFRIENDVC_TOPBAR_COLOR];

И это сработало для меня. Таким образом, в начале основной урок состоит в том, чтобы не смешивать настройки «фреймов» с «ограничениями», а просто придерживаться ограничений в основном.

person malena    schedule 24.08.2015