
import UIKitclass LuckGameCollectionVIEwLayout: UICollectionVIEwFlowLayout { // Used for calculating each cells CGRect on screen. // CGRect will define the Origin and Size of the cell. let CELL_HEIGHT = 70.0 let CELL_WIDTH = 70.0 // Dictionary to hold the UICollectionVIEwLayoutAttributes for // each cell. The layout attribtues will define the cell's size // and position (x,y,and z index). I have found this process // to be one of the heavIEr parts of the layout. I recommend // holding onto this data after it has been calculated in either // a dictionary or data store of some kind for a smooth performance. var cellAttrsDictionary = Dictionary<NSIndexPath,UICollectionVIEwLayoutAttributes>() // defines the size of the area the user can move around in // within the collection vIEw. var contentSize = CGSize.zero overrIDe func collectionVIEwContentSize() -> CGSize { return self.contentSize } overrIDe func prepareLayout() { // Cycle through each section of the data source. if collectionVIEw?.numberOfSections() > 0 { for section in 0...collectionVIEw!.numberOfSections()-1 { // Cycle through each item in the section. if collectionVIEw?.numberOfItemsInSection(section) > 0 { for item in 0...collectionVIEw!.numberOfItemsInSection(section)-1 { // Build the UICollectionVIELayoutAttributes for the cell. let cellindex = NSIndexPath(forItem: item,inSection: section) let xPos = Double(item) * CELL_WIDTH let yPos = Double(section) * CELL_HEIGHT let cellAttributes = UICollectionVIEwLayoutAttributes(forCellWithIndexPath: cellindex) cellAttributes.frame = CGRect(x: xPos,y: yPos,wIDth: CELL_WIDTH,height: CELL_HEIGHT) // Save the attributes. cellAttrsDictionary[cellindex] = cellAttributes } } } } // Update content size. let contentWIDth = Double(collectionVIEw!.numberOfItemsInSection(0)) * CELL_WIDTH let contentHeight = Double(collectionVIEw!.numberOfSections()) * CELL_HEIGHT self.contentSize = CGSize(wIDth: contentWIDth,height: contentHeight) } overrIDe func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionVIEwLayoutAttributes]? { // Create an array to hold all elements found in our current vIEw. var attributesInRect = [UICollectionVIEwLayoutAttributes]() // Check each element to see if it should be returned. for (_,cellAttributes) in cellAttrsDictionary { if CGRectIntersectsRect(rect,cellAttributes.frame) { attributesInRect.append(cellAttributes) } } // Return List of elements. return attributesInRect } overrIDe func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionVIEwLayoutAttributes? { return cellAttrsDictionary[indexPath]! } overrIDe func shouldInvalIDateLayoutForBoundsChange(newBounds: CGRect) -> Bool { return false }} 编辑:
以下是我在layoutAttributesForElementsInRect方法中提出的更改.
overrIDe func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionVIEwLayoutAttributes]? { // Create an array to hold all elements found in our current vIEw. var attributesInRect = [UICollectionVIEwLayoutAttributes]() let xOffSet = self.collectionVIEw?.contentOffset.x let yOffSet = self.collectionVIEw?.contentOffset.y let totalColumnCount = self.collectionVIEw?.numberOfSections() let totalRowCount = self.collectionVIEw?.numberOfItemsInSection(0) let startRow = Int(Double(xOffSet!)/CELL_WIDTH) - 10 //include 10 rows towards left let endRow = Int(Double(xOffSet!)/CELL_WIDTH + Double(Utils.getScreenWIDth())/CELL_WIDTH) + 10 //include 10 rows towards right let startCol = Int(Double(yOffSet!)/CELL_HEIGHT) - 10 //include 10 rows towards top let endCol = Int(Double(yOffSet!)/CELL_HEIGHT + Double(Utils.getScreenHeight())/CELL_HEIGHT) + 10 //include 10 rows towards bottom for(var i = startRow ; i <= endRow; i = i + 1){ for (var j = startCol ; j <= endCol; j = j + 1){ if (i < 0 || i > (totalRowCount! - 1) || j < 0 || j > (totalColumnCount! - 1)){ continue } let indexPath: NSIndexPath = NSIndexPath(forRow: i,inSection: j) attributesInRect.append(cellAttrsDictionary[indexPath]!) } } // Return List of elements. return attributesInRect} 我已经计算了collectionVIEw的偏移量,并用它来计算屏幕上可见的单元格(使用每个单元格的高度/宽度).我不得不在每一侧添加额外的单元格,以便当用户滚动时没有丢失的单元格.我测试了这个并且性能很好.
解决方法 通过利用已知单元格大小的layoutAttributesForElementsInRect(rect:CGRect),您不需要缓存属性,只需在collectionVIEw请求它们时为给定的rect计算它们.您仍然需要检查0的边界情况和最大的部分/行计数,以避免计算不需要的或无效的属性,但可以在循环周围的where子句中轻松完成.这是一个工作示例,我已经测试了1000个部分x 1000行,它工作得很好,没有滞后于设备:编辑:我添加了更大的Result,以便在滚动到达之前可以预先计算属性.从您的编辑看起来,您仍然在缓存我认为性能不需要的属性.此外,它会带来更大的内存占用,滚动更多.还有一个原因是你不想从回调中使用提供的CGRect而不是从contentOffset手动计算一个?
class LuckGameCollectionVIEwLayout: UICollectionVIEwFlowLayout {let CELL_HEIGHT = 50.0let CELL_WIDTH = 50.0overrIDe func collectionVIEwContentSize() -> CGSize { let contentWIDth = Double(collectionVIEw!.numberOfItemsInSection(0)) * CELL_WIDTH let contentHeight = Double(collectionVIEw!.numberOfSections()) * CELL_HEIGHT return CGSize(wIDth: contentWIDth,height: contentHeight)}overrIDe func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionVIEwLayoutAttributes]? { let biggerRect = rect.insetBy(dx: -2048,dy: -2048) let startIndexY = Int(Double(biggerRect.origin.y) / CELL_HEIGHT) let startIndexX = Int(Double(biggerRect.origin.x) / CELL_WIDTH) let numberOfVisibleCellsInRectY = Int(Double(biggerRect.height) / CELL_HEIGHT) + startIndexY let numberOfVisibleCellsInRectX = Int(Double(biggerRect.wIDth) / CELL_WIDTH) + startIndexX var attributes: [UICollectionVIEwLayoutAttributes] = [] for section in startIndexY..<numberOfVisibleCellsInRectY where section >= 0 && section < self.collectionVIEw!.numberOfSections() { for item in startIndexX..<numberOfVisibleCellsInRectX where item >= 0 && item < self.collectionVIEw!.numberOfItemsInSection(section) { let cellindex = NSIndexPath(forItem: item,inSection: section) if let attrs = self.layoutAttributesForItemAtIndexPath(cellindex) { attributes.append(attrs) } } } return attributes}overrIDe func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionVIEwLayoutAttributes? { let xPos = Double(indexPath.row) * CELL_WIDTH let yPos = Double(indexPath.section) * CELL_HEIGHT let cellAttributes = UICollectionVIEwLayoutAttributes(forCellWithIndexPath: indexPath) cellAttributes.frame = CGRect(x: xPos,height: CELL_HEIGHT) return cellAttributes}} 总结 以上是内存溢出为你收集整理的ios – 滚动双向滚动UICollectionView并具有大量单元格(250,000或更多)时可见延迟全部内容,希望文章能够帮你解决ios – 滚动双向滚动UICollectionView并具有大量单元格(250,000或更多)时可见延迟所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)