gpt4 book ai didi

ios - 删除单元格后使用自定义布局调整 UICollectionView 的大小

转载 作者:可可西里 更新时间:2023-11-01 00:56:13 25 4
gpt4 key购买 nike

我为我的 CollectionView 下载了这个 Pintrest-esc 自定义布局:https://www.raywenderlich.com/164608/uicollectionview-custom-layout-tutorial-pinterest-2 (稍微修改了一下缓存代码)

所以布局工作正常,我设置好了,所以当你滚动到底部时,我进行另一个 API 调用,创建并填充额外的单元格。

问题:如果用户向下滚动并加载更多单元格(比如说 20 个单元格),然后使用“搜索功能” 我已经在顶部实现,然后它将通过 MinRange - MaxRange 的价格过滤一些数据,给您留下(假设 5 个结果),从而删除一些单元格并重新填充这些单元格。 但是 - 前 20 个单元格中存在的所有空间和可滚动空间仍然作为空白空间存在......我如何删除这个空间? 为什么可以添加更多单元格时调整大小,但删除它们时不调整大小?

我的 API 调用代码:

DispatchQueue.global(qos: .background).async {

WebserviceController.GetSearchPage(parameters: params) { (success, data) in
if success
{

if let products = data!["MESSAGE"] as? [[String : AnyObject]]
{
self.productList = products

}
}

DispatchQueue.main.async(execute: { () -> Void in
self.pintrestCollectionView.reloadData()
self.pintrestCollectionView.collectionViewLayout.invalidateLayout()
self.pintrestCollectionView.layoutSubviews()
})

}

}

自定义布局类和协议(protocol)代码:

协议(protocol) PinterestLayoutDelegate: 类 {

func collectionView(_ collectionView:UICollectionView, heightForPhotoAtIndexPath indexPath:IndexPath) -> CGFloat

PintrestLayout 类:UICollectionViewFlowLayout {

// 1

weak var delegate : PinterestLayoutDelegate!

// 2
fileprivate var numberOfColumns = 2
fileprivate var cellPadding: CGFloat = 10

// 3
fileprivate var cache = [UICollectionViewLayoutAttributes]()

// 4
fileprivate var contentHeight: CGFloat = 0

fileprivate 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
//You only calculate the layout attributes if cache is empty and the collection view exists.
/*guard cache.isEmpty == true, let collectionView = collectionView else {
return
}*/
cache.removeAll()
guard cache.isEmpty == true || cache.isEmpty == false, let collectionView = collectionView else {
return
}
// 2
//This declares and fills the xOffset array with the x-coordinate for every column based on the column widths. The yOffset array tracks the y-position for every column.
let columnWidth = contentWidth / CGFloat(numberOfColumns)
var xOffset = [CGFloat]()
for column in 0 ..< numberOfColumns {
xOffset.append(CGFloat(column) * columnWidth)
}
var column = 0
var yOffset = [CGFloat](repeating: 0, count: numberOfColumns)

// 3
//This loops through all the items in the first section, as this particular layout has only one section.
for item in 0 ..< collectionView.numberOfItems(inSection: 0) {

if collectionView.numberOfItems(inSection: 0) < 3
{
collectionView.isScrollEnabled = false
} else {
collectionView.isScrollEnabled = true
}

let indexPath = IndexPath(item: item, section: 0)

// 4
//This is where you perform the frame calculation. width is the previously calculated cellWidth, with the padding between cells removed.

let photoHeight = delegate.collectionView(collectionView, heightForPhotoAtIndexPath: indexPath)
let height = cellPadding * 2 + photoHeight
let frame = CGRect(x: xOffset[column], y: yOffset[column], width: columnWidth, height: height)
let insetFrame = frame.insetBy(dx: 7, dy: 4)

collectionView.contentInset = UIEdgeInsets.init(top: 15, left: 12, bottom: 0, right: 12)

// 5
//This creates an instance of UICollectionViewLayoutAttribute, sets its frame using insetFrame and appends the attributes to cache.
let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath)
attributes.frame = insetFrame
cache.append(attributes)

// 6
//This expands contentHeight to account for the frame of the newly calculated item.
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
}

仅供引用:在 MainStoryboard 中,我禁用了“Adjust Scroll View Insets”,因为许多其他主题和论坛都建议...

最佳答案

我猜您已经找到了答案,但自从我遇到这个问题后,我就在这里发布给下一个人。

这里的技巧是 contentHeight 实际上永远不会变小。

contentHeight = max(contentHeight, frame.maxY)

这是一个非递减函数。

要修复它,只需在调用 prepare 时将 contentHeight 设置为 0:

guard cache.isEmpty == true || cache.isEmpty == false, let 
collectionView = collectionView else {
return
}
contentHeight = 0

关于ios - 删除单元格后使用自定义布局调整 UICollectionView 的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47821600/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com