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 的末尾
iOS 9 UICollectionView 水平重新加载数据不起作用