Ошибка автоматического макета

У меня была проблема, аналогичная этому плакату. . И я воспользовался предложением jrturton перенести код настройки кнопок в viewDidLayoutSubviews. Он работал хорошо, пока я не получил эту ошибку:

«NSInternalInconsistencyException», причина: «Автоматическая компоновка по-прежнему требуется после отправки -viewDidLayoutSubviews в контроллер представления. Реализация ViewController должна отправить -layoutSubviews в представление, чтобы вызвать автоматическую компоновку.'

Я очень плохо разбираюсь в графике, и единственное, что я мог придумать, это поставить [self.view layoutSubviews];, но это ничего не исправило. Это сработало, когда я снял флажок «Автоматический макет» в своей раскадровке, но это изменило размеры моих кнопок, и мне было интересно, есть ли другой способ исправить это?

Код:

-(void)viewDidLayoutSubviews {
    NSArray *arrayOfButtons = [NSArray arrayWithObjects:self.decimalButton, self.buttonOne, self.buttonTwo, self.buttonThree, nil];

    for (UIButton *button in arrayOfButtons) {

        [button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
        [button setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted];

        button.layer.borderWidth = 0.25f;
        button.layer.borderColor = [[UIColor grayColor] CGColor];

        CAGradientLayer *btnGradient = [CAGradientLayer layer];
        btnGradient.frame = button.bounds;
        btnGradient.colors = [NSArray arrayWithObjects:
                              (id)[[UIColor colorWithRed:122.0f / 255.0f green:188.0f / 255.0f blue:255.0f / 255.0f alpha:1.0f] CGColor],
                              (id)[[UIColor colorWithRed:96.0f / 255.0f green:171.0f / 255.0f blue:248.0f / 255.0f alpha:1.0f] CGColor],
                              nil];
        [button.layer insertSublayer:btnGradient atIndex:0];
    }
}

person stumped    schedule 19.03.2013    source источник
comment
Как насчет звонка [super viewDidLayoutSubviews]? Документы говорят, что реализация по умолчанию ничего не делает, но стоит попробовать.   -  person Chris Wagner    schedule 19.03.2013


Ответы (1)


Недавно у меня была эта проблема, когда я хотел программно настроить кадр представления, созданного раскадровкой, предоставив обработчик сообщений viewDidLayoutSubviews. Следуя инструкции из сообщения об исключении, я попытался добавить [self.view layoutIfNeeded] в конце -viewDidLayoutSubviews, и тогда это сработало.

person Hercrom    schedule 02.07.2013
comment
Я в замешательстве, почему это работает. Кажется, что это должно закончиться бесконечной рекурсией, но это не так. Разве после звонка [self.view layoutSubviews] не будет ли снова звонить viewDidLayoutSubviews и т.д.? - person Snowman; 16.11.2013
comment
Я предполагаю, что есть несколько проходов, в течение которых автоматические макеты устанавливаются, то есть они постепенно помечаются как удовлетворенные или нет, пока не останется неоднозначности. - person Rupert Rawnsley; 10.01.2014
comment
Вы спасли меня. Я уверен, что ошибка указывает на то, что мы должны явно вызывать layoutSubviews перед вызовом реализации super. - person user; 29.06.2014
comment
Это работает, хотя вместо этого я вызвал [self.view layoutIfNeeded], и это тоже сработало — в документах говорится, что никогда нельзя вызывать layoutSubviews напрямую. - person Anna Dickinson; 27.10.2014
comment
Я думаю, есть причина, почему вы получили так много голосов за это. Мы все не совсем понимаем, как это работает, а поскольку исходный код какао не является открытым, мы можем только догадываться. +1 Hercrom за исправление. И +1 @Anna Dickinson за указание на лучшее решение. - person HotFudgeSunday; 08.01.2015
comment
[self.view layoutIfNeeded] должно быть лучше. Но я не уверен, имеет ли это исправление какой-либо побочный эффект на iOS 8? - person Wingzero; 04.03.2015
comment
Кажется, это исправлено на iOS8, этого также не происходит, если вы вместо этого помещаете код в viewWillLayoutSubviews - person aryaxt; 21.05.2015