Как настроить высоту UICollectionView как высоту размера содержимого UICollectionView?

Я хотел бы, чтобы UICollectionView (красный) сократился до высоты размера контента, в этом случае UICollectionViewCells (желтые), потому что там много пустого пространства. Я пытался использовать:

override func layoutSubviews() {
    super.layoutSubviews()
    if !__CGSizeEqualToSize(bounds.size, self.intrinsicContentSize) {
        self.invalidateIntrinsicContentSize()
    }
}

override var intrinsicContentSize: CGSize {
    return self.collection.contentSize
}

но return self.collection.contentSize всегда возвращает (ширина, 0) и по этой причине он слишком сильно сжимается до значения высоты 30 (значение, которое я установил в файле XIB для высоты, хотя у меня есть constaint> = 30).

enter image description here

Ответ 1

Я бы предложил следующее:

  1. Добавьте ограничение высоты в представление вашей коллекции.
  2. Установите его приоритет на 999.
  3. Установите его константу в любое значение, которое делает его разумно видимым на раскадровке.
  4. Измените нижнее равное ограничение представления коллекции на большее или равное.
  5. Подключите ограничение высоты к розетке.
  6. Каждый раз, когда вы перезагрузите данные в представлении сбора, сделайте следующее:

Пример кода:

CGFloat height = myCollectionView.collectionViewLayout.collectionViewContentSize.height
heightConstraint.constant = height
self.view.setNeedsLayout() Or self.view.layoutIfNeeded()

Пояснение: Дополнительно, Вам не нужно читать, если вы это понимаете. очевидно !!

Пользовательский интерфейс попытается отразить все ограничения независимо от их приоритетов. Поскольку ограничение по высоте имеет более низкий приоритет (999), а ограничение снизу типа больше или равно. всякий раз, когда константе ограничения высоты устанавливается значение меньше высоты родительского представления, представление коллекции будет равно заданной высоте, достигая обоих ограничений.

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

Следующее - только предположение из опыта. Таким образом, он достигает одного постоянного. Но он также пытается сделать ошибку в полученном пользовательском интерфейсе для другого недостижимого ограничения с более низким приоритетом как можно более низким. Следовательно, высота представления коллекции будет равна размеру родительского представления.

Ответ 2

В итоге я создал подкласс UICollectionView и переопределил некоторые методы следующим образом.

  • Возвращение self.collectionViewLayout.collectionViewContentSize для intrinsicContentSize гарантирует, что всегда будет правильный размер
  • Затем просто вызывайте его всякий раз, когда он может измениться (как на reloadData)

Код:

override func reloadData() {
    super.reloadData()
    self.invalidateIntrinsicContentSize()
}

override var intrinsicContentSize: CGSize {
    return self.collectionViewLayout.collectionViewContentSize
}

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

Ответ 3

1) Установите Fix Fix вашего CollectionView.

2) Создайте выход этой константы высоты CollectionView. Подобно:

IBOutlet NSLayoutConstraint * constHeight;

3) Добавьте ниже метод в вашем файле .m:

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];

    CGFloat height = collectionMenu.collectionViewLayout.collectionViewContentSize.height;
    constHeight.constant = height;
}

Ответ 4

Вы должны установить ограничение по высоте равным размеру содержимого

HeightConstraint.constant = collection.contentSize.height 

Ответ 5

Сделайте следующее.

  1. первый набор ограничений высоты для UICollectionView
  2. здесь calendarBaseViewHeight - это UICollectionView height Переменная
  3. вызвать функцию после перезагрузки коллекции

    func resizeCollectionViewSize(){  
           calendarBaseViewHeight.constant = collectionView.contentSize.height      
     }
    

Ответ 6

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

    collectionView.frame = CGRectMake (x,y,w,collectionView.collectionViewLayout.collectionViewContentSize.height); //objective c
    //[collectionView reloadData];
   collectionView.frame = CGRect(x: 0, y: 0, width: width, height: collectionView.collectionViewLayout.collectionViewContentSize.height) // swift

Ответ 7

В Swift 5 и Xcode 10.2.1

1) Исправить высоту CollectionView

2) Создать аутлет вашего CollectionView

IBOutlet weak var myCollectionViewHeight: NSLayoutConstraint!

3) Используйте код ниже

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    let height = myCollectionView.collectionViewLayout.collectionViewContentSize.height
    myCollectionViewHeight.constant = height
    self.view.layoutIfNeeded()
}

Ответ 8

Принял решение с помощью d4Rk, что замечательно, за исключением того, что в моем случае это продолжало бы обрезать нижнюю часть моего представления коллекции (слишком короткое). Я понял, что это потому, что внутренний размер контента иногда равен 0, и это может привести к потере вычислений. ИДК. Все, что я знаю, это исправить это.

import UIKit

class SelfSizedCollectionView: UICollectionView {
    override func reloadData() {
        super.reloadData()
        self.invalidateIntrinsicContentSize()
    }

    override var intrinsicContentSize: CGSize {
        let s = self.collectionViewLayout.collectionViewContentSize
        return CGSize(width: max(s.width, 1), height: max(s.height,1))
    }

}

Ответ 9

На вашем UICollectionView установите ваши ограничения, такие как Trailing, Leading и Bottom:

UICollectionView constraints

Если вы посмотрите на мое ограничение по высоте более подробно, так как оно чисто для раскадровки, поэтому я не получаю ошибок, я могу Remove at build time. Ограничение реальной высоты установлено в моем коде ниже.

UICollectionView height constraint

Мой код для DrawerCollectionView, который устанавливается как представление коллекции Custom Class:

UICollectionView custom class

import UIKit

class DrawerCollectionView: UICollectionView {

    override func didMoveToSuperview() {
        super.didMoveToSuperview()

        heightAnchor.constraint(equalToConstant: contentSize.height).isActive = true
    }
}

Ответ 10

работать на меня

    let heightRes = resCollectionView.collectionViewLayout.collectionViewContentSize.height
    foodHeightConstrant.constant = height.advanced(by: 1 )

    foodCollectionView.setNeedsLayout()
    foodCollectionView.layoutIfNeeded()

Ответ 11

Получите высоту клетки. Примерно так

let cellHeight = cell.frame.height

Получить происхождение представления коллекции

let cvOrigin = collectionView.frame.origin

Получите ширину представления коллекции

let cvWidth = collectionView.bounds.width

Установите рамку представления содержимого

collection.frame = CGRect(x: cvOrigin.x, y: cvOrigin.y, width: cvWidth, height: cellHeight )