zoukankan      html  css  js  c++  java
  • 瀑布流的实现全过程

    1.创建继承自UICollectionViewCell的l类ImageCell,将imageView和label声明成属性,然后重写- initWithFrame:方法,初始化内部控件

    - (id)initWithFrame:(CGRect)frame

    {

        self = [super initWithFrame:frame];

        if (self) {

            [self setupSubviews];

        }

        return self;

    }

     

    - (void)setupSubviews

    {

        _imageView = [[UIImageView allocinitWithFrame:self.bounds];

        [self.contentView addSubview:_imageView];

        _numberLabel = [[UILabel allocinitWithFrame:CGRectMake(005020)];

        [_imageView addSubview:_numberLabel];

        

    }

    - (void)layoutSubviews

    {

        [super layoutSubviews];

        

        _imageView.frame = self.bounds;

    }

    2:创建模型Model类,声明好属性

    - (void)setValue:(id)value forUndefinedKey:(NSString *)key

    {

    //    if ([key isEqualToString:@"id"]) {

    //        self.ID = value;

    }

     

    - (void)setValue:(id)value forKey:(NSString *)key

    {

        [super setValue:value forKey:key];

        

        if ([key isEqualToString:@"width"]) {

            

            self.width = [value floatValue];

        }

        

        if ([key isEqualToString:@"height"]) {

            

            self.height = [value floatValue];

        }

        

    }

     

    3:创建一个瀑布流的布局类继承自NSObject,然后设置代理协议,并声明属性  

     

    4:在这个自定义的WaterFlowLayout中实现各种布局方法

    //存放每一列的高度

    @property (nonatomic, retain) NSMutableArray *columnHeightsArray;

     

    //存放 每一个item 属性 包含 frame以及下标

    @property (nonatomic, retain) NSMutableArray *attributesArray;

     @end

     

    //获取最小高度的方法

    - (CGFloat)minHeight

    {

        CGFloat min = 100000;

        for (NSNumber *height in _columnHeightsArray) {

            CGFloat h = [height floatValue];

            if (min > h) {

                min = h;

            }

        }

        return min;

    }

     

    //获取最大值

    - (CGFloat)maxHeight

    {

        CGFloat max = 0;

        for (NSNumber *height in _columnHeightsArray) {

            CGFloat h = [height floatValue];

            if (max < h) {

                max = h;

            }

        }

        return max;

    }

    //最小高度的下标

    - (NSUInteger)indexOfMinHeight

    {

        NSUInteger index = 0;

        for (int i = 0; i < [_columnHeightsArray count]; i ++) {

            CGFloat height = [_columnHeightsArray[i] floatValue];

            if (height == [self minHeight]) {

                index = i;

                return index;

            }

        }

        return index;

    }

     

    //重写父类的布局方法

    - (void)prepareLayout

    {

        [super prepareLayout];

        

        _attributesArray = [[NSMutableArray alloc] init];

        

        _columnHeightsArray = [[NSMutableArray alloc] initWithCapacity:self.numberOfColumn];

        

        //给列高数组里面的对象赋初值

        for (int i = 0; i < self.numberOfColumn; i ++) {

            [_columnHeightsArray addObject:@0.0];

        }

        

        CGFloat totalWidth = self.collectionView.frame.size.width;

        

        //创建 每个item frame中的xy

        CGFloat x = 0;

        CGFloat y = 0;

        

        NSUInteger itemCount = [self.collectionView numberOfItemsInSection:0];

        

        for (int i = 0; i < itemCount; i ++) {

            //得到集合视图中 列间隙的个数

            NSUInteger numberOfSpace = self.numberOfColumn - 1;

            

            //代理对象执行代理方法,得到 item之间的间隙大小

            CGFloat spaceWidth = [_delegate collectionView:self.collectionView layout:self minimumInteritemSpacingForSectionAtIndex:0];

            

            //求每列的宽度,也就是每个itemwidth

            CGFloat width = (totalWidth - spaceWidth * numberOfSpace) / self.numberOfColumn;

            

            

            //获取每一个itemSize的大小

            NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];

            

            //数据中原始图片大小

            CGSize imageSize = [_delegate collectionView:self.collectionView layout:self sizeForItemAtIndexPath:indexPath];

        

            //通过 约分公式得到固定宽之后的高度是多少

            CGFloat height = width * imageSize.height / imageSize.width;

            

            

            UICollectionViewLayoutAttributes *attribute = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];

            

            //记录每一个item的大小和位置

            attribute.frame = CGRectMake(x, y, width, height);

            

            //数组保存每个item的位置信息

            [_attributesArray addObject:attribute];

            

            NSLog(@"item = %d",i);

            NSLog(@"x = %.2f y = %.2f width = %.2f height = %.2f",x,y,width,height);

            

            //求列高最小的那一列的下标

            NSUInteger minHeightIndex = [self indexOfMinHeight];

            

            //求出最小列的高度

            CGFloat minHeight = [_columnHeightsArray[minHeightIndex] floatValue];

            

            //求出行高

            CGFloat lineHeight = [_delegate collectionView:self.collectionView layout:self minimumLineSpacingForSectionAtIndex:0];

            

            //上一次总的列高 加上 行高 加上新加上的itemheight,才是现在这一列的总高度

            //minHeight为最小列现在的高度

            //lineHeight为行间距

            //height为新加的item的高

            _columnHeightsArray[minHeightIndex] = [NSNumber numberWithFloat:minHeight + lineHeight + height];

            

            //重新算最小列高的下标

            minHeightIndex = [self indexOfMinHeight];

            

            //算下一次新加的itemxy

            x = (spaceWidth + width) * minHeightIndex;

            

            y = [self minHeight];

        }

    }

     

    //重写这个方法,可以返回集合视图的总高度

    - (CGSize)collectionViewContentSize

    {

        return CGSizeMake(self.collectionView.frame.size.width, [self maxHeight]);

    }

     

    //这个方法不写 集合视图显示不出来,这个方法是将保存的每个item的信息告诉集合视图,进行显示。

    - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect

    {

        return _attributesArray;

    }

     //这是重写的一个布局方法,和系统的布局方法就不一样了,然后就可以将这个类当成系统的UICollectionFlowLayout相同的方法使用了

     

    #pragma mark -----WaterFlowDelegate-----

    - (CGSize)collectionView:(UICollectionView *)collectionView layout:(WaterFlowLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath

    {

        Model *model = _dataArray[indexPath.row];

        return CGSizeMake(model.width, model.height);

    }

     

    - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(WaterFlowLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section

    {

        return UIEdgeInsetsMake(0, 0, 0, 0);

    }

     

    - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(WaterFlowLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section

    {

        return 10;

    }

     

     

    - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(WaterFlowLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section

    {

        return 5;

    }

     

    - (void)viewDidLoad {

        [super viewDidLoad];

    //bundle文件中读取原始数据  json格式

        NSString * filePath = [[NSBundle mainBundle] pathForResource:@"Data" ofType:@"json"];

        NSData * sourceData = [NSData dataWithContentsOfFile:filePath];

        

        //解析

        NSArray * sourceArray = [NSJSONSerialization JSONObjectWithData:sourceData options:NSJSONReadingMutableContainers error:nil];

        

        self.dataArray = [NSMutableArray arrayWithCapacity:40];

        

        //处理数据

        for (NSDictionary * dic in sourceArray) {

            

            Model * m = [[Model alloc] init];

            [m setValuesForKeysWithDictionary:dic];

            [_dataArray addObject:m];

            [m release];

        }

        

        //创建布局对象

        WaterFlowLayout *flowLayout = [[WaterFlowLayout alloc] init];

        

        flowLayout.delegate = self;

        flowLayout.numberOfColumn = 3;

        

        //创建集合视图

        UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:[UIScreen mainScreen].bounds collectionViewLayout:flowLayout];

        collectionView.backgroundColor = [UIColor whiteColor];

        

        collectionView.delegate = self;

        collectionView.dataSource = self;

        

        //collectionView注册一个cell

        [collectionView registerClass:[ImageCell class] forCellWithReuseIdentifier:@"aaa"];

        

        [self.view addSubview:collectionView];

        

        [collectionView release];

        [flowLayout release];

        

        // Do any additional setup after loading the view, typically from a nib.

    }

     

    #pragma mark -----DataSource-----

    - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section

    {

        return [_dataArray count];

    }

     

    // The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseIdentifier:forIndexPath:

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

    {

        ImageCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"aaa" forIndexPath:indexPath];

        

        

        //获取模型

        Model *model = self.dataArray[indexPath.row];

        

        NSURL *url = [NSURL URLWithString:model.thumbURL];

        

        [cell.imageView sd_setImageWithURL:url placeholderImage:[UIImage imageNamed:@"屏幕快照 2016-02-25 下午4.17.55.png"]];

        

    //    cell.imageView.image = [UIImage imageNamed:@"8.png"];

        

    //    cell.numberLabel.text = [NSString stringWithFormat:@"%ld",indexPath.row];

        

        return cell;

    }

    这里需要用到一个类SDWebImage的文件,将它上传到了我的github上。

     

     

     

     

  • 相关阅读:
    httpClient模拟浏览器发请求
    中文字符所占字节
    eclipse代码左虚线对齐设置
    git 几款好用的客户端工具
    github快速入门(一)
    eclipse插件开发(一)
    SpringMVC解决跨域的两种方案
    SpringMVC SessionAttributes 简述
    关于Spring的HibernateTemplate的findByExample方法使用时的一点注意。
    Windows10 Ubuntu bash 配置 LAMP+JDK+Tomcat
  • 原文地址:https://www.cnblogs.com/arenouba/p/5217838.html
Copyright © 2011-2022 走看看