iOS: автомакет с дочерними контроллерами представления

Я использую autolayout уже пару недель. В настоящее время я использую стороннюю библиотеку под названием FLKAutoLayout, которая упрощает процесс. Я нахожусь в точке, где я могу создавать представления так, как хочу, обычно без проблем. Однако за последние 4 дня на работе я боролся с автомакетом, когда задействованы контроллеры просмотра. Я в порядке со всеми видами UIViews... но по какой-то причине каждый viewcontroller.view - это полный демон. У меня не было ничего, кроме проблем с получением размера viewcontroller.view так, как я хочу, и еще более глубокая проблема заключается в том, что UIView дочерних контроллеров представления не получают должным образом события при использовании автомакета. дочерние контроллеры просмотра прекрасно работают при назначении фреймов вручную, но все ломается с автомакетом.

Я не понимаю, что такого особенного в UIView контроллера представления, что отличает его от всех остальных... Мой разум тает от разочарования. ios возится с моими представлениями контроллера просмотра за кулисами или что-то в этом роде?

пример изображения

На изображении красная область принадлежит дочернему контроллеру представления. Эта область не должна выходить за пределы самого нижнего подвида (карточка с надписью «три»). Это должно быть легко, и я могу заставить его работать нормально с кучей обычных UIViews, но поскольку это контроллер представления, все ломается...

Может кто-нибудь пролить свет на то, что это я не знаю. Любые выводы по потенциальным проблемам очень ценятся.

Спасибо за чтение.

Обновление: проблема может быть связана с неоднозначными ограничениями

UIView *box = [[UIView alloc]init];
[box addSubview:imageView];
[box addSubview:nameLabel];

imageView constrainWidth:@"32" height:@"32"];
[imageView alignTop:@">=0" leading:@"0" bottom:@"<=0" trailing:@"<=0" toView:box];
[imageView alignCenterYWithView:box predicate:@"0"];

[nameLabel constrainLeadingSpaceToView:imageView predicate:@"5"];
[nameLabel alignTop:@">=0" leading:@">=0" bottom:@"<=0" trailing:@"<=0" toView:box];
[nameLabel alignCenterYWithView:box predicate:@"0"];

[self addSubview:box];
[box alignTop:@"5" leading:@"5" bottom:@"-5" trailing:@"-5" toView:self];

В приведенном выше примере неоднозначный макет, но я не могу понять, что с ним не так...


person Sethypie    schedule 10.07.2013    source источник
comment
Вы должны показать код, где вы добавляете дочерний контроллер представления, и какие ограничения вы пытались добавить.   -  person rdelmar    schedule 11.07.2013
comment
Есть ли что-нибудь из этого в виде прокрутки?   -  person Maarten    schedule 11.07.2013
comment
На данный момент в режиме прокрутки ничего нет. Однако в прошлом, когда я пытался использовать прокрутку в автомакете, все представления сжимались, чтобы быть суперкомпактными. Но это еще одна проблема на будущее.   -  person Sethypie    schedule 11.07.2013


Ответы (2)


Вероятно, это должен быть комментарий, но комментарии — отстой для кода. ;-)


Вы проверяли неоднозначные ограничения? Мне кажется, что это представление может быть вызвано неоднозначными ограничениями.

Добавьте этот код в свой делегат приложения:

// before @implementation AppDelegate
@interface UIWindow (AutoLayoutDebug)
+ (UIWindow *)keyWindow;
- (NSString *)_autolayoutTrace;
@end

// inside of @implementation

- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event {
    NSString *autolayoutTrace = [[UIWindow keyWindow] _autolayoutTrace];
    if ([autolayoutTrace rangeOfString:@"AMBIGUOUS"].location != NSNotFound) {
        NSLog(@"%@", autolayoutTrace);
    }
    else {
        NSLog(@"No Ambiguous autolayout found");
    }
}

а теперь встряхни свой симулятор. Вы найдете жест встряхивания в аппаратном меню.

Если он не показывает «Неоднозначный автомакет не найден», проверьте неоднозначный элемент (ы) пользовательского интерфейса в напечатанной трассировке. Они помечены как «НЕОДНОЗНАЧНО».

Затем начните добавлять ограничения, чтобы больше не было двусмысленности.

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


И обязательно удалите код отладки в вашем продукте доставки. Вы можете поместить эти две части внутрь #if DEBUG и #endif.

person Matthias Bauch    schedule 10.07.2013
comment
Спасибо, Матиас! Я нашел кучу неоднозначных раскладок... это отстой, но, по крайней мере, теперь я знаю, на что обратить внимание. Я немного не уверен, как определить, какие представления имеют неоднозначные макеты и что насчет ограничений неоднозначно. Вы упомянули об использовании упражнения AmbiguityInLayout, но я не вижу, где отображается эта информация... в любом случае в окне отладки ничего не отображается. Я использовал этот метод для нескольких UIViews с неоднозначными ограничениями, но, похоже, ничего не происходит. - person Sethypie; 11.07.2013

В определенный момент вашего кода вам нужно добавить дочерний контроллер представления в иерархию контроллеров представления: [topViewController addChildViewController:childViewController];. И не забудьте потом добавить -didMoveToParentViewController:.

Это гарантирует, что ваши события поворота и касания пересылаются так, как вы ожидаете.

Что касается ваших проблем с автомакетом: Эрика Садун написала несколько очень полезные инструменты для отладки автомакета. Я использую его в основном для просмотра viewLayoutDescription, который она написала в категории в UIView, который печатает очень читаемые списки ограничений, сообщает вам о двусмысленности и т. д. Попробуйте, это действительно помогло мне понять, как были мои ограничения. запутался.

Второе: всегда следите за тем, чтобы во всех ваших представлениях translateAutoresizingMasksIntoConstraints было установлено на NO.

person Maarten    schedule 11.07.2013