2012-11-07 72 views
66

在我的項目中,我使用UICollectionView來顯示一個圖標網格。UICollectionView動畫數據變化

用戶可以通過單擊調用從不同NSSortDescriptor的核心數據獲取的分段控件來更改排序。

的數據量始終是一樣的,只是結束了在不同的部分/行:

- (IBAction)sortSegmentedControlChanged:(id)sender { 

    _fetchedResultsController = nil; 
    _fetchedResultsController = [self newFetchResultsControllerForSort]; 

    NSError *error; 
    if (![self.fetchedResultsController performFetch:&error]) { 
     NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
    } 

    [self.collectionView reloadData]; 
} 

的問題是,reloadData沒有動畫的變化,UICollectionView只是用新的數據持久性有機污染物。

我應該跟蹤一個單元格在更改前後的indexPath,並使用[self.collectionView moveItemAtIndexPath:toIndexPath:]來執行更改的動畫,或者有更好的方法嗎?

我沒有得到多少成子類collectionViews所以任何幫助將是巨大的......

感謝, 比爾。

+0

你試過在動畫塊中包裝'reloadData'調用? – simon

回答

58

reloadData不會動畫,也不會在放入UIView動畫塊時可靠地這樣做。它想成爲一個UICollecitonView performBatchUpdates塊,所以嘗試更多的東西一樣:

[self.collectionView performBatchUpdates:^{ 
    [self.collectionView reloadData]; 
} completion:^(BOOL finished) {}]; 
+4

是的,這似乎工作,但前提是你必須保存部分號碼......別的我收到「部分的失效數量。包含在更新後的集合視圖部分的數量(10)必須等於數在更新(16)之前收集視圖中包含的部分「。我必須手動插入/刪除部分...無論如何接受!謝謝。 – Nimrod7

+1

通過「手動」,你的意思是通過UICollectionView的insertSections/moveSection:toSection/deleteSections調用嗎?或者是其他東西?通過這些方法(很抱歉,迄今爲止我使用UICollectionView已經有部分的靜態數) – Stripes

+1

是......它有點棘手實現思想,你有更新前後記住indexpaths,取出插入什麼人物,或移動... – Nimrod7

130

結束語在-performBatchUpdates:-reloadData似乎沒有引起一個截面集合視圖動畫。

[self.collectionView performBatchUpdates:^{ 
    [self.collectionView reloadData]; 
} completion:nil]; 

然而,此代碼的工作:

[self.collectionView performBatchUpdates:^{ 
    [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]]; 
} completion:nil]; 
+8

注意:您不應該調用重載數據的方法在項目被插入或刪除動畫塊的中間。插入和刪除操作會自動導致表格數據被適當更新。 –

+0

我認爲這應該是正確的答案。因爲這對我有用。我只有1個部分,這是不正確的答案。 –

+0

如果您還插入了,則不起作用。將重寫排序動畫。 –

2

幫助文本說:

調用此方法重新加載所有項目的集合視圖。 這會導致收集視圖丟棄任何當前可見項目 並重新顯示它們。爲了提高效率,收集視圖僅顯示 那些可見的單元格和補充視圖。如果 收集數據因重新加載而收縮,則收集視圖 會相應地調整其滾動偏移量。在插入或刪除項目爲 的動畫塊中,不應將此方法稱爲 方法。插入和刪除操作會自動導致 表的數據得到適當更新。

我認爲關鍵部分是「導致集合視圖丟棄任何目前可見的項目」。它將如何動畫它丟棄的物品的運動?

47

這是我做的動畫各斷面重載:

[self.collectionView reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, self.collectionView.numberOfSections)]]; 

斯威夫特3

let range = Range(uncheckedBounds: (0, collectionView.numberOfSections)) 
let indexSet = IndexSet(integersIn: range) 
collectionView.reloadSections(indexSet) 
2

如果你想要更多的控制和定製功能檢查this, 它包含一個非常詳細地解釋了UICollectionViewCell動畫的各種方式。

4

重新裝載performBatchUpdates:completion:塊內的整個集合視圖確實爲我在iOS 9模擬器出問題動畫。如果您想刪除特定的UICollectionViewCell,或者如果您有它的索引路徑,則可以在該塊中調用deleteItemsAtIndexPaths:。通過使用deleteItemsAtIndexPaths:,它可以製作流暢動人的動畫。

UICollectionViewCell* cellToDelete = /* ... */; 
NSIndexPath* indexPathToDelete = /* ... */; 

[self.collectionView performBatchUpdates:^{ 
    [self.collectionView deleteItemsAtIndexPaths:@[[self.collectionView indexPathForCell:cell]]]; 
    // or... 
    [self.collectionView deleteItemsAtIndexPaths:@[indexPath]]; 
} completion:nil]; 
+1

只是想提一個解決我的情況下的崩潰問題的東西,更新數據源(即。部分/項目計數),然後在集合視圖上調用performUpdates。 – ViruMax

-2

對於SWIFT用戶這來得心應手 -

collectionView.performBatchUpdates({ 

      self.collectionView.reloadSections(NSIndexSet(index: index)) 

      }, completion: nil) 
1

對於SWIFT用戶,如果您的CollectionView只有一個部分:

self.collectionView.performBatchUpdates({ 
        let indexSet = IndexSet(integersIn: 0...0) 
        self.collectionView.reloadSections(indexSet) 
       }, completion: nil) 

由於看到https://stackoverflow.com/a/42001389/4455570