Автозапуск iOS 8, VFL и маржа равны или больше, чем

У меня возникают проблемы с ограничениями в VFL на iOS 8, а на 6 и 7 все в порядке. Это ограничение:

H:|-margin-[_imageView]-(=>margin)-[_label]-margin-|

Оба _imageView_ и _label получают свою правильную внутреннюю ширину, и маржа растет, как ожидалось. Я хочу достичь

|-[_imageView]-------------------------------[some text]-|

|-[_imageView]---------------------------[a larger text]-|

|-[_imageView]-----------------------[a very large text]-|

|-[_imageView]-[a very very very very very very larg...]-|

Это нормально визуально, но оно вызывает исключение с нарушенным ограничением:

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x7b856ee0 H:[UIImageView:0x7b8ef1f0]-(>=12)-[UILabel:0x7b8e7c60'Test']>

После печати _autolayoutTrace нет двусмысленности.

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

H:|-margin-[_label1]-(=>margin)-[_label2]-margin-|

Проблема может быть решена в следующих шагах:

Изменение ограничения на удаление >= и добавление приоритетов:

H:|-margin-[_imageView]-([email protected])-[_label]-margin-|

Настройка приоритета обхода для _imageView

[_imageView setContentHuggingPriority:UILayoutPriorityDefaultHigh forAxis:UILayoutConstraintAxisHorizontal];

Установка сопротивления сжатия _label

[_label setContentCompressionResistancePriority:UILayoutPriorityDefaultLow forAxis:UILayoutConstraintAxisHorizontal];

С этими правилами на любой платформе нет проблем. Все это необходимо на iOS 8? Это ошибка, или я делал это неправильно?

Спасибо.

Ответ 1

Я начал проект с нуля, и вот мой код (который на самом деле отлично работает):

UIView *topView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 200)];
topView.backgroundColor = [UIColor redColor];
topView.translatesAutoresizingMaskIntoConstraints = NO;

UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(20, 20, 40, 160)];
imageView.backgroundColor = [UIColor greenColor];
imageView.translatesAutoresizingMaskIntoConstraints = NO;
[topView addSubview:imageView];

self.label = [[UILabel alloc] initWithFrame:CGRectMake(80, 80, 200, 32)];
self.label.backgroundColor = [UIColor yellowColor];
self.label.text = @"some text";
self.label.translatesAutoresizingMaskIntoConstraints = NO;
[topView addSubview:self.label];


self.tableView.tableHeaderView = topView;

NSDictionary *views = @{@"imageView":imageView, @"label":self.label};

NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-margin-[imageView(40)]-(>=margin)-[label]-margin-|" options:0 metrics:@{@"margin": @30} views:views];
NSArray *imageConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[imageView(160)]-20-|" options:0 metrics:nil views:views];
NSArray *textConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-40-[label]" options:0 metrics:nil views:views];
NSArray *topConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:[topView(320)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(topView)];

[topView addConstraints:constraints];
[topView addConstraints:imageConstraints];
[topView addConstraints:textConstraints];
[topView addConstraints:topConstraints];

Я думаю, что ваша основная проблема заключается в том, что вы не отключите translatesAutoresizingMaskIntoConstraints, который создает UIView-Encapsulated-Layout (которого я никогда не встречал до iOs8). Я не нашел места, где он хорошо документирован, но есть ряд вопросов относительно этого ограничения.

Я также создал github repo, поэтому вы можете попробовать: https://github.com/Nikita2k/constraintsTest

Кроме того, вы можете посмотреть видео WWDC2014 - Что нового в представлении таблицы и коллекции (~ 20 минут). Есть информация, что вы можете увидеть проблему UIView-Encapsulated-Layout, но она будет исправлена ​​позже. Кроме того, вы можете попробовать играть с rowHeight, так как все таблицы iOS8 tableViews из раскадровки (или xib) должны явно устанавливать

self.tableView.rowHeight = UITableViewAutomaticDimension

Я не уверен, поможет ли это в этом конкретном случае или нет, но попробуйте тоже!