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
中的所有标签,等等,突然滚动变得如丝般顺滑。
我目前正在处理一个困扰我很多的问题。我正在开发一个无休止的可滚动年视图,它与标准的苹果日历应用程序非常相似:
所以我基本上有 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
中的所有标签,等等,突然滚动变得如丝般顺滑。