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

Posted

技术标签:

【中文标题】UICollectionView 水平滚动延迟加载单元格【英文标题】:UICollectionView Horizontal Scrollling Delay loading cells 【发布时间】:2015-03-23 20:44:28 【问题描述】:

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

视图控制器

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 单元格类

@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;

【问题讨论】:

你能添加关于你的集合视图数据源和你的自定义集合视图单元的代码吗? @kuley 添加了更多代码! 当您说加载延迟时,您的意思是加载需要时间,还是只需要进一步滚动才能看到下一个单元格? @Kujey 主要是你必须进一步滚动 【参考方案1】:

试试这个方法:

@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:我只是写了,没有测试它。我希望它不包含任何错误。但无论如何,这是您应该处理自定义流布局的方式。

【讨论】:

以上是关于UICollectionView 水平滚动延迟加载单元格的主要内容,如果未能解决你的问题,请参考以下文章

如何检测滚动到水平 UICollectionView 的末尾

延迟加载 UICollectionView 图像

iOS 9 UICollectionView 水平重新加载数据不起作用

UIcollectionView 具有缓慢的图像加载和滚动

UICollectionView 在滚动 Alamofire 时将图像加载到错误的位置

页面加载时滚动后如何访问 UICollectionView 中的特定单元格?