tutorial source how example data collection ios swift uicollectionview uicollectionviewlayout

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] }