1 year ago
#73265

bao le
Custom UICollectionViewLayout, change cell height after image is downloaded inside a cell?
I'm using pinterest tutorial to achieve dynamic cell height according to image's size.
But there is a problem: After it downloaded the data, I send the URL
to according cell
. When the cell receives the link, it will download and change the picture. But from the tutorial, it calculate the image size way before its downloaded because it uses temp images that are already stored.
Inside cell Class:
var imageURL: String? {
didSet {
imageView.loadImage(self.imageURL ?? "")
}
}
Func to return image size height, this is in the ViewController
class
func collectionView(
_ collectionView: UICollectionView, heightForPhotoAtIndexPath indexPath: IndexPath) -> CGFloat {
return imgArr[indexPath.item].size.height + 100
// it should be like this
// guard let cell = self.collectionView.cellForItem(at: indexPath) as? LoansCell else {return}
// return cell.photo.size.height
}
Inside the UICollectionViewLayout class:
override func prepare() {
// 1
var section = 1
if isPartner {
section = 0
}
let collectionViewItemCount = collectionView?.numberOfItems(inSection: section) ?? 0
guard cache.isEmpty || collectionViewItemCount > cache.count, let collectionView = collectionView else { return }
// 2
let columnWidth = contentWidth / CGFloat(numberOfColumns)
var xOffset: [CGFloat] = []
for column in 0..<numberOfColumns {
xOffset.append(CGFloat(column) * columnWidth)
}
var column = 0
var yOffset: [CGFloat] = .init(repeating: 0, count: numberOfColumns)
// 3
for section in 0..<collectionView.numberOfSections {
for item in 0..<collectionView.numberOfItems(inSection: section) {
let indexPath = IndexPath(item: item, section: section)
let attributes: UICollectionViewLayoutAttributes
// where it calls the protocol to get image h
let photoHeight = delegate?.collectionView(
collectionView,
heightForPhotoAtIndexPath: indexPath) ?? 180
let height = cellPadding * 2 + photoHeight
let frame: CGRect
var paddingForSection0: CGFloat = cellPadding // to make the horizontalView leading and trailling = screen.leading/trailing
if section == 0 && !isPartner {
frame = CGRect(x: 0,
y: yOffset[column] + headerHeight + cellPadding,
width: contentWidth + insetLeftRight*2,
height: height)
contentHeight = frame.maxY
for column in 0..<numberOfColumns {
yOffset[column] = frame.maxY
}
paddingForSection0 = 0
column = 0
} else {
// 4
var yPad = cellPadding * 2
if isPartner { // this is a temp approach
headerHeight = 0
yPad = cellPadding
}
frame = CGRect(x: xOffset[column] + insetLeftRight,
y: yOffset[column] + headerHeight + yPad,
width: columnWidth,
height: height)
contentHeight = max(contentHeight, frame.maxY)
yOffset[column] = yOffset[column] + height
column = column < (numberOfColumns - 1) ? (column + 1) : 0
}
let insetFrame = frame.insetBy(dx: paddingForSection0, dy: cellPadding)
attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath)
attributes.frame = insetFrame
cache.append(attributes)
}
}
}
The article I used: https://www.raywenderlich.com/4829472-uicollectionview-custom-layout-tutorial-pinterest
ios
swift
uicollectionview
uicollectionviewlayout
0 Answers
Your Answer