您的位置:首页 > 其它

蘑菇街瀑布流的实现

2015-11-01 14:44 239 查看
蘑菇街利用UIScrollView(基本和tableView一样实现重用) 实现思想为第一次或刷新时计算frame,同时用一个数组存放frame**计算思路。**用一个c语言数组存放每一列图片的最大Y值每一个cell计算Y值时都算出哪一列的y值最小,计算出来并把此frame设置为对应列的最大y值全部算完计算contentsizeUIScrollView比较特殊,layoutsubviews在每次滚动时都会调用,所以利用这点可以在layoutsubviews里让cell显示出来首先需要一个字典(dispalayCells)存放当前显示在屏幕上的cell还需要一个集合(reusableSet)存放创建过得的cell(即充当缓存池作用)遍历frame数组计算每个frame是否显示在屏幕上当CGRectGetMaxY(frame)>self.contentOffset.y&&CGRectGetMinY(frame)<self.contentOffset.y+self.frame.size.height时即显示在屏幕上,在判断dispalayCells中有没有此cell,如果为nil则调用数据源方法创建(数据源会像充当缓存池的集合中找,找不到符合条件的才会创建),加到scrollview上,并加入到dispalayCells中,并设置frame如果没显示在屏幕上,也判断之前是否显示在屏幕上,即dispalayCells中有没有此cell,如果为真,则把它从scrollview中删除,并从dispalayCells中删除,并加入到reusableSet中,每次刷新都需要把存放frame的数组和dispalayCells
和reusableSet清空,还有把所有cell移除,因为有可能cell全部变了,所以必须移除,时间处理即判断当前显示的cell的frame是否包含触摸点,谁包含即谁点击

代码如下

-(void)reloadData{
//没吃重新刷新都清除所有数据 [self.displayCells.allValues makeObjectsPerformSelector:@selector(removeFromSuperview)];
[self.displayCells removeAllObjects]; [self.cellFrames removeAllObjects];
[self.reusableCells removeAllObjects]; //总个数
NSInteger numbersOfCell=[self.dataSource numbersOfCellsInWaterFlowView:self]; //总列数
NSInteger numbersOfColumn=[self numbersOfColumn]; CGFloat marginLeft=[self marginWithType:LSWaterFlowViewMarginTypeLeft];
CGFloat marginTop=[self marginWithType:LSWaterFlowViewMarginTypeTop]; CGFloat marginRow=[self marginWithType:LSWaterFlowViewMarginTypeRow];
CGFloat marginCol=[self marginWithType:LSWaterFlowViewMarginTypeColumn]; CGFloat cellW=[self cellWidth];
//定义一个c语言的存放每一列的最大Y值 CGFloat columnMaxY[numbersOfColumn];
//开始全部设置为0.0 for (int i=0; i<numbersOfColumn; i++) {
columnMaxY[i]=0.0; }
for (int i=0; i<numbersOfCell; i++) { //假设第一列为最小Y
NSInteger column=0; // 列号为0 CGFloat maxColumnY=columnMaxY[column];
for (int j=1; j<numbersOfColumn; j++) { if (maxColumnY>columnMaxY[j]) {
maxColumnY=columnMaxY[j]; column=j;
} } CGFloat cellY;
CGFloat cellX=marginLeft+(cellW+marginCol)*column; CGFloat cellH=[self cellHeightAtIndex:i];
//第一次为0,所以得加上顶部边距 if (maxColumnY==0.0) {
cellY=marginTop; }else{
cellY=maxColumnY+marginRow; }
CGRect frame=CGRectMake(cellX, cellY, cellW, cellH); columnMaxY[column]=CGRectGetMaxY(frame); [self.cellFrames addObject:[NSValue valueWithCGRect:frame]];
} //计算contentSize CGFloat contentH=columnMaxY[0]; for (int i=1; i<numbersOfColumn;
i++) { if (contentH<columnMaxY[i]) { contentH=columnMaxY[i]; }
} CGFloat marginBottom=[self marginWithType:LSWaterFlowViewMarginTypeBottom]; contentH+=marginBottom;
self.contentSize=CGSizeMake(0, contentH);}-(void)layoutSubviews{
[super layoutSubviews]; int count=self.cellFrames.count;
for (int i=0; i<count; i++) { //在屏幕上
LSWaterFlowViewCell *cell=self.displayCells[@(i)]; CGRect frame=[self.cellFrames[i] CGRectValue];
if([self isOnScreenWithRect:frame]){ if (cell==nil) {
cell=[self.dataSource waterFlowView:self cellForIndex:i]; cell.frame= frame;
[self addSubview:cell]; //存放到记录显示在屏幕上的cell字典中
self.displayCells[@(i)]=cell; }
} else{//不在屏幕上
if (cell) { //从字典中移除同时移除scrolllview
[self.displayCells removeObjectForKey:@(i)]; [cell removeFromSuperview];
//加入缓存池 [self.reusableCells addObject:cell];
} } }}-(id)dequeueReusableCellWithIdentifier:(NSString
*)identifier{
__block LSWaterFlowViewCell *reuseCell=nil; [self.reusableCells enumerateObjectsUsingBlock:^(LSWaterFlowViewCell * cell, BOOL * _Nonnull
stop) { if ([cell.identifier isEqualToString:identifier]) {
reuseCell=cell; *stop=YES;
} }]; if (reuseCell)
{ [self.reusableCells removeObject:reuseCell];
} return reuseCell;}//计算是否在屏幕上-(BOOL)isOnScreenWithRect:(CGRect)rect{
return (CGRectGetMaxY(rect)>self.contentOffset.y)&&(CGRectGetMinY(rect)<self.contentOffset.y+self.frame.size.height);}-(void)touchesEnded:(NSSet<UITouch
*> *)touches withEvent:(UIEvent *)event{
UITouch *touch=[touches anyObject]; CGPoint point=[touch locationInView:self];
__block NSNumber *selectedIndex=nil; [self.displayCells enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, LSWaterFlowViewCell* cell,
BOOL * _Nonnull stop) { if (CGRectContainsPoint(cell.frame, point)) {
selectedIndex=key; *stop=YES;}
}]; if (selectedIndex) { if ([self.myDelegate respondsToSelector:@selector(waterFlowView:didSelectedAtIndex:)]) {
[self.myDelegate waterFlowView:self didSelectedAtIndex:selectedIndex.integerValue]; } }


源代码地址http://download.csdn.net/detail/itiapp_home/9231281






内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: