Потому-что, так никто не делает, ну кроме Вас. Для работы auto layout нужно построить цепочку ограничений сверху вниз.
Что бы не спрашивать что у Вас есть, а что нет, сразу напишу полный список./
1) Прописать у layout коллекции:
// ...
layout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
layout.itemSize = UICollectionViewFlowLayout.automaticSize
2) Соврал, нужно уточнение.
pronunciationLabel - Сколько строк должен занимать? (Только одну?) Увеличивается только в ширину?
wordLabel - Тоже, что и pronunciationLabel? Или увеличивается в высоту?
3) Этот бред больше никогда не нужно делать.
contentView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
contentView.leftAnchor.constraint(equalTo: leftAnchor),
contentView.rightAnchor.constraint(equalTo: rightAnchor),
contentView.topAnchor.constraint(equalTo: topAnchor),
contentView.bottomAnchor.constraint(equalTo: bottomAnchor)
])
Уточнение получены. Продолжим.
Для начала уточним, как нам добиться динамического размера вьюхи в ширину и высоту. Приведу простой и наглядный пример. Создам вьюхи и помещу туда два лейбла. Пишу всё исключительно кодом, т.к. не использую сториборд, но думаю свести проблем не составит. И так:
![5cab4bce2a9a6308684642.png](https://habrastorage.org/webt/5c/ab/4b/5cab4bce2a9a6308684642.png)
Код текстомlet v = UIView(frame: .zero)
let l1 = UILabel(frame: .zero)
l1.translatesAutoresizingMaskIntoConstraints = false
l1.font = .systemFont(ofSize: 27.0)
l1.text = "asdlas"
v.addSubview(l1)
NSLayoutConstraint.activate([
l1.topAnchor.constraint(equalTo: v.topAnchor),
l1.leadingAnchor.constraint(equalTo: v.leadingAnchor),
])
l1.setContentHuggingPriority(.required, for: .vertical)
l1.setContentCompressionResistancePriority(.required, for: .vertical)
let trailing = l1.trailingAnchor.constraint(equalTo: v.trailingAnchor)
trailing.priority = .defaultHigh
NSLayoutConstraint.activate([
trailing
])
let l2 = UILabel(frame: .zero)
l2.translatesAutoresizingMaskIntoConstraints = false
l2.font = .systemFont(ofSize: 17.0)
l2.text = ""
v.addSubview(l2)
NSLayoutConstraint.activate([
l2.topAnchor.constraint(equalTo: l1.bottomAnchor),
l2.leadingAnchor.constraint(equalTo: v.leadingAnchor),
])
l2.setContentHuggingPriority(.required, for: .vertical)
l2.setContentCompressionResistancePriority(.required, for: .vertical)
let trailing_ = l2.trailingAnchor.constraint(equalTo: v.trailingAnchor)
trailing_.priority = .defaultHigh
let bottom = l2.bottomAnchor.constraint(equalTo: v.bottomAnchor)
bottom.priority = .defaultHigh
NSLayoutConstraint.activate([
trailing_,
bottom
])
let s = v.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
view.addSubview(v)
v.frame.size = s
v.center = view.center
v.layer.borderColor = UIColor.red.cgColor
v.layer.borderWidth = 1.0
В принципе мы делаем обычные констрениты, задавая топ и лидинг. Примечателен тут другой момент, а именно трейлинг. Перед его заданием, мы обязательно установили св-ва сопротивление сжатию и сопротивления расстяжения обоим лейблам, давая тем самым системе понять, что хотим видеть лейбл ровно такой ширины, какой он есть на самом деле. После мы делаем констрейнт трейлинг и указываем ему приоритет немного ниже чем 1000(required). Кстати, быть может в сториборде приоритет снижать не придется. Проверьте. (Кажись система делаем это за вас)
С шириной всё готово. Смотрим на костреинты для высоты. Тут вполне обычно, начинаем с топ. После нижний лейбл крепится к боттом первого. И снова небольшая магия. Последний нижний констрейнт снова с пониженным приоритетом. Кстати, быть может в сториборде приоритет снижать не придется. Проверьте. (Кажись система делаем это за вас)
Если быть точнее снижая приоритет(по крайне мере если задавать их кодом) такой подход даёт понять системе, что высоту и ширину он прямиком и полностью должен расчитывать исходя из высоты и ширины его сабвьюх, а не назначить свои значения.
Поглядим на примеры:
Первая имеет
меньший размер шрифта, но
больше символов.
![HC2w483.png](https://i.imgur.com/HC2w483.png)
Первая имеет
больший размер шрифта, но
больше символов.
![5MhP2nj.png](https://i.imgur.com/5MhP2nj.png)
Первая имеет
меньший размер шрифта, но
меньше символов.
![V00A7Qc.png](https://i.imgur.com/V00A7Qc.png)
Первая имеет
больший размер шрифта, но
меньше символов.
![zXH8glH.png](https://i.imgur.com/zXH8glH.png)
Как видимо размер вьюхи система посчитала вольностью верным. То есть мы динамически научились задавать высоту и ширину ячейки.
Поехали дальше.
Но для ячеек есть ещё одна небольшая проблема. Система лайаута коллекции имеет все нужные констреинты, но она ничего не знает о данных в этих ячеек. А ведь именно они задают ширину ячеейки. Для этого нам нужно в какой-то момент времени немного подсказать системе.
Воспользуемся методом:
![5cab50033a6e2506454233.png](https://habrastorage.org/webt/5c/ab/50/5cab50033a6e2506454233.png)
Код текстомfunc preferredLayoutAttributesFitting(
_ layoutAttributes: UICollectionViewLayoutAttributes
) -> UICollectionViewLayoutAttributes
{
let layoutAttributes = super.preferredLayoutAttributesFitting(layoutAttributes)
let fittingSize = UIView.layoutFittingCompressedSize
layoutAttributes.frame.size = systemLayoutSizeFitting(
fittingSize,
withHorizontalFittingPriority: .fittingSizeLevel,
verticalFittingPriority: .fittingSizeLevel
)
return layoutAttributes
}
Так как все констреинты у нас настроены, нам осталась попросить систему подсчитать нужные размеры и передать новые размеры системе лайаута коллекции. В этот момент кстати, все данные ячейка уже получила. (Текст для лейблов)
И малая ремарка, возможно в метод
preferredLayoutAttributesFitting после вызова super. надо будет добавить вызов метода
layoutIfNeeded(). А может и не нужно.
Итого:
Добавляем то, что в пункте 1.
Устанавливаем нужные констреинты.
Удаляем ваш код в пункте 3.
Добавляем метод preferredLayoutAttributesFitting