Более быстрый способ оценки высоты ячейки в CollectionView - PullRequest
0 голосов
/ 25 мая 2018

У меня есть бесконечная прокрутка в моем UICollectionView, и я заметил, что способ, которым я оцениваю высоту моей ячейки, является узким местом моего представления коллекции.Это приводит к длительным задержкам, чем больше я прокручиваю свой вид коллекции.

Есть ли лучший способ оценить высоту моих ячеек?

Ячейки имеют разную высоту, потому чтоУ меня есть UILabel в каждом из них.Я назначаю NSMutableAttributedStrings разной длины этим UILabels:

let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .justified
paragraphStyle.lineSpacing = 5.0

let attributedText = NSMutableAttributedString(string: "   \(post.caption)", attributes: [NSAttributedStringKey.font: UIFont.systemFont(ofSize: 15), .paragraphStyle: paragraphStyle, .baselineOffset: NSNumber(value: 0)])

attributedText.append(NSAttributedString(string: "\n\n", attributes: [NSAttributedStringKey.font: UIFont.systemFont(ofSize: 4)]))

let timeAgoDisplay = post.creationDate.timeAgoDisplay()
attributedText.append(NSAttributedString(string: timeAgoDisplay, attributes: [NSAttributedStringKey.font: UIFont.systemFont(ofSize: 14), NSAttributedStringKey.foregroundColor: UIColor.storiesLightGray()]))

captionLabel.attributedText = attributedText

My sizeForItemAt метод.Я заметил, что вызов dummyCell.layoutIfNeeded() делает мое приложение очень медленным, когда у меня в представлении коллекции более 200 элементов:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

        var height: CGFloat = 180

        let frame = CGRect(x: 0, y: 0, width: view.frame.width, height: height)
        let dummyCell = HomePostCell(frame: frame)

        dummyCell.post = presenter.posts[indexPath.item]
        dummyCell.layoutIfNeeded()

        let targetSize = CGSize(width: view.frame.width, height: 5000)
        let estimatedSize = dummyCell.systemLayoutSizeFitting(targetSize)

        let newHeight = max(height, estimatedSize.height)

        return CGSize(width: view.frame.width, height: newHeight)
 }

Спасибо!

1 Ответ

0 голосов
/ 25 мая 2018

В идеале вам не следует использовать systemLayoutSizeFitting в вашем sizeForItemAt, потому что, как вы говорите, он медленный.

Вы можете предварительно кэшировать некоторые данные ячейки, вычислять размеры и сохранять их в массивеили что-то подобное, так что sizeForItemAt просто должен выполнить поиск в массиве - что быстро.

И вам также не нужно использовать systemLayoutSizeFitting;вы можете использовать свои знания о размере и содержании метки для расчета размера (например, используя методы измерения NSAttributedString).

Это то, что мы делали до systemLayoutSizeFitting или автоматического макета, и он остается намного быстрее.

...