我'使用Alamofire构建类似pinterest的布局。
我跟着uicollectionview-custom-layout-tutorial-pinterest来建立类似pinterest的布局。当我想用异步下载的照片来实现它时,它会失败。
断言失败 - [UICollectionViewData layoutAttributesForItemAtIndexPath:]
Alamofire.request(Unicooo.Router.ReadPostList("",["act_id": self.actId, "page": self.currentPage])).validate().responseJSON {
response in
switch response.result {
case .Success:
let JSON = response.result.value
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) {
let photoInfos = ((JSON as! NSDictionary).valueForKey("results") as! [NSDictionary]).map {
PostPhotoInfo(id: ($0["id"] as! Int), title: ($0["post_title"] as! String)...)
}
let lastItem = self.postPhotos.count
self.postPhotos.addObjectsFromArray(photoInfos)
let indexPaths = (lastItem..<self.postPhotos.count).map { NSIndexPath(forItem: $0, inSection: 0)}
dispatch_async(dispatch_get_main_queue()) {
self.collectionView!.insertItemsAtIndexPaths(indexPaths) // Thread 1: breakpoint 1.1.
}
}
当我将Main.storyboard集合视图布局设置为Flow时,这很有效,但是当我使用这样的自定义流时:
private var cache = Dictionary<NSIndexPath, UICollectionViewLayoutAttributes>() //I change cache to Dictionary
override func prepareLayout() {
if cache.isEmpty {
let columnWidth = contentWidth / CGFloat(numberOfColumns)
var xOffset = [CGFloat]()
for column in 0 ..< numberOfColumns {
xOffset.append(CGFloat(column) * columnWidth )
}
var column = 0
var yOffset = [CGFloat](count: numberOfColumns, repeatedValue: 0)
for item in 0 ..< collectionView!.numberOfItemsInSection(0) {
let indexPath = NSIndexPath(forItem: item, inSection: 0)
let width = columnWidth - cellPadding * 2
let photoHeight = delegate.collectionView(collectionView!, heightForPhotoAtIndexPath: indexPath,
withWidth:width)
let annotationHeight = delegate.collectionView(collectionView!,
heightForAnnotationAtIndexPath: indexPath, withWidth: width)
let height = cellPadding + photoHeight + annotationHeight + cellPadding
let frame = CGRect(x: xOffset[column], y: yOffset[column], width: columnWidth, height: height)
insetFrame = CGRectInset(frame, cellPadding, cellPadding)
let attributes = UICollectionViewLayoutAttributes(forCellWithIndexPath: indexPath)
attributes.frame = insetFrame!
cache[indexPath] = attributes //I change this line
contentHeight = max(contentHeight, CGRectGetMaxY(frame))
yOffset[column] = yOffset[column] + height
column = column >= (numberOfColumns - 1) ? 0 : ++column
}
}
}
override func collectionViewContentSize() -> CGSize {
return CGSize(width: contentWidth, height: contentHeight)
}
override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
var layoutAttributes = [UICollectionViewLayoutAttributes]()
for (_, attributes) in cache {
if CGRectIntersectsRect(attributes.frame, rect) {
layoutAttributes.append(attributes)
}
}
return layoutAttributes
}
当我在google中搜索关于集合视图的所有内容时:我尝试添加此方法:
override func layoutAttributesForItemAtIndexPath(_ indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? {
let attributes = cache[indexPath]
return attributes
}
但仍然无法工作。我认为这可能与layoutAttributesForItemAtIndexPath没有返回更正属性有关。
感谢任何想法。
答案 0 :(得分:0)
有点晚了,但我遇到了同样的问题。
您还需要覆盖invalidateLayout
方法。
override func invalidateLayout() {
cache.removeAll()
super.invalidateLayout()
}
然后你需要在调用insertItemsAtIndexPaths
您需要清除缓存,因为只有缓存为空时才会调用prepareLayout
方法中的逻辑。由于布局已经准备好并且缓存已填满,因此新的布局属性不会被计算并存储在缓存中。