ios - source - Error ''No UICollectionViewLayoutAttributes instancia para-layoutAttributesForItemAtIndexPath'' utilizando UICollectionViewLayout personalizado
uicollectionview swift 4 (1)
Estoy usando un UICollectionViewLayout personalizado como este:
override func prepareLayout() {
cache.removeAll(keepCapacity: false)
let standardHeight = LayoutConstants.Cell.standardHeight
let featuredHeight = LayoutConstants.Cell.featuredHeight
var frame = CGRectZero
var y: CGFloat = 0
for item in 0..<numberOfItems {
let indexPath = NSIndexPath(forItem: item, inSection: 0)
let attributes = UICollectionViewLayoutAttributes(forCellWithIndexPath: indexPath)
let cell = collectionView!.cellForItemAtIndexPath(indexPath)
/* Important because each cell has to slide over the top of the previous one */
attributes.zIndex = item
/* Initially set the height of the cell to the standard height */
var height = standardHeight
if indexPath.item == featuredItemIndex {
/* The featured cell */
let yOffset = standardHeight * nextItemPercentageOffset
y = collectionView!.contentOffset.y - yOffset
height = featuredHeight
} else if indexPath.item == (featuredItemIndex + 1) && indexPath.item != numberOfItems {
/* The cell directly below the featured cell, which grows as the user scrolls */
let maxY = y + standardHeight
height = standardHeight + max((featuredHeight - standardHeight) * nextItemPercentageOffset, 0)
y = maxY - height
}
frame = CGRect(x: 0, y: y, width: width, height: height)
attributes.frame = frame
cache.append(attributes)
y = CGRectGetMaxY(frame)
}
}
/* Return all attributes in the cache whose frame intersects with the rect passed to the method */
override func layoutAttributesForElementsInRect(rect: CGRect) -> [AnyObject]? {
var layoutAttributes = [UICollectionViewLayoutAttributes]()
for attributes in cache {
if CGRectIntersectsRect(attributes.frame, rect) {
layoutAttributes.append(attributes)
}
}
return layoutAttributes
}
Eso funciona como yo quiero, pero si quiero insertar otro elemento, mi aplicación se bloquea con este error:
2015-05-31 22:37:29.032 Flore-Jessy[15359:717220] *** Assertion failure in -[UICollectionViewData layoutAttributesForItemAtIndexPath:], /SourceCache/UIKit_Sim/UIKit-3347.44/UICollectionViewData.m:694
2015-05-31 22:37:29.077 Flore-Jessy[15359:717220] *** Terminating app due to uncaught exception ''NSInternalInconsistencyException'', reason: ''no UICollectionViewLayoutAttributes instance for -layoutAttributesForItemAtIndexPath: <NSIndexPath: 0x7b952a70> {length = 2, path = 0 - 15}''
*** First throw call stack:
(
0 CoreFoundation 0x00a0a746 __exceptionPreprocess + 182
1 libobjc.A.dylib 0x02867a97 objc_exception_throw + 44
2 CoreFoundation 0x00a0a5da +[NSException raise:format:arguments:] + 138
3 Foundation 0x01093720 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 118
4 UIKit 0x01de5c74 -[UICollectionViewData layoutAttributesForItemAtIndexPath:] + 461
5 UIKit 0x01dafbe7 __51-[UICollectionView _viewAnimationsForCurrentUpdate]_block_invoke1382 + 161
6 UIKit 0x01dad73b -[UICollectionView _viewAnimationsForCurrentUpdate] + 4789
7 UIKit 0x01db0eb8 -[UICollectionView _updateWithItems:tentativelyForReordering:] + 2447
8 UIKit 0x01dabf0d -[UICollectionView _endItemAnimationsWithInvalidationContext:tentativelyForReordering:] + 14802
9 UIKit 0x01da8536 -[UICollectionView _endItemAnimationsWithInvalidationContext:] + 48
10 UIKit 0x01da82ed -[UICollectionView _updateRowsAtIndexPaths:updateAction:] + 374
11 UIKit 0x01da833f -[UICollectionView insertItemsAtIndexPaths:] + 48
12 Flore-Jessy 0x0009183c _TFC11Flore_Jessy22TimelineViewController13viewDidAppearfS0_FSbT_ + 556
13 Flore-Jessy 0x000918cf _TToFC11Flore_Jessy22TimelineViewController13viewDidAppearfS0_FSbT_ + 63
14 UIKit 0x017f3245 -[UIViewController _setViewAppearState:isAnimating:] + 629
15 UIKit 0x017f3860 -[UIViewController __viewDidAppear:] + 171
16 UIKit 0x017f3b2b -[UIViewController _endAppearanceTransition:] + 322
17 UIKit 0x0180bd4e -[UIViewController(UIContainerViewControllerProtectedMethods) endAppearanceTransition] + 41
18 UIKit 0x017c403b -[UIPresentationController transitionDidFinish:] + 839
19 UIKit 0x01e50109 -[_UIFullscreenPresentationController transitionDidFinish:] + 59
20 UIKit 0x017c6c11 __56-[UIPresentationController runTransitionForCurrentState]_block_invoke_2 + 165
21 UIKit 0x01ef444a -[_UIViewControllerTransitionContext completeTransition:] + 124
22 Flore-Jessy 0x0008e174 _TFFC11Flore_Jessy29SwipeBluredTransitionAnimator17animateTransitionFS0_FPSo36UIViewControllerContextTransitioning_T_U0_FSbT_ + 436
23 Flore-Jessy 0x0008ca34 _TPA__TFFC11Flore_Jessy29SwipeBluredTransitionAnimator17animateTransitionFS0_FPSo36UIViewControllerContextTransitioning_T_U0_FSbT_ + 68
24 Flore-Jessy 0x0008e1bc _TTRXFo_dSb_dT__XFo_iSb_iT__ + 28
25 Flore-Jessy 0x0008caea _TPA__TTRXFo_dSb_dT__XFo_iSb_iT__ + 90
26 Flore-Jessy 0x0008e1f7 _TTRXFo_iSb_iT__XFo_dSb_dT__ + 39
27 Flore-Jessy 0x0008cb9e _TPA__TTRXFo_iSb_iT__XFo_dSb_dT__ + 78
28 Flore-Jessy 0x0008e245 _TTRXFo_dSb_dT__XFdCb_dV10ObjectiveC8ObjCBool_dT__ + 69
29 UIKit 0x017149be -[UIViewAnimationBlockDelegate _didEndBlockAnimation:finished:context:] + 318
30 UIKit 0x016f81b2 -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 206
31 UIKit 0x016f8522 -[UIViewAnimationState animationDidStop:finished:] + 80
32 QuartzCore 0x0154a571 _ZN2CA5Layer23run_animation_callbacksEPv + 307
33 libdispatch.dylib 0x02f59bef _dispatch_client_callout + 14
34 libdispatch.dylib 0x02f3f6bb _dispatch_main_queue_callback_4CF + 993
35 CoreFoundation 0x009638ee __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 14
36 CoreFoundation 0x009215f0 __CFRunLoopRun + 2256
37 CoreFoundation 0x00920a5b CFRunLoopRunSpecific + 443
38 CoreFoundation 0x0092088b CFRunLoopRunInMode + 123
39 GraphicsServices 0x051e02c9 GSEventRunModal + 192
40 GraphicsServices 0x051e0106 GSEventRun + 104
41 UIKit 0x0168a106 UIApplicationMain + 1526
42 Flore-Jessy 0x00080a24 main + 180
43 libdyld.dylib 0x02f84ac9 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Este es el código que uso para insertar el nuevo elemento
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
if let post = newPost {
collectionView!.insertItemsAtIndexPaths([dataSource.indexPathForNewPost(post)])
}
}
/// Return the new indexPath for the TimelineItem
func indexPathForNewPost(item: TimelineItem) -> NSIndexPath {
if let liste = listPosts {
listPosts!.append(item)
}
return indexPathForPost(item)
}
func indexPathForPost(item: TimelineItem) -> NSIndexPath {
var itemIndex = 0
for (index, currentTimelineItem) in enumerate(allPosts()) {
if currentTimelineItem === item {
itemIndex = index
break
}
}
return NSIndexPath(forItem: itemIndex, inSection: 0)
}
Alguna idea ?
En base al mensaje de error, esto se debe a que la celda no puede recuperar layoutAttributes. layoutAttributesForItemAtIndexPath
devuelve nil si la celda que creará la actualización no está visible.
Para corregir este error, anule el método layoutAttributesForItemAtIndexPath
:
override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? {
return cache[indexPath.row]
}
SWIFT 3 -
override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
return cache[indexPath.row]
}