2013-10-18 19 views
17

iOS7上的聲明失敗UICollectionViewDatavalidateLayoutInRectUICollectionViewData中的聲明失敗ios7上的validateLayoutInRect

我在嘗試使用for循環逐個刪除所有UICollectionView項目;我在下面發佈了我的代碼。我使用deleteItemsAtIndexPaths刪除UICollectionView項目。這是在iOS6的完美的工作,但崩潰的iOS7與此異常:

斷言失敗在UICollectionViewData validateLayoutInRect

我刪除collectionArray然後self.collectionView對象,一個接一個,使用indexPath 。當我刪除第4個對象時,它在iOS7上引發Assertion failure。我在這裏使用performBatchUpdates

請幫我在iOS7中獲得正確的結果。分享正確的代碼。 在此先感謝。

try {  
    for (int i=count-1; i>=0; i--) { 
     [self.collectionView performBatchUpdates:^(void){ 
      [collectionArray removeObjectAtIndex:i]; // First delete the item from you model 
      [self.collectionView deleteItemsAtIndexPaths:@[[NSIndexPath indexPathForRow:i inSection:0]]]; 
     } completion:nil]; 
     [self.collectionView reloadData]; 
    } 
} 
@catch (NSException *exception) { 
} 
@finally { 
} 
+0

看起來提到像你有同樣的問題: http://stackoverflow.com/questions/18189311/bad-access-on-uicollectionview-setcollectionviewlayoutanimated和 http://stackoverflow.com/questions/ 18339030/uicollectionview-assertion-error-on-stale-data –

回答

23

事實上,我這個崩潰一次不是因爲我是回零的數量在部分部分或項目的,但因爲我是重用這樣的流佈局超過1個集合視圖:

UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init]; 
[flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal]; 
Collection1 = [[UICollectionView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 50.0f) collectionViewLayout:flowLayout]; 
[Collection1 setDataSource:self]; 
[Collection1 setDelegate:self]; 
[self.view addSubview:Collection1]; 

Collection2 = [[UICollectionView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, self.view.frame.size.height) collectionViewLayout:flowLayout]; 
Collection2.backgroundColor = [UIColor whiteColor]; 

相反,如果我爲每個UICollectionView創建一個新的流佈局,我會避免這種崩潰。希望這可以幫助別人

UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init]; 
[flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal]; 
Collection1 = [[UICollectionView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 50.0f) collectionViewLayout:flowLayout]; 
[Collection1 setDataSource:self]; 
[Collection1 setDelegate:self]; 
[self.view Collection1]; 

UICollectionViewFlowLayout *flowLayoutVert = [[UICollectionViewFlowLayout alloc] init]; 
[flowLayoutVert setScrollDirection:UICollectionViewScrollDirectionVertical]; 
Collection2 = [[UICollectionView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, self.view.frame.size.height) collectionViewLayout:flowLayoutVert]; 
+0

我正在做同樣的事情,但無濟於事。 – Nitesh

+2

有很大的幫助。節省我的時間。 – WeZZard

+0

讓我很高興,當它真正幫助某人時,我會寫下這些東西。 – ColossalChris

3

看起來你可能想這樣做:

[self.CollectionView performBatchUpdates:^(void) { 
    for (int i = count - 1; i >= 0; i--) { 
    [collectionArray removeObjectAtIndex:i]; // First delete the item from you model 
    [self.CollectionView deleteItemsAtIndexPaths:@[[NSIndexPath indexPathForRow:i inSection:0]]]; 
    } 
} completion:nil]; 

,使所有的更新一起執行。否則,您將最終嘗試執行幾次批量更新。

0

嘗試調用[yourCollectionView.collectionViewLayout invalidateLayout];

-1
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { 
    [collectionView.collectionViewLayout invalidateLayout]; 
    return 1; 
} 
+3

這會導致堆棧溢出。 – Superwayne

13

在iOS的10,您必須禁用prefetchingEnabled:

// Swift 
if #available(iOS 10, *) { 
    collectionView.prefetchingEnabled = false 
} 

//Obj C 
if ([self.collectionView respondsToSelector:@selector(setPrefetchingEnabled:)]) { 
    self.collectionView.prefetchingEnabled = false; 
} 
+1

你先生是救命的人。謝謝。它確實解決了我使用自定義FlowLayout類時的問題。 – Arslan

+0

親吻和詛咒 – dang

+0

我應該在** viewDidLoad()**中添加此代碼嗎? – iUser

0

在我的情況下委託失蹤:

func numberOfSections(in collectionView: UICollectionView) -> Int { 
     return 1 
    } 
0

layout lifecycle

您應該在layoutClass中執行invalidateLayout並刪除配置中的各種UICollectionViewLayoutAttributes項。

- (void)invalidateLayout{ 
    [super invalidateLayout]; 
    [self.itemsAttributes removeAllObjects]; 
} 
0

你應該在你的佈局類中實現和的invalidateLayout消除各種UICollectionViewLayoutAttributes物品在你的配置。

- (void)invalidateLayout{ 
    [super invalidateLayout]; 
    [self.itemsAttributes removeAllObjects]; 
} 

對於實現invalidateLayoutWithContext一種更好的方式,看到更多的關於UICollectionViewLayoutInvalidationContext

Apple Developer documentation

在實現自定義佈局,您可以覆蓋此方法,並使用 它來處理由一個自定義的無效中提供的信息。 如果您能夠提供可幫助 優化佈局更新的其他屬性,則不需要提供自定義無效上下文,但可能需要 。如果您重寫此方法,則必須在實施中的某個時刻調用 超級。