Построение titleView программно с ограничениями (или вообще построение представления с ограничениями)

Я пытаюсь создать titleView с ограничениями, которые выглядят так:

Я знаю, как бы это сделать с помощью фреймов. Я бы вычислил ширину текста, ширину изображения, создал бы представление с этой шириной /, высотой, чтобы содержать оба, затем добавил бы оба как подпредставления в надлежащих местах с рамками.

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

UILabel *categoryNameLabel = [[UILabel alloc] init];
categoryNameLabel.text = categoryName; // a variable from elsewhere that has a category like "Popular"
categoryNameLabel.translatesAutoresizingMaskIntoConstraints = NO;
[categoryNameLabel sizeToFit]; // hoping to set it to the instrinsic size of the text?

UIView *titleView = [[UIView alloc] init]; // no frame here right?
[titleView addSubview:categoryNameLabel];
NSArray *constraints;
if (categoryImage) {
    UIImageView *categoryImageView = [[UIImageView alloc] initWithImage:categoryImage];
    [titleView addSubview:categoryImageView];
    categoryImageView.translatesAutoresizingMaskIntoConstraints = NO;
    constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|[categoryImageView]-[categoryNameLabel]|" options:NSLayoutFormatAlignAllTop metrics:nil views:NSDictionaryOfVariableBindings(categoryImageView, categoryNameLabel)];
} else {
    constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|[categoryNameLabel]|" options:NSLayoutFormatAlignAllTop metrics:nil views:NSDictionaryOfVariableBindings(categoryNameLabel)];
}
[titleView addConstraints:constraints];


// here I set the titleView to the navigationItem.titleView

Мне не нужно жестко кодировать размер titleView. Его можно определить по размеру его содержимого, но ...

TitleView определяет, что его размер равен 0, если я не жестко закодировал кадр.Если я установлюtranslatesAutoresizingMaskIntoConstraints = NO приложение вылетает с этой ошибкой:'Auto Layout still required after executing -layoutSubviews. UINavigationBar's implementation of -layoutSubviews needs to call super.'Обновить

Я получил его для работы с этим кодом, но мне все еще нужно установить кадр в titleView:

UILabel *categoryNameLabel = [[UILabel alloc] init];
categoryNameLabel.translatesAutoresizingMaskIntoConstraints = NO;
categoryNameLabel.text = categoryName;
categoryNameLabel.opaque = NO;
categoryNameLabel.backgroundColor = [UIColor clearColor];

UIView *titleView = [[UIView alloc] init];
[titleView addSubview:categoryNameLabel];
NSArray *constraints;
if (categoryImage) {
    UIImageView *categoryImageView = [[UIImageView alloc] initWithImage:categoryImage];
    [titleView addSubview:categoryImageView];
    categoryImageView.translatesAutoresizingMaskIntoConstraints = NO;
    constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|[categoryImageView]-7-[categoryNameLabel]|" options:NSLayoutFormatAlignAllCenterY metrics:nil views:NSDictionaryOfVariableBindings(categoryImageView, categoryNameLabel)];
    [titleView addConstraints:constraints];
    constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[categoryImageView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(categoryImageView)];
    [titleView addConstraints:constraints];

    titleView.frame = CGRectMake(0, 0, categoryImageView.frame.size.width + 7 + categoryNameLabel.intrinsicContentSize.width, categoryImageView.frame.size.height);
} else {
    constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|[categoryNameLabel]|" options:NSLayoutFormatAlignAllTop metrics:nil views:NSDictionaryOfVariableBindings(categoryNameLabel)];
    [titleView addConstraints:constraints];
    constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[categoryNameLabel]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(categoryNameLabel)];
    [titleView addConstraints:constraints];
    titleView.frame = CGRectMake(0, 0, categoryNameLabel.intrinsicContentSize.width, categoryNameLabel.intrinsicContentSize.height);
}
return titleView;

Ответы на вопрос(5)

Ваш ответ на вопрос