UICollectionView 可滚动年视图:性能问题

UICollection View scrollable year view: performance issue

我目前正在处理一个困扰我很多的问题。我正在开发一个无休止的可滚动年视图,它与标准的苹果日历应用程序非常相似:

所以我基本上有 2 个数组,第一个包含每个月的第一天对应的工作日,第二个包含我要显示的月份的总天数。

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {


    int currentYearIndex = (int)indexPath.section * 12;

    int fillDays      = [[self.dayIndexThisMonthArray objectAtIndex:indexPath.row  + currentYearIndex ]intValue];
    int daysThisMonth = [[self.daysThisMonthArray     objectAtIndex:indexPath.row  + currentYearIndex ]intValue];

    EMYearCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"YearCell" forIndexPath:indexPath];
    [cell configureForNumberOfFillDays: fillDays daysThisMonth: daysThisMonth];

    return cell;

}

我创建了一个自定义的UICollectionView class,它接收aford-said 2信息并在创建相应月份后进行处理:

#import "EMYearCell.h"

@interface EMYearCell()

@end

@implementation EMYearCell


- (void)configureForNumberOfFillDays: (int)fillDays daysThisMonth: (int)daysThisMonth
{
    @autoreleasepool {

        void (^labelingBlock) (int, int, int)= ^(int horizontalSpacingMultiplier, int i,  int fillDayAdjuster){

            self.theLabel = [[EMCalendarLabel alloc]initWithFrame:CGRectMake(self.initialXCord + i * self.distanceBetweenLabels, self.initialYCord + self.horizontalSpacing * horizontalSpacingMultiplier, 50, 50)];
            [self.theLabel setText:[NSString stringWithFormat:@"%d",i + fillDayAdjuster - fillDays]];
            [self addSubview:self.theLabel];
        };

    for (int i = fillDays; i < 7; i++){

        labelingBlock (1,i,1);
    }

    for (int i = 0; i < 7; i++){

        labelingBlock (2,i,8);
    }

    for (int i = 0; i < 7; i++){

        labelingBlock (3,i,15);
    }

    for (int i = 0; i < 7; i++){

        labelingBlock (4,i,22);
    }

    for (int i = 0; i < 7; i++){

        if (i + 29 - fillDays < daysThisMonth + 1){

            labelingBlock (5,i,29);
        }
    }

    for (int i = 0; i < 7; i++){

        if (i + 36 - fillDays < daysThisMonth + 1){

                labelingBlock (6,i,36);
            }
        }
    }
}

尽管我只是将一堆标签作为子视图添加到我的自定义 UICollectionView 单元格中,但滚动非常缓慢且不稳定。我真的想不出有什么可能让这一切变得更便宜。

我试过这个:

[self.view.layer setShouldRasterize:YES];
[self.view.layer setRasterizationScale:[UIScreen mainScreen].scale];

但我也没有发现任何改善。

我非常感谢能在这种情况下帮助我的任何建议。

你可以简单地做这样的事情:

@interface EMYearCell : UICollectionViewCell    
@property (nonatomic, strong) NSOperation *updateOperation;
@end

@interface MyCollectionViewController ()
@property NSOperationQueue *operationQueue;
@end

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.operationQueue = [NSOperationQueue new];        
    self.operationQueue.maxConcurrentOperationCount = 1;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
        EMYearCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier: @"YearCell" forIndexPath: indexPath];

        // Increment the cell's tag
        NSInteger currentTag = cell.tag + 1;
        cell.tag = currentTag;

        NSBlockOperation *updateOperation = [NSBlockOperation blockOperationWithBlock:^{

                // preparing data for the cell here

                dispatch_sync(dispatch_get_main_queue(), ^{
                        // Only update the cell if the cell tag hasn't changed. Otherwise, the cell has been re-used.
                        if (cell.tag == currentTag) {

                                // update the cell here

                        }
                });
        }];

        cell.updateOperation = updateOperation;
        [self.operationQueue addOperation:updateOperation];

        return cell;
}

- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath {
        // cancel the associated update operation
        EMYearCell *yearCell = (EMYearCell *)cell;
        [yearCell.updateOperation cancel];
}

我通过添加 CATextLayer 作为子层替换了我的自定义 UICollectionViewCell 中的所有标签,等等,突然滚动变得如丝般顺滑。