Here is my tags (tabs) and when I click to tag, collectionview is not refresh it. You can see on photo. How I can refresh - reload it. Also heightForItemAt method is not called 2nd time
Also when reload to collectionview , long scrollview and scroll indicator is on same position. I use custom UICollectionViewFlowLayout (PinterestLayout).
PinterestLayout code:
/**
* Copyright (c) 2019 Razeware LLC
*
*/
import UIKit
protocol PinterestLayoutDelegate: AnyObject {
func collectionView(_ collectionView: UICollectionView, heightForItemAt indexPath: IndexPath, with width: CGFloat) -> CGFloat
}
class PinterestLayout: UICollectionViewFlowLayout {
// 1
weak var delegate: PinterestLayoutDelegate?
// 2
private let numberOfColumns = 2
private let cellPadding: CGFloat = 6
// 3
public var cache: [UICollectionViewLayoutAttributes] = []
// 4
private var contentHeight: CGFloat = 0
private var contentWidth: CGFloat {
guard let collectionView = collectionView else {
return 0
}
let insets = collectionView.contentInset
return collectionView.bounds.width - (insets.left + insets.right)
}
// 5
override var collectionViewContentSize: CGSize {
return CGSize(width: contentWidth, height: contentHeight)
}
override func prepare() {
// 1
/*guard
cache.isEmpty == true,
let collectionView = collectionView
else {
return
}*/
// cache.removeAll()
guard let collectionView = collectionView else {return} // NEW BIT
// 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 item in 0..<collectionView.numberOfItems(inSection: 0) {
let indexPath = IndexPath(item: item, section: 0)
// 4
let width = columnWidth - cellPadding * 2
let photoHeight = delegate?.collectionView(collectionView, heightForItemAt: indexPath, with: width) ?? 0
let height = cellPadding * 2 + photoHeight
let frame = CGRect(x: xOffset[column],
y: yOffset[column],
width: columnWidth,
height: height)
let insetFrame = frame.insetBy(dx: cellPadding, dy: cellPadding)
// 5
let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath)
attributes.frame = insetFrame
cache.append(attributes)
// 6
contentHeight = max(contentHeight, frame.maxY)
yOffset[column] = yOffset[column] + height
column = column < (numberOfColumns - 1) ? (column + 1) : 0
}
}
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
var visibleLayoutAttributes: [UICollectionViewLayoutAttributes] = []
// Loop through the cache and look for items in the rect
for attributes in cache {
if attributes.frame.intersects(rect) {
visibleLayoutAttributes.append(attributes)
}
}
return visibleLayoutAttributes
}
override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
return cache[indexPath.item]
}
}
taps click code:
func tagsCollectionView(_ tagsCollectionView: TagsCollectionView, didSelect model: TagModel) {
guard let selectedCat = tagsView.selectedTag?.name else { return }
guard let selectedSubCat = subtagsView.selectedTag?.name else { return }
self.selectedCategory = selectedCat
self.selectedSubcategory = selectedSubCat
if selectedCategory == TagTypes.CLASSICS.stringValue() && selectedSubcategory == TagTypes.IMAGES.stringValue() {
self.collectionViewArray = self.classicImageArray
}else if selectedCategory == TagTypes.CLASSICS.stringValue() && selectedSubcategory == TagTypes.VIDEOS.stringValue() {
self.collectionViewArray = self.classicVideoArray
}else if selectedCategory == TagTypes.AESTHETICS.stringValue() {
self.collectionViewArray = self.aestheticArray
}
collectionView.reloadData()
}
}
viewcontroller and viewdidload code :
class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout, PinterestLayoutDelegate {
var customLayout: PinterestLayout? {
let layout = collectionView?.collectionViewLayout as? PinterestLayout
layout?.delegate = self
return layout
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
if #available(iOS 10.0, *) {
collectionView!.isPrefetchingEnabled = false
}
collectionView.collectionViewLayout = customLayout!
collectionView.contentInset = UIEdgeInsets(top: 0, left: leftRightMargin, bottom: 0, right: leftRightMargin)
}
func collectionView(_ collectionView: UICollectionView, heightForItemAt indexPath: IndexPath, with width: CGFloat) -> CGFloat {
if selectedCategory == TagTypes.CLASSICS.stringValue()
{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "TemplateCell", for: indexPath)
guard let cell2 = cell as? TemplateCell else {
return CGFloat()
}
let myImageView = MemesManager.shared.imageArray[indexPath.row]
let imageHeight:CGFloat = resizeImageHeightForCollectionViewWidth(collectionView: collectionView, imageView: myImageView)
return imageHeight
}
return 190;
}
func resizeImageHeightForCollectionViewWidth(collectionView:UICollectionView ,imageView:UIImageView? ) -> CGFloat {
let collectionViewWidth = collectionView.frame.size.width
let spacingBetweenCells: CGFloat = 0
let totalSpacing = spacingBetweenCells * 2 // Hücreler arasındaki toplam boşluk
let cellWidth = (collectionViewWidth - totalSpacing) / 2 // 3 sütun olduğu için genişliği üçe bölelim
guard let myImage = imageView!.image else {
return CGFloat(0)
}
// calculate image height for collectionview
let imageWidth = imageView!.image!.size.width
let imageHeight = imageView!.image!.size.height
let aspectRatio = imageWidth / imageHeight
let cellHeight = cellWidth / aspectRatio
return cellHeight
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
//filteredPresets.count + 1
//return MemesManager.shared.imageMemeArray.count
return self.collectionViewArray.count
}
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
if (selectedCategory == TagTypes.CLASSICS.stringValue() && selectedSubcategory == TagTypes.VIDEOS.stringValue()){
if let videoCell = cell as? TemplateCell {
// Call a method on the cell to load the video data
videoCell.loadVideo()
}
}
}
func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
if (selectedCategory == TagTypes.CLASSICS.stringValue() && selectedSubcategory == TagTypes.VIDEOS.stringValue()){
if let videoCell = cell as? TemplateCell {
// Call a method on the cell to load the video data
videoCell.unloadVideo()
}
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "TemplateCell", for: indexPath)
if let cell = cell as? TemplateCell
{
cell.imageView? = self.collectionViewArray[indexPath.row]
}
return cell
}
}




