dar*_*sky 31 xcode objective-c ipad ios uicollectionview
我有一个UICollectionView我试图动态/动画插入项目.所以我有一些函数可以异步下载图像,并希望批量插入项目.
获得数据后,我想执行以下操作:
[self.collectionView performBatchUpdates:^{
for (UIImage *image in images) {
[self.collectionView insertItemsAtIndexPaths:****]
}
} completion:nil];
Run Code Online (Sandbox Code Playgroud)
现在代替了***,我应该传递一个数组NSIndexPaths,它应该指向要插入的新项目的位置.我提供位置后非常困惑,如何提供应该在该位置显示的实际图像?
谢谢
更新:
resultsSize包含数据源数组的大小self.results,在从数据中添加新数据之前newImages.
[self.collectionView performBatchUpdates:^{
int resultsSize = [self.results count];
[self.results addObjectsFromArray:newImages];
NSMutableArray *arrayWithIndexPaths = [NSMutableArray array];
for (int i = resultsSize; i < resultsSize + newImages.count; i++)
[arrayWithIndexPaths addObject:[NSIndexPath indexPathForRow:i inSection:0]];
[self.collectionView insertItemsAtIndexPaths:arrayWithIndexPaths];
} completion:nil];
Run Code Online (Sandbox Code Playgroud)
Mar*_*n R 30
请参阅"适用于iOS的集合视图编程指南 "中的插入,删除和移动节和项目:
要插入,删除或移动单个部分或项目,您必须执行以下步骤:
- 更新数据源对象中的数据.
- 调用集合视图的相应方法以插入或删除节或项.
在通知集合视图任何更改之前更新数据源至关重要.集合视图方法假定您的数据源包含当前正确的数据.如果没有,集合视图可能会从您的数据源收到错误的项目集,或者询问不存在的项目并使您的应用程序崩溃.
因此,在您的情况下,您必须先将图像添加到集合视图数据源,然后再调用insertItemsAtIndexPaths.然后,集合视图将要求数据源委托函数提供插入项的视图.
Plo*_*lot 11
我刚刚用Swift实现了它.所以我想分享我的实施.首先初始化NSBlockOperations数组:
var blockOperations: [NSBlockOperation] = []
Run Code Online (Sandbox Code Playgroud)
在控制器中将更改,重新初始化数组:
func controllerWillChangeContent(controller: NSFetchedResultsController) {
blockOperations.removeAll(keepCapacity: false)
}
Run Code Online (Sandbox Code Playgroud)
在做了改变对象的方法:
func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
if type == NSFetchedResultsChangeType.Insert {
println("Insert Object: \(newIndexPath)")
blockOperations.append(
NSBlockOperation(block: { [weak self] in
if let this = self {
this.collectionView!.insertItemsAtIndexPaths([newIndexPath!])
}
})
)
}
else if type == NSFetchedResultsChangeType.Update {
println("Update Object: \(indexPath)")
blockOperations.append(
NSBlockOperation(block: { [weak self] in
if let this = self {
this.collectionView!.reloadItemsAtIndexPaths([indexPath!])
}
})
)
}
else if type == NSFetchedResultsChangeType.Move {
println("Move Object: \(indexPath)")
blockOperations.append(
NSBlockOperation(block: { [weak self] in
if let this = self {
this.collectionView!.moveItemAtIndexPath(indexPath!, toIndexPath: newIndexPath!)
}
})
)
}
else if type == NSFetchedResultsChangeType.Delete {
println("Delete Object: \(indexPath)")
blockOperations.append(
NSBlockOperation(block: { [weak self] in
if let this = self {
this.collectionView!.deleteItemsAtIndexPaths([indexPath!])
}
})
)
}
}
Run Code Online (Sandbox Code Playgroud)
在更改部分方法中:
func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) {
if type == NSFetchedResultsChangeType.Insert {
println("Insert Section: \(sectionIndex)")
blockOperations.append(
NSBlockOperation(block: { [weak self] in
if let this = self {
this.collectionView!.insertSections(NSIndexSet(index: sectionIndex))
}
})
)
}
else if type == NSFetchedResultsChangeType.Update {
println("Update Section: \(sectionIndex)")
blockOperations.append(
NSBlockOperation(block: { [weak self] in
if let this = self {
this.collectionView!.reloadSections(NSIndexSet(index: sectionIndex))
}
})
)
}
else if type == NSFetchedResultsChangeType.Delete {
println("Delete Section: \(sectionIndex)")
blockOperations.append(
NSBlockOperation(block: { [weak self] in
if let this = self {
this.collectionView!.deleteSections(NSIndexSet(index: sectionIndex))
}
})
)
}
}
Run Code Online (Sandbox Code Playgroud)
最后,在did控制器中确实改变了内容方法:
func controllerDidChangeContent(controller: NSFetchedResultsController) {
collectionView!.performBatchUpdates({ () -> Void in
for operation: NSBlockOperation in self.blockOperations {
operation.start()
}
}, completion: { (finished) -> Void in
self.blockOperations.removeAll(keepCapacity: false)
})
}
Run Code Online (Sandbox Code Playgroud)
我个人也在deinit方法中添加了一些代码,以便在ViewController即将解除分配时取消操作:
deinit {
// Cancel all block operations when VC deallocates
for operation: NSBlockOperation in blockOperations {
operation.cancel()
}
blockOperations.removeAll(keepCapacity: false)
}
Run Code Online (Sandbox Code Playgroud)
我在从索引中删除项目时遇到了类似的问题,这是我认为在使用performBatchUpdates:方法时我们需要做的事情.
1#首先调用deleteItemAtIndexPath从集合视图中删除该项.
2#从数组中删除元素.
3#通过重新加载数据更新集合视图.
[self.collectionView performBatchUpdates:^{
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:sender.tag inSection:0];
[self.collectionView deleteItemsAtIndexPaths:[NSArray arrayWithObject:indexPath]];
[self.addNewDocumentArray removeObjectAtIndex:sender.tag];
} completion:^(BOOL finished) {
[self.collectionView reloadData];
}];
Run Code Online (Sandbox Code Playgroud)
这有助于我删除所有崩溃和断言失败.
| 归档时间: |
|
| 查看次数: |
70382 次 |
| 最近记录: |