UICollectionView custom flow layout crashes on scrolling

匿名 (未验证) 提交于 2019-12-03 09:05:37

问题:

I am creating a custom flowLayout with section headers.

here is my flowLayout.swift

import UIKit  class FlowLayout: UICollectionViewFlowLayout {      override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {        // let attributesForElementsInRect = super.         var newAttributesForElementsInRect = [UICollectionViewLayoutAttributes]()          // unwrap super's attributes         guard let attributesForElementsInRect = super.layoutAttributesForElementsInRect(rect) else { return nil }          // modify attributes          var leftMargin: CGFloat = 0.0;            for attributes in attributesForElementsInRect {              let itemAttributesCopy = attributes.copy() as! UICollectionViewLayoutAttributes              if( itemAttributesCopy.frame.size.width + leftMargin > self.collectionView?.frame.size.width)             {                 leftMargin = 8.0             }             if (itemAttributesCopy.frame.origin.x == self.sectionInset.left) {                 leftMargin = self.sectionInset.left             } else {                 var newLeftAlignedFrame = itemAttributesCopy.frame                 newLeftAlignedFrame.origin.x = leftMargin                 itemAttributesCopy.frame = newLeftAlignedFrame             }             leftMargin += itemAttributesCopy.frame.size.width + 8             print(itemAttributesCopy.frame)               newAttributesForElementsInRect.append(itemAttributesCopy)             print(itemAttributesCopy)         }          return newAttributesForElementsInRect     }  } 

here is my ViewController with delegate function for section header

func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {           if(sectionsArray.count == 0)         {             return 1         }         else         {             return sectionsArray.count         }     }        func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {              let headerView: TagHeader = collectionView.dequeueReusableSupplementaryViewOfKind(kind, withReuseIdentifier: "TagHeader", forIndexPath: indexPath) as! TagHeader              headerView.sectionLabel.text = sectionsArray[indexPath.section].header             return headerView         } 

So when I run the app, it shows me the section headers and everything works fine.

But when I scroll, app crashes with following error from debugger

2016-07-01 18:52:12.051 TagFlowLayout[15025:4704387] *** Assertion failure in -[UICollectionViewData validateLayoutInRect:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit/UIKit-3512.60.7/UICollectionViewData.m:408 2016-07-01 18:52:12.054 TagFlowLayout[15025:4704387] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'layout attributes for supplementary item at index path (<NSIndexPath: 0x17e96f70> {length = 2, path = 0 - 0}) changed from <UICollectionViewLayoutAttributes: 0x17e7ab00> index path: (<NSIndexPath: 0x17d8fb30> {length = 2, path = 0 - 0}); element kind: (UICollectionElementKindSectionHeader); frame = (8 0; 314 50); zIndex = 10;  to <UICollectionViewLayoutAttributes: 0x17e9d770> index path: (<NSIndexPath: 0x17e96f70> {length = 2, path = 0 - 0}); element kind: (UICollectionElementKindSectionHeader); frame = (0 0; 314 50); zIndex = 10;  without invalidating the layout' 

回答1:

You need to invalidate the existing layout before updating, see the end of the error message:

without invalidating the layout

You should override the method at the subclass of UICollectionViewFlowLayout:

override func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool {         return true     } 

For more reference see Apple Documentation for UICollectionViewLayout



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!