1

我正在通过更改数据源来交换在我的集合视图中显示的数据。这是作为选项卡式界面的一部分完成的。当新数据加载时,我想闪烁滚动指示器以告诉用户在视口之外还有更多数据。

立即地

立即这样做不起作用,因为集合视图尚未加载数据:

collectionView.dataSource = dataSource2;
[collectionView flashScrollIndicators]; // dataSource2 isn't loaded yet

dispatch_async

稍后调度flashScrollIndicators呼叫也不起作用:

collectionView.dataSource = dataSource2;
dispatch_async(dispatch_get_main_queue(), ^{
    [collectionView flashScrollIndicators]; // dataSource2 still isn't loaded
});

performSelector:withObject:afterDelay:

在定时延迟后执行flashScrollIndicators确实有效(我在 SO 的其他地方看到它),但会导致显示滚动指示器时出现一些滞后。我可以减少延迟,但似乎它只会导致竞争条件:

collectionView.dataSource = dataSource2;
[collectionView performSelector:@selector(flashScrollIndicators) withObject:nil afterDelay:0.5];

一旦集合视图接收到新数据并调整了内容视图的大小,我是否可以连接到回调以闪烁滚动指示器?

4

2 回答 2

3

把你的电话flashScrollIndicators放在里面UICollectionViewLayout的方法-finalizeCollectionViewUpdates上。

来自 Apple 的文档:

"... 在用于执行所有插入、删除和移动动画的动画块中调用此方法,因此您可以根据需要使用此方法创建其他动画。否则,您可以使用它来执行任何相关的最后一分钟任务管理布局对象的状态信息。”

希望这可以帮助!

编辑:

好,我知道了。既然您提到该finalizeCollectionViewUpdates方法没有被调用,我决定自己尝试一下。你是对的。问题是(对不起,我之前没有注意到这一点)该方法仅在您更新集合视图(例如,插入、删除、移动单元格)后调用。所以在这种情况下,它对你不起作用。所以,我有一个新的解决方案;它涉及在 ' 方法中使用UICollectionView'方法indexPathsForVisibleItemsUICollectionViewDataSourcecollectionView:cellForItemAtIndexPath:

每次你将一个新的 UICollectionViewCell 交给你的集合视图时,使用 . 检查它是否是最后一个可见单元格[[self.collectionView indexPathsForVisibleItems] lastObject]。您还需要一个 BOOL ivar 来决定是否应该闪烁指示器。每次更改数据源时,将标志设置为YES.

- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    UICollectionViewCell *cell = [cv dequeueReusableCellWithReuseIdentifier:@"MyCell" forIndexPath:indexPath];
    cell.backgroundColor = [UIColor whiteColor];

    NSIndexPath *iP = [[self.collectionView indexPathsForVisibleItems] lastObject];
    if (iP.section == indexPath.section && iP.row == indexPath.row && self.flashScrollIndicators) {
        self.flashScrollIndicators = NO;
        [self.collectionView flashScrollIndicators];
    }

    return cell;
}

我尝试了这种方法,它对我有用。

希望能帮助到你!

于 2013-06-19T00:43:58.613 回答
3

子类化UICollectionView和覆盖layoutSubviews可以是一个解决方案。您可以调用[self flashScrollIndicators]集合。问题是layoutSubviews在多个场景中被调用。

  1. 最初在创建集合并分配数据源时。
  2. 在滚动时,超出视口的单元格会被重新使用和重新布局。
  3. 显式更改框架/重新加载集合。

解决方法是,保留一个仅在重新加载数据源时才会创建的BOOL属性YES,否则将保留NO. 因此滚动条的闪烁只会在重新加载集合时显式发生。

在源代码方面,

我的收藏.h

#import <UIKit/UIKit.h>

@interface MyCollection : UICollectionView

@property (nonatomic,assign) BOOL reloadFlag;

@end

我的收藏.m

#import "MyCollection.h"

@implementation MyCollection

- (void) layoutSubviews {
    [super layoutSubviews];
    if(_reloadFlag) {
        [self flashScrollIndicators];
        _reloadFlag=NO;
    }
}

用法应该是

self.collection.reloadFlag = YES;
self.collection.dataSource = self;
于 2013-06-19T11:40:15.367 回答