UICollectionView 水平滚动延迟加载单元格

UICollectionView Horizontal Scrollling Delay loading cells

尝试添加一个水平滚动的UICollectionView 次。问题是在一堆单元格之后,就像下一个单元格加载晚了一样。我必须经常在屏幕上一直滚动,直到加载下一组单元格。在屏幕截图中,时间 2:30PM 和 3:00PM 应该已经可见。

视图控制器

GHTMeetingTimesCollectionViewFlowLayout *timesFlowLayout = [[GHTMeetingTimesCollectionViewFlowLayout alloc] init];
timesFlowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
timesFlowLayout.itemSize = CGSizeMake(kIconCellItemWidth, kIconCollectionHeight);

self.timesSelectCollectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:timesFlowLayout];
self.timesSelectCollectionView.translatesAutoresizingMaskIntoConstraints = NO;
self.timesSelectCollectionView.allowsMultipleSelection = YES;
self.timesSelectCollectionView.showsHorizontalScrollIndicator = NO;
self.timesSelectCollectionView.backgroundColor = [UIColor clearColor];
self.timesSelectCollectionView.delegate = self;
self.timesSelectCollectionView.dataSource = self;
[self.contentView addSubview:self.timesSelectCollectionView];
[self.timesSelectCollectionView registerClass:[GHTMeetingTimeCollectionViewCell class] forCellWithReuseIdentifier:kMeetingTimeCellIdentifier];

GHTMeetingTimesCollectionViewFlowLayout

@implementation GHTMeetingTimesCollectionViewFlowLayout

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
    NSArray* arr = [super layoutAttributesForElementsInRect:rect];
    for (UICollectionViewLayoutAttributes* atts in arr) {
        if (nil == atts.representedElementKind) {
            NSIndexPath* attsPath = atts.indexPath;
            atts.frame = [self layoutAttributesForItemAtIndexPath:attsPath].frame;
        }
    }
    return arr;
}


- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {

    UICollectionViewLayoutAttributes* atts = [super layoutAttributesForItemAtIndexPath:indexPath];
    CGRect adjustedFrame = atts.frame;
    adjustedFrame.origin.x = indexPath.row*kIconCellItemWidth;
    adjustedFrame.size.width = kIconCellItemWidth;
    adjustedFrame.size.height = kIconCollectionHeight;
    atts.frame = adjustedFrame;
    return atts;
}

CollectionView 单元格 Class

@implementation GHTMeetingTimeCollectionViewCell


- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];

    if (self) {
        self.backgroundColor = [UIColor clearColor];

        self.highlightColor = [UIColor lightBlue];

        self.timeLabel = [[UILabel alloc] init];
        self.timeLabel.layer.cornerRadius = 3;
        self.timeLabel.clipsToBounds = YES;
        self.timeLabel.font = [UIFont fontWithName:GFFontStandard size:14];
        self.timeLabel.textColor = [UIColor lightBlue];
        self.timeLabel.translatesAutoresizingMaskIntoConstraints = NO;
        self.timeLabel.textAlignment = NSTextAlignmentCenter;
        self.timeLabel.backgroundColor = [UIColor clearColor];
        [self.contentView addSubview:self.timeLabel];

        [NSLayoutConstraint sidesOfChild:self.timeLabel toSidesOfParent:self.contentView margin:8];
        [NSLayoutConstraint centerYOfChild:self.timeLabel toCenterYOfParent:self.contentView];
    }

    return self;
}

-(void)setTimeDisplay:(NSString *)time {
    self.timeLabel.text = time;
}

- (void)setSelected:(BOOL)selected {
    [super setSelected:selected];
    self.timeLabel.backgroundColor = selected ? self.highlightColor : [UIColor clearColor];
    self.timeLabel.textColor = selected ? [UIColor whiteColor] : self.highlightColor;

}

- (void)setHighlightColor:(UIColor *)highlightColor {

    _highlightColor = highlightColor;
    self.timeLabel.backgroundColor = self.isSelected ? _highlightColor : [UIColor clearColor];
    self.timeLabel.textColor = self.isSelected ? [UIColor whiteColor] : _highlightColor;

}

委托方法

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

    GHTMeetingTimeCollectionViewCell *cell = [self.timesSelectCollectionView dequeueReusableCellWithReuseIdentifier:kMeetingTimeCellIdentifier forIndexPath:indexPath];

    NSDate *date = [self.times objectAtIndex:indexPath.row];
    [cell setTimeDisplay:[self.timeOnlyFormatter stringFromDate:date]];
    if (self.existing) {
        [cell setHighlightColor:[UIColor lightGrayColor]];
    }

    return cell;
}

试试看:

@interface GHTMeetingTimesCollectionViewFlowLayout ()

@property (nonatomic, strong) NSMutableDictionary *layoutInfo;

@end
@implementation GHTMeetingTimesCollectionViewFlowLayout


- (NSDictionary *)layoutInfo
{
    if (!_layoutInfo)
    {
        _layoutInfo = [NSMutableDictionary dictionary];
    }

    return _layoutInfo;
}

- (void)prepareLayout
{
    NSInteger sectionCount = [self.collectionView numberOfSections];
    NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:0];


    for (NSInteger section = 0; section < sectionCount; section++) {

        NSInteger itemCount = [self.collectionView numberOfItemsInSection:section];

        for (NSInteger item = 0; item < itemCount; item++) {

            indexPath = [NSIndexPath indexPathForItem:item inSection:section];

            UICollectionViewLayoutAttributes *atts = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];

            CGRect adjustedFrame = atts.frame;
            adjustedFrame.origin.x = indexPath.row*kIconCellItemWidth;
            adjustedFrame.size.width = kIconCellItemWidth;
            adjustedFrame.size.height = kIconCollectionHeight;

            atts.frame = adjustedFrame;

            self.layoutInfo[indexPath] = atts;
        }
    }
}

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
    NSMutableArray *allAttributes = [NSMutableArray arrayWithCapacity:self.layoutInfo.count];

    [self.layoutInfo enumerateKeysAndObjectsUsingBlock:^(NSIndexPath *indexPath, UICollectionViewLayoutAttributes *attributes, BOOL *innerStop)
    {
        if (CGRectIntersectsRect(rect, attributes.frame)) {
            [allAttributes addObject:attributes];
        }

    }];

    return allAttributes;
}

-(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
    return self.layoutInfo[indexPath];
}


@end

PS : 我刚写的,没有测试。我希望它不包含任何错误。但无论如何,这是您处理自定义流程布局的方式。