Настройка динамической высоты ячейки с помощью пользовательского макета представления коллекции swift - PullRequest
0 голосов
/ 10 сентября 2018

У меня есть пользовательский макет представления коллекции, который загружает ячейки снизу вверх для приложения обмена сообщениями, за исключением того, что у меня возникают проблемы с реализацией динамической высоты ячеек. Я полагаю, что протокол и делегаты, которые я подключил для получения динамической высоты ячейки, работают для каждой ячейки (которую я вывел из печати высоты для каждой indexPath.item), за исключением того, что при загрузке collectionView высоты ячеек не соответствуют предполагаемой высоте быть. Все они имеют одну статическую высоту (а не 80, заданную var cellHeight) и показывают только одну строку текста.

 protocol InvertedStackProtocol: class {
    func collectionView(_ collectionView: UICollectionView, heightForCellAtIndexPath indexPath: IndexPath) -> CGFloat
    }

    class InvertedStackLayout: UICollectionViewLayout, UICollectionViewDelegateFlowLayout {

    var cellHeight: CGFloat = 80

    weak var delegate: InvertedStackProtocol!

    override func prepare() {

        guard let collectionView = self.collectionView else {return}

        for item in 0 ..< collectionView.numberOfItems(inSection: 0) {
            let indexPath = IndexPath(item: item, section: 0)
            let height = delegate.collectionView(collectionView, heightForCellAtIndexPath: indexPath)
            print (height, indexPath.item)
            cellHeight = height
        }

    }

    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        var layoutAttrs = [UICollectionViewLayoutAttributes]()

        if let collectionView = self.collectionView {
            for section in 0 ..< collectionView.numberOfSections {
                if let numberOfSectionItems = numberOfItemsInSection(section) {
                    for item in 0 ..< numberOfSectionItems {
                        let indexPath = IndexPath(item: item, section: section)
                        let layoutAttr = layoutAttributesForItem(at: indexPath)

                        if let layoutAttr = layoutAttr, layoutAttr.frame.intersects(rect) {
                            layoutAttrs.append(layoutAttr)
                        }
                    }
                }
            }
        }

        return layoutAttrs
    }

    override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
        let layoutAttr = UICollectionViewLayoutAttributes(forCellWith: indexPath)
        let contentSize = self.collectionViewContentSize

        layoutAttr.frame = CGRect(
            x: 0, y: contentSize.height - CGFloat(indexPath.item + 1) * cellHeight,
            width: contentSize.width, height: cellHeight)

        return layoutAttr
    }

    func numberOfItemsInSection(_ section: Int) -> Int? {
        if let collectionView = self.collectionView,
            let numSectionItems = collectionView.dataSource?.collectionView(collectionView, numberOfItemsInSection: section)
        {
            return numSectionItems
        }

        return 0
    }

    override var collectionViewContentSize: CGSize {
        get {
            var height: CGFloat = 0.0
            var bounds = CGRect.zero

            if let collectionView = self.collectionView {
                for section in 0 ..< collectionView.numberOfSections {
                    if let numItems = numberOfItemsInSection(section) {
                        height += CGFloat(numItems) * cellHeight
                    }
                }

                bounds = collectionView.bounds
            }

            return CGSize(width: bounds.width, height: max(height, bounds.height))
            // return CGSize(width: bounds.width, height: height) do this for more exact fit of collection view
        }
    }

    override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
        if let oldBounds = self.collectionView?.bounds,
            oldBounds.width != newBounds.width || oldBounds.height != newBounds.height
        {
            return true
        }

        return false
    }
}

1 Ответ

0 голосов
/ 10 сентября 2018

Используйте этот метод для изменения высоты, UICollectionViewCell.

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: 125.0, height: 175.0)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...