UIView с динамической высотой, которая использует intrinsicContentSize

Я пытаюсь создать пользовательский контейнерный вид с UIImageView и многострочным UILabel в качестве подзонов. Чтобы сделать представление хорошо работающим с автозапуском, я переопределяю intrinsicContentSize, как показано ниже:

- (CGSize)intrinsicContentSize
{
    return [self sizeThatFits:self.bounds.size];
}

Размер, рассчитанный в sizeThatFits, имеет одинаковую ширину и регулирует высоту, чтобы метки и изображение не были обрезаны. Это хорошо работает, но я был удивлен, увидев в документах следующий комментарий:

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

Если это так, то каков способ автоопределения для корректировки текущей высоты просмотров в зависимости от ее ширины и содержимого? Должен ли я приближаться к этому по-другому?

Ответ 1

Чтобы ответить на мой собственный вопрос, похоже, что в этой ситуации нет подходящего решения для автозапуска. Глядя на UILabel для вдохновения, проблема здесь решена с добавлением свойства preferredMaxLayoutWidth, которое затем может использоваться в качестве ограничивающей ширины при вычислении размера собственного содержимого. Любой пользовательский вид должен использовать что-то подобное.

Ответ 2

Я думаю, что документ означает, что ваш containerView может иметь placeHolderFrame как кадр содержимого.

внутренний размер не должен быть связан с кадром контента, а только с его собственным субконтентом. Например, ваше изображение и UILabel.

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

Просто мое мнение...

Ответ 3

Я думаю, вы могли бы использовать новое свойство preferredMaxLayoutWidth UILabel для ярлыка макета и использовать другие подходы к компоновке других вещей.

Что-то вроде этого:

- (void)layoutSubviews
{
    ...
    [super layoutSubviews]; // get width from solved constraints
    label.preferredMaxLayoutWidth = label.frame.size.width; // use it
    [super layoutSubviews]; // update height of a label (probably intrinsicContentSize)
    ...
}