Потому-что, так никто не делает, ну кроме Вас. Для работы 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)
])
Уточнение получены. Продолжим.
Для начала уточним, как нам добиться динамического размера вьюхи в ширину и высоту. Приведу простой и наглядный пример. Создам вьюхи и помещу туда два лейбла. Пишу всё исключительно кодом, т.к. не использую сториборд, но думаю свести проблем не составит. И так:
Код текстом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). Кстати, быть может в сториборде приоритет снижать не придется. Проверьте. (Кажись система делаем это за вас)
С шириной всё готово. Смотрим на костреинты для высоты. Тут вполне обычно, начинаем с топ. После нижний лейбл крепится к боттом первого. И снова небольшая магия. Последний нижний констрейнт снова с пониженным приоритетом. Кстати, быть может в сториборде приоритет снижать не придется. Проверьте. (Кажись система делаем это за вас)
Если быть точнее снижая приоритет(по крайне мере если задавать их кодом) такой подход даёт понять системе, что высоту и ширину он прямиком и полностью должен расчитывать исходя из высоты и ширины его сабвьюх, а не назначить свои значения.
Поглядим на примеры:
Первая имеет
меньший размер шрифта, но
больше символов.
Первая имеет
больший размер шрифта, но
больше символов.
Первая имеет
меньший размер шрифта, но
меньше символов.
Первая имеет
больший размер шрифта, но
меньше символов.
Как видимо размер вьюхи система посчитала вольностью верным. То есть мы динамически научились задавать высоту и ширину ячейки.
Поехали дальше.
Но для ячеек есть ещё одна небольшая проблема. Система лайаута коллекции имеет все нужные констреинты, но она ничего не знает о данных в этих ячеек. А ведь именно они задают ширину ячеейки. Для этого нам нужно в какой-то момент времени немного подсказать системе.
Воспользуемся методом:
Код текстом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