UI基础__UICollectionView__瀑布流

本文重点记录使用collectionView做九宫格、瀑布流

创建九宫格三种情况:

1.使用storyboard
2.使用xib
3.纯代码实现

编码过程中的注意点记录:

UIImageView *imgView=[[UIImageView alloc]init];
    //从父容器获取子控件
    imgView=cell.contentView.subviews[0];
    XYappData *data=self.arr[indexPath.item];
    imgView.image=[UIImage imageNamed:data.icon];
    UILabel *lab=[[UILabel alloc]init];
    lab=cell.contentView.subviews[2];
    lab.text=data.name;
    return cell;
根据具体的xib文件来设置itemSize
    //instantiateWithOwner可以读取指定的xib文件,将xib文件中所有的view返回存储到数组中,同时设置top view
    XYAppCell *cell=[[nib instantiateWithOwner:self options:nil] lastObject];
    //设置布局属性
    self.layout.itemSize=CGSizeMake(cell.frame.size.width, cell.frame.size.height);
使用xib注册cell
    //1.名称:区分大小写,不要扩展名
    //2.如果是nil,则默认就是mainBundle
    UINib *nib=[UINib nibWithNibName:@"XYAppCell" bundle:nil];
    [self.collectionView registerNib:nib forCellWithReuseIdentifier:@"app"];
    XYAppCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:@"app" forIndexPath:indexPath];
    cell.app=self.apps[indexPath.item];
    return cell;
设置header和footer
//当前的视图能够看到头部view或者底部view的时候就会调用这个方法来创建头部或者底部view
- (UICollectionReusableView *) collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
    NSString *ID=@"header";
    if (kind==UICollectionElementKindSectionFooter) {
        ID=@"footer";
    }
    UICollectionReusableView *userView=[collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:ID
        forIndexPath:indexPath];
    //NSLog(@"%@",kind);
    return  userView;
}

瀑布流的制作

关键点:
1.设置底部视图的时候,需要点是把footer进行封装,有利于对其控制,

//设置底部视图
-(UICollectionReusableView*)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath{
    XYshopFooter *footer=nil;
    if (kind==UICollectionElementKindSectionFooter) {
    footer=[collectionView dequeueReusableSupplementaryViewOfKind: kind withReuseIdentifier:@"footer" forIndexPath:indexPath];
//        NSLog(@"footer");
        //让菊花开始转动
        [footer.grayView startAnimating];
        //延迟操作,加载数据,
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            //加载
            [self loadData];

            //刷新界面
            [self.collectionView reloadData];
        });

          return footer;
            }

    return nil;
}
2.把布局属性进行封装,进行frame值的获取

注意:在生成底部视图的时候,需要在下次加载之前删除一个footer ,不然会出现两个footer
将i改为从self.attArr.count开始,可以避免在数据刷新的时候上次的数据为空
若实现全部的自动布局,将self.attArr.count清空,并在此从0开始布局,这样在换屏的时候可以从新布局,实现效果

@interface XYlayout()
//存储cell的frame值的数组
@property(nonatomic,strong)NSMutableArray *attArr;
//存储每一列的
@property(nonatomic,strong)NSMutableDictionary *mutYDic;
@end

@implementation XYlayout
-(NSMutableArray *)attArr{
    if (_attArr==nil) {
        _attArr=[NSMutableArray array];
    }
    return _attArr;
}
//初始化Y值,从顶部的位置开始
-(NSMutableDictionary *)mutYDic{
    if (_mutYDic==nil) {
        _mutYDic=[NSMutableDictionary dictionary];
        for (int i=0; i<self.countLine; i++) {
            NSString *key=[NSString stringWithFormat:@"%d",i];
            _mutYDic[key]=@(self.sectionInset.top);
        }
    }
    return _mutYDic;
}
//每次布局的时候调用该方法
-(void)prepareLayout{
    NSLog(@"preparelayout");
    //删除底部的值,不然会出现两个footer
    [self.attArr removeLastObject];
    NSInteger total=[self.collectionView numberOfItemsInSection:0];
    //将i改为从self.attArr.count开始,可以避免在数据刷新的时候上次的数据为空
    //若实现全部的自动布局,将self.attArr.count清空,并在此从0开始布局
    self.mutYDic=nil;
    for (NSInteger i=0; i<total; i++) {
        //确定某个位置上
        NSIndexPath *path=[NSIndexPath indexPathForItem:i inSection:0];
        UICollectionViewLayoutAttributes *att=[UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:path];

        //计算宽
        CGFloat width=(self.collectionView.bounds.size.width-self.sectionInset.left-self.sectionInset.right-self.minimumInteritemSpacing*(self.countLine-1))/(self.countLine);
        //计算高,代理实现
//        XYshoping *shop=self.shop[i];
//        CGFloat height=(width*shop.height)/shop.width;
        CGFloat height= [self.delegate heightForIndex:i withWidth:width];
        //计算X
//        CGFloat x=self.sectionInset.left+(width+self.minimumInteritemSpacing)*(i%self.countLine);
        NSString *minCol=[self minCol];
        CGFloat x=self.sectionInset.left+(width+self.minimumInteritemSpacing)*[minCol floatValue];
        //计算Y
//        NSString *col=[NSString stringWithFormat:@"%ld",i%self.countLine];
        CGFloat y=[self.mutYDic[minCol] floatValue];
        att.frame=CGRectMake(x, y, width, height);
        //重置y
//        y=[@(y+height+self.minimumLineSpacing) floatValue];
        self.mutYDic[minCol]=@(y+height+self.minimumLineSpacing);
        //将att加入到数组中
        [self.attArr addObject:att];
    }
    //设置底部frame值
    NSIndexPath *path=[NSIndexPath indexPathForItem:0 inSection:0];
    UICollectionViewLayoutAttributes *footer=[UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionFooter withIndexPath:path];
    NSString *maxCol=[self maxCol];
    footer.frame=CGRectMake(0, [self.mutYDic[maxCol] floatValue], self.collectionView.bounds.size.width, self.footerReferenceSize.height);
    [self.attArr addObject:footer];

}
//确定滚动的范围
-(CGSize)collectionViewContentSize{
     NSString *maxCol=[self maxCol];
    CGSize size=CGSizeMake(self.collectionView.bounds.size.width, [self.mutYDic[maxCol] floatValue]+self.footerReferenceSize.height);
    return size;
}
//比较最大的Y值
-(NSString*)maxCol{
    NSString *maxCol=@"0";
    for (int i=0; i<self.countLine; i++) {
        NSString *col=[NSString stringWithFormat:@"%d",i];
        if ([self.mutYDic[col] floatValue]>[self.mutYDic[maxCol] floatValue]) {
            maxCol=col;
        }
    }

    return maxCol;
}
//比较最小的Y值
-(NSString*)minCol{
    NSString *minCol=@"0";
    for (int i=0; i<self.countLine; i++) {
        NSString *col=[NSString stringWithFormat:@"%d",i];
        if ([self.mutYDic[col] floatValue]<[self.mutYDic[minCol] floatValue]) {
            minCol=col;
        }
    }

    return minCol;
}
//返回数组
-(NSArray<UICollectionViewLayoutAttributes*>*)layoutAttributesForElementsInRect:(CGRect)rect{
    [super layoutAttributesForElementsInRect:rect];
    return self.attArr;
}
@end
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值