В вертикальном UICollectionView
,
Можно ли иметь ячейки полной ширины , но разрешить управление динамической высотой с помощью автоматического размещения ?
Это кажется мне, пожалуй, «самым важным вопросом в iOS, на который нет действительно хорошего ответа».
Важный:
Обратите внимание, что в 99% случаев для достижения полной ширины ячеек + динамической высоты автоматического раскладки просто используйте табличное представление. Это так просто.
Итак, каков пример того, где вам нужно представление коллекции?
Представления коллекций невероятно мощнее табличных представлений.
Один простой пример, в котором вам действительно нужно использовать представление коллекции для достижения ячеек полной ширины + динамической высоты автоматического раскладки:
Если вы выполняете анимацию между двумя макетами в представлении коллекции. Например, между макетом с 1 и 2 столбцами, когда устройство вращается.
Это обычная и нормальная идиома в iOS. К сожалению, этого можно достичь только путем решения проблемы, поставленной в этом QA. : - /
источник
SpringDamping
иinitialSpringVelocity
) в таблице Cell ..... посмотрите этот Bouncy List с помощью tableView ,,,, pastebin.com/pFRQhkrX вы можете анимироватьTableViewCell
в таблице вwillDisplayCell:(UITableViewCell *)cell
методе delgate @Fattie, который вы можете принять ответ, который решил вашу проблему, чтобы помочь другим, кто ищет ту же проблемуОтветы:
1. Решение для iOS 13+
В Swift 5.1 и iOS 13 вы можете использовать объекты Compositional Layout для решения вашей проблемы.
В следующем полном примере кода показано, как отображать многострочность во
UILabel
всю ширинуUICollectionViewCell
:CollectionViewController.swift
HeaderView.swift
CustomCell.swift
Ожидаемый показ:
2. Решение для iOS 11+
В Swift 5.1 и iOS 11 вы можете
UICollectionViewFlowLayout
создать подкласс и установить для егоestimatedItemSize
свойства значениеUICollectionViewFlowLayout.automaticSize
(это сообщает системе, что вы хотите иметь дело с автоматическим изменением размеровUICollectionViewCell
). Затем вам придется переопределитьlayoutAttributesForElements(in:)
иlayoutAttributesForItem(at:)
установить ширину ячеек. Наконец, вам придется переопределитьpreferredLayoutAttributesFitting(_:)
метод своей ячейки и вычислить ее высоту.В следующем полном коде показано, как отобразить многострочность
UILabel
внутри на всю ширинуUIcollectionViewCell
(ограниченаUICollectionView
безопасной областью иUICollectionViewFlowLayout
вставками):CollectionViewController.swift
CustomFlowLayout.swift
HeaderView.swift
CustomCell.swift
Вот несколько альтернативных реализаций для
preferredLayoutAttributesFitting(_:)
:Ожидаемый показ:
источник
проблема
Вам нужна автоматическая высота, а также полная ширина, невозможно использовать оба варианта
UICollectionViewFlowLayoutAutomaticSize
.Вы хотите использовать,
UICollectionView
поэтому решение для вас ниже.Решение
1. Если у вас есть только
UILabel
вCollectionViewCell
чем установитьnumberOfLines=0
и вычислили ожидаемую высотуUIlable
, пройти все три paramters2. Если ваш
CollectionViewCell
содержит толькоUIImageView
и если он должен быть динамическим по высоте, вам нужно получить высотуUIImage
(у васUIImageView
должны бытьAspectRatio
ограничения)3. Если он содержит оба, вычислите их высоту и сложите их вместе.
1. Добавьте
UICollectionViewDelegateFlowLayout
делегата в свой viewController2. Реализуйте метод делегата.
Надеюсь, это вам поможет.
источник
return CGSize(width: view.frame.width/2, height: expectedHeight)
также сохраните в учетной записи Padding, чем верните ширину, иначе две ячейки не поместятся в одну строку.Есть несколько способов решить эту проблему.
Один из способов - дать макету потока представления коллекции примерный размер и вычислить размер ячейки.
Примечание. Как указано в комментариях ниже, начиная с iOS 10 вам больше не нужно указывать и предполагаемый размер для запуска вызова ячеек
func preferredLayoutAttributesFitting(_ layoutAttributes:)
. Раньше (iOS 9) требовалось предоставить приблизительный размер, если вы хотели запросить ячейки prefferedLayoutAttributes.(при условии, что вы используете раскадровки и представление коллекции подключено через IB)
Для простых ячеек этого обычно бывает достаточно. Если размер по-прежнему неверен, в ячейке представления коллекции вы можете переопределитьfunc preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes
, что даст вам более точный контроль над размером ячейки. Примечание. Вам все равно нужно будет указать примерный размер схемы потока .Затем переопределите,
func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes
чтобы вернуть правильный размер.В качестве альтернативы вместо этого вы можете использовать размерную ячейку для вычисления размера ячейки в
UICollectionViewDelegateFlowLayout
.Хотя это не идеальные готовые примеры, они должны помочь вам начать работу в правильном направлении. Я не могу сказать, что это лучшая практика, но у меня это работает даже с довольно сложными ячейками, содержащими несколько меток, которые могут или не могут переноситься на несколько строк.
источник
preferredLayoutAttributesFitting
. Затем я добавил собственное ограничение в указанную функцию, привязку к фиксированному измерению из EstimatedItemSize, FWIW, см. Мой ответ ниже.Я нашел довольно простое решение этой проблемы: внутри моего CollectionViewCell я получил UIView (), который на самом деле является просто фоном. Чтобы получить полную ширину, я просто установил следующие привязки
«Магия» происходит в первой строке. Я динамически устанавливаю widthAnchor на ширину экрана. Также важно вычесть вставки вашего CollectionView. В противном случае ячейка не появится. Если вы не хотите иметь такой вид фона, просто сделайте его невидимым.
FlowLayout использует следующие настройки
Результатом является ячейка полной ширины с динамической высотой.
источник
РАБОТАЕТ!!! Проверено на IOS: 12.1 Swift 4.1
У меня есть очень простое решение, которое работает без нарушения ограничений.
Мой ViewControllerClass
CustomCell класс:
Основной ингредиент является systemLayoutSizeFitting функция Customcell. А также мы должны установить ширину представления внутри Cell с ограничениями.
источник
Вам нужно добавить ограничение ширины в CollectionViewCell
источник
Набор
estimatedItemSize
макета вашего потока:Определите ограничение ширины в ячейке и установите его равным ширине супервизора:
Полный пример
Проверено на iOS 11.
источник
Лично я нашел лучший способ иметь UICollectionView, где AutoLayout определяет размер, в то время как каждая ячейка может иметь другой размер, - это реализовать функцию UICollectionViewDelegateFlowLayout sizeForItemAtIndexPath при использовании фактической ячейки для измерения размера.
Я говорил об этом в одном из своих сообщений в блоге
Надеюсь, это поможет вам достичь того, чего вы хотите. Я не уверен на 100%, но я считаю, что в отличие от UITableView, где вы действительно можете иметь полностью автоматическую высоту ячеек, используя AutoLayout в сочетании с
UICollectionView не имеет такого способа, позволяющего AutoLayout определять размер, потому что UICollectionViewCell не обязательно заполняет всю ширину экрана.
Но вот вопрос к вам : если вам нужны ячейки с полной шириной экрана, зачем вам вообще использовать UICollectionView вместо старого доброго UITableView, который поставляется с ячейками автоматического изменения размера?
источник
Согласно моему комментарию к ответу Эрика, мое решение очень похоже на его, но мне пришлось добавить ограничение в предпочтительныйSizeFor ..., чтобы ограничиться фиксированным размером.
В этом вопросе есть несколько дубликатов, я подробно ответил на него здесь и предоставил рабочий образец приложения здесь.
источник
Не уверен, что это можно назвать «действительно хорошим ответом», но я использую именно его для этого. Мой макет потока горизонтальный, и я пытаюсь настроить ширину с помощью автоматического макета, так что он похож на вашу ситуацию.
Затем в контроллере представления, где изменяется ограничение автоматического размещения, я запускаю NSNotification.
В моем подклассе UICollectionView я прослушиваю это уведомление:
и аннулируем макет:
Это вызывает
sizeForItemAt
повторный вызов с использованием нового размера представления коллекции. В вашем случае он должен иметь возможность обновляться с учетом новых ограничений, доступных в макете.источник
На вашем
viewDidLayoutSubviews
установитеestimatedItemSize
полную ширину (макет относится к объекту UICollectionViewFlowLayout):В ячейке убедитесь, что ваши ограничения касаются как верхней, так и нижней части ячейки (в следующем коде используется картография для упрощения установки ограничений, но вы можете сделать это с помощью NSLayoutConstraint или IB, если хотите):
Вуаля, клетки теперь автоматически увеличиваются в высоту!
источник
Ни одно из решений не помогло мне, так как мне нужна динамическая ширина, чтобы адаптироваться к ширине iPhone.
источник
Начиная с iOS 10, для этого у нас появился новый API-интерфейс потокового макета.
Все, что вам нужно сделать, это установить
flowLayout.estimatedItemSize
новую константуUICollectionViewFlowLayoutAutomaticSize
.Источник
источник
AutoLayout можно использовать для автоматического изменения размера ячеек в CollectionView за 2 простых шага:
flowLayout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
collectionView(:cellForItemAt:)
чтобы ограничить ширину contentView шириной collectionView.Вот и вы получите желаемый результат. Полный код см. В следующих статьях:
Ссылки / Кредиты:
Скриншот:
источник
Вы должны унаследовать класс UICollectionViewDelegateFlowLayout в своей коллекцииViewController. Затем добавьте функцию:
Используя это, вы получаете размер ширины экрана.
И теперь у вас есть collectionViewController со строками в виде tableViewController.
Если вы хотите, чтобы высота каждой ячейки была динамической, возможно, вам следует создать собственные ячейки для каждой нужной ячейки.
источник