我怎么知道UICollectionView已经完全加载?
每当UICollectionView被完全加载时,我必须做一些操作,即当时所有的UICollectionView的数据源/布局方法都应该被调用。 我怎么知道? 有没有任何委托方法知道UICollectionView加载状态?
// In viewDidLoad [self.collectionView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionOld context:NULL]; - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { // You will get here when the reloadData finished } - (void)dealloc { [self.collectionView removeObserver:self forKeyPath:@"contentSize" context:NULL]; }
这对我工作:
[self.collectionView reloadData]; [self.collectionView performBatchUpdates:^{} completion:^(BOOL finished) { /// collection-view finished reload }];
这其实很简单。
例如,当您调用UICollectionView的reloadData方法或其布局的invalidateLayout方法时,请执行以下操作:
dispatch_async(dispatch_get_main_queue(), ^{ [self.collectionView reloadData]; }); dispatch_async(dispatch_get_main_queue(), ^{ //your stuff happens here //after the reloadData/invalidateLayout finishes executing });
为什么这个工作:
主线程(我们应该在哪里执行所有的UI更新)包含主队列,它是串行的,即它以FIFO的方式工作。 所以在上面的例子中,第一个块被调用了,我们调用了reloadData
方法,接下来是第二个块中的其他东西。
现在主线程也被阻塞了。 所以如果你reloadData
需要3s执行,第二个块的处理将被这些3s推迟。
像这样做:
UIView.animateWithDuration(0.0, animations: { [weak self] in guard let strongSelf = self else { return } strongSelf.collectionView.reloadData() }, completion: { [weak self] (finished) in guard let strongSelf = self else { return } // Do whatever is needed, reload is finished here // eg scrollToItemAtIndexPath let newIndexPath = NSIndexPath(forItem: 1, inSection: 0) strongSelf.collectionView.scrollToItemAtIndexPath(newIndexPath, atScrollPosition: UICollectionViewScrollPosition.Left, animated: false) })
只要添加到一个伟大的@dezinezync答案:
Swift 3+
collectionView.collectionViewLayout.invalidateLayout() // or reloadData() DispatchQueue.main.async { // your stuff here executing after collectionView has been layouted }
这适用于我:
__weak typeof(self) wself= self; [self.contentCollectionView performBatchUpdates:^{ [wself.contentCollectionView reloadData]; } completion:^(BOOL finished) { [wself pageViewCurrentIndexDidChanged:self.contentCollectionView]; }];
这就是我用Swift 3.0解决问题的方法:
override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) if !self.collectionView.visibleCells.isEmpty { // stuff } }
你可以这样做…
- (void)reloadMyCollectionView{ [myCollectionView reload]; [self performSelector:@selector(myStuff) withObject:nil afterDelay:0.0]; } - (void)myStuff{ // Do your stuff here. This will method will get called once your collection view get loaded. }
尝试这个:
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return _Items.count; } - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { UICollectionViewCell *cell; //Some cell stuff here... if(indexPath.row == _Items.count-1){ //THIS IS THE LAST CELL, SO TABLE IS LOADED! DO STUFF! } return cell; }