zoukankan      html  css  js  c++  java
  • UICollectionView

      1 #import "ViewController.h"
      2 #import "Model.h"
      3 #import "MyCollectionViewCell.h"
      4 #import "UIImageView+WebCache.h"
      5 #import "CustomLayout.h"
      6 @interface ViewController ()<UICollectionViewDataSource,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout,CustomLayoutDelegate>
      7 
      8 ///声明一个数组用于存储model的数据类
      9 @property (nonatomic,strong)NSMutableArray *saveModelArray;
     10 
     11 @end
     12 
     13 @implementation ViewController
     14 
     15 - (void)viewDidLoad {
     16     [super viewDidLoad];
     17     // Do any additional setup after loading the view, typically from a nib.
     18     
     19     //首先知道要显示的数据是数组套字典的格式
     20     //创建Model类用于处理数据
     21     //解析数据
     22     [self analysizeData];
     23     
     24     //创建UICollectionView
     25     [self createCollectionView];
     26     
     27     //现在效果图片发虚,不是我们真正想要的一个效果,用户体验相当不好,所以说我们需要自定义flowLayout显示图片
     28     
     29     
     30     
     31     
     32     
     33     
     34 }
     35 
     36 #pragma mark - 创建UICollectionView(在创建此视图之前必须设置UICollectionViewFlowLayout进行布局)
     37 - (void)createCollectionView{
     38     /*
     39     //1.创建UICollectionViewFlowLayout
     40     UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
     41     //设置行间距
     42     layout.minimumLineSpacing = 10;
     43     //设置列间距的
     44     layout.minimumInteritemSpacing = 10;
     45     //设置item大小的
     46     layout.itemSize = CGSizeMake(100, 100);
     47     //设置视图距离上左下右的一个距离
     48     layout.sectionInset = UIEdgeInsetsMake(10, 10, 10, 10);
     49     
     50     //设置头部和尾部的高度
     51     layout.headerReferenceSize = CGSizeMake(10, 10);
     52     layout.footerReferenceSize = CGSizeMake(10, 10);
     53     //设置滚动方向
     54     layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
     55      */
     56     
     57     //使用自定义的layout进行布局
     58     CustomLayout *layout = [[CustomLayout alloc] init];
     59     layout.delegate = self;
     60     
     61     //设置布局的一个宽度
     62     CGFloat width = ([[UIScreen mainScreen] bounds].size.width - 40)/3;
     63     //设置item的一个大小
     64     layout.itemSize = CGSizeMake(width, width);
     65     //设置距离上下左右的间距
     66     layout.sectionInsets = UIEdgeInsetsMake(10, 10, 10, 10);
     67 
     68     layout.insertItemSpacing = 10;
     69     layout.numberOfColumns = 3;
     70     
     71     
     72     //创建UICollectionView
     73     UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:[[UIScreen mainScreen] bounds] collectionViewLayout:layout];
     74     collectionView.delegate = self;
     75     collectionView.dataSource = self;
     76     collectionView.backgroundColor = [UIColor whiteColor];
     77     [self.view addSubview:collectionView];
     78     
     79     
     80     //千万不要忘记注册cell
     81     [collectionView registerClass:[MyCollectionViewCell class] forCellWithReuseIdentifier:@"MyCollectionViewCell"];
     82     
     83     
     84     
     85 }
     86 
     87 //设置item的高度
     88 - (CGFloat)heightItemForIndexpath:(NSIndexPath *)indexPath{
     89     
     90     //获取model的对象
     91     Model *model = _saveModelArray[indexPath.row];
     92     
     93     CGFloat width = ([UIScreen mainScreen].bounds.size.width - 40)/3;
     94     
     95     CGFloat height = (model.height / model.width) * width;
     96     
     97     return height;
     98     
     99 }
    100 
    101 #pragma mark - 实现相关的代理方法
    102 //设置item的数量
    103 - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
    104     
    105     return _saveModelArray.count;
    106 }
    107 //设置区的个数
    108 - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
    109     return 1;
    110 }
    111 //设置cell的一个样式
    112 - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    113     
    114     //重用池里取出与之对应的cell
    115     MyCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"MyCollectionViewCell" forIndexPath:indexPath];
    116     cell.backgroundColor = [UIColor whiteColor];
    117     
    118     //设置cell上显示的内容
    119     //首先取出model对象
    120     Model *model = _saveModelArray[indexPath.row];
    121     //然后将model对象中字符串类型的url转换成NSURL类型,以备使用
    122     NSURL *url = [NSURL URLWithString:model.thumbURL];
    123     
    124     [cell.imageView sd_setImageWithURL:url placeholderImage:[UIImage imageNamed:@"placeHoderImage.png"]];
    125     
    126     
    127     
    128     
    129     return cell;
    130     
    131 }
    132 
    133 #pragma mark - 解析数据
    134 -  (void)analysizeData{
    135     
    136     //读取文件
    137     NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Data" ofType:@"json"];
    138     
    139     //因为准备的数据是json数据,所以解析要遵循json数据的解析方式
    140     NSData *data = [NSData dataWithContentsOfFile:filePath];
    141     NSMutableArray *array = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
    142     //给数组初始化
    143     self.saveModelArray = [NSMutableArray array];
    144     //使用for..in遍历取出数组中的字典,然后赋值给model,存储起来
    145     for (NSDictionary *dic in array) {
    146         //使用kvc给model赋值
    147         Model *model = [[Model alloc] init];
    148         [model setValuesForKeysWithDictionary:dic];
    149         [_saveModelArray addObject:model];
    150     }
    151     
    152     NSLog(@"%@",_saveModelArray);   
    153    
    154     
    155 }
    156 
    157 - (void)didReceiveMemoryWarning {
    158     [super didReceiveMemoryWarning];
    159     // Dispose of any resources that can be recreated.
    160 }
    161 
    162 @end
     1 #import <UIKit/UIKit.h>
     2 
     3 //第一步:创建继承与UICollectionViewLayout的类,声明一个协议,只是先一个代理方法
     4 
     5 @protocol CustomLayoutDelegate <NSObject>
     6 
     7 //用于获取item的高度
     8 - (CGFloat)heightItemForIndexpath:(NSIndexPath *)indexPath;
     9 
    10 @end
    11 
    12 
    13 @interface CustomLayout : UICollectionViewLayout
    14 
    15 //第二步:设置相关的属性(设置外部可以访问到的)
    16 ///item的大小
    17 @property (nonatomic,assign)CGSize itemSize;
    18 ///设置collectionView的内间距
    19 @property (nonatomic,assign)UIEdgeInsets sectionInsets;
    20 
    21 ///item间距的设置
    22 @property (nonatomic,assign)CGFloat insertItemSpacing;
    23 ///列的数目
    24 @property (nonatomic,assign)NSInteger numberOfColumns;
    25 
    26 ///代理
    27 @property (nonatomic,weak)id <CustomLayoutDelegate>delegate;
    28 
    29 
    30 
    31 
    32 @end
      1 #import "CustomLayout.h"
      2 
      3 //第三步:声明一些不暴露在外部使用的属性,只有当前文件可以使用的
      4 @interface CustomLayout ()
      5 
      6 ///获取item的总数量
      7 @property (nonatomic,assign)NSInteger numberOfItems;
      8 
      9 ///存储每一列高度的数组
     10 @property (nonatomic,strong)NSMutableArray *columnHeights;
     11 
     12 ///存储距离上下左右的数组(x,y,w,h)
     13 @property (nonatomic,strong)NSMutableArray *itemAtrributes;
     14 
     15 ///存储item的x值
     16 @property (nonatomic,assign)CGFloat detalX;
     17 
     18 ///存储item相对应的y值
     19 @property (nonatomic,assign)CGFloat detalY;
     20 
     21 ///记录最短的列
     22 @property (nonatomic,assign)NSInteger shortestIndex;
     23 
     24 ///获取最长列的索引值
     25 - (NSInteger)p_indexForLongestColumn;
     26 
     27 ///获取最短列的索引值
     28 - (NSInteger)p_indexForShortestColumn;
     29 
     30 
     31 
     32 @end
     33 
     34 @implementation CustomLayout
     35 
     36 //第四步:懒加载一些数据源
     37 - (NSMutableArray *)columnHeights{
     38     if (!_columnHeights) {
     39         self.columnHeights = [NSMutableArray array];
     40     }
     41     
     42     return _columnHeights;
     43 }
     44 
     45 - (NSMutableArray *)itemAtrributes{
     46     if (!_itemAtrributes) {
     47         self.itemAtrributes = [NSMutableArray array];
     48     }
     49     
     50     return _itemAtrributes;
     51 }
     52 
     53 //第五步:实现获取最长列的方法
     54 - (NSInteger)p_indexForLongestColumn{
     55     //定义一个变量用于记录哪一列是最长列
     56     NSInteger longestIndex = 0;
     57     //当前最长列的一个高度
     58     CGFloat longestHeight = 0;
     59 
     60     //遍历数组取出相关数据然后返回
     61     for (int i = 0; i < self.numberOfColumns; i++) {
     62         //获取相关的一个高度
     63         CGFloat currentHeight = [self.columnHeights[i] floatValue];
     64         
     65         //判断选出最高的一个高度
     66         if (currentHeight > longestHeight) {
     67             longestHeight = currentHeight;
     68             longestIndex = i;
     69         }
     70     }
     71     
     72     return longestIndex;
     73 
     74 }
     75 
     76 //第六步:实现获取最短列的一个方法
     77 - (NSInteger)p_indexForShortestColumn{
     78     
     79     //记录索引
     80     NSInteger shortestIndex = 0;
     81 
     82     //记录最小的一个高度
     83     CGFloat shortestHeight = MAXFLOAT;
     84     
     85     //遍历赋值取出最小的下标
     86     for (int i = 0; i < self.numberOfColumns; i++) {
     87         //获取一个当前高度
     88         CGFloat currentHeight = [self.columnHeights[i] floatValue];
     89         if (currentHeight < shortestHeight) {
     90             shortestHeight = currentHeight;
     91             shortestIndex = i;
     92         }
     93     }
     94     return shortestIndex;
     95     
     96 }
     97 
     98 //第七步:实现给每一列添加top高度
     99 - (void)addHeightWithColumns{
    100     
    101     //遍历取出相关的数值
    102     for (int i = 0;i < self.numberOfColumns;i++){
    103         self.columnHeights[i] = @(self.sectionInsets.top);
    104     }
    105 
    106 }
    107 
    108 //第八步:查找最短的列,并设置相关属性
    109 // 查找最短的列,并设置相关属性
    110 - (void)searchShortColumns
    111 {
    112     _shortestIndex = [self p_indexForShortestColumn];
    113     CGFloat shortestH = [self.columnHeights[_shortestIndex] floatValue];
    114     // 计算x值:内边距left + (item宽 + item的间距)* 索引
    115     self.detalX = self.sectionInsets.left + (self.itemSize.width +self.insertItemSpacing) * _shortestIndex;
    116     // 计算y值
    117     self.detalY = shortestH + self.insertItemSpacing;
    118     
    119 }
    120 
    121 //第九步:查找最短的列,并设置相关属性
    122 // 设置属性和frame
    123 - (void)setFrame:(NSIndexPath *)indexPath
    124 {
    125     // 设置属性
    126     UICollectionViewLayoutAttributes *layoutArr = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
    127     // 保存item的高
    128     CGFloat itemHeight = 0;
    129     if (_delegate && [_delegate respondsToSelector:@selector(heightItemForIndexpath:)]) {
    130         // 使用代理方法获取item的高
    131         itemHeight = [_delegate heightItemForIndexpath:indexPath];
    132     }
    133     // 设置frame
    134     layoutArr.frame = CGRectMake(_detalX, _detalY, self.itemSize.width, itemHeight);
    135     // 放入数组
    136     [self.itemAtrributes addObject:layoutArr];
    137     // 更新高度
    138     self.columnHeights[_shortestIndex] = @(_detalY +itemHeight);
    139 }
    140 
    141 //步骤十:在实现文件中必须要的实现三个方法
    142 /*
    143  - (void)prepareLayout 准备布局方法,在每个UICollectionViewLayout将要被使用的时候调用这个方法
    144  
    145  - (CGSize)collectionViewContentSize  计算每个item的大小,会走很多次
    146  
    147  - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect 返回所有的item的位置信息和大小
    148  */
    149 
    150 //第十一步:实现准备布局的代理方法
    151 // 准备布局
    152 - (void)prepareLayout
    153 {
    154     // 调用父类布局
    155     [super prepareLayout];
    156     [self addHeightWithColumns];
    157     // 获取item的数量
    158     self.numberOfItems = [self.collectionView numberOfItemsInSection:0];
    159     // 为每一个item设置frame和indexPath
    160     for(int i = 0;i < self.numberOfItems;i++)
    161     {
    162         // 查找最短的列,并设置相关属性
    163         [self searchShortColumns];
    164         // 设置indexPath
    165         NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
    166         [self setFrame:indexPath];
    167     }
    168 }
    169 
    170 //第十二步:计算每个item的大小
    171 // 计算每个item的大小
    172 - (CGSize)collectionViewContentSize
    173 {
    174     // 获取最长高度索引
    175     NSInteger longerstIndex = [self p_indexForLongestColumn];
    176     // 通过索引获取高度
    177     CGFloat longestH = [self.columnHeights[longerstIndex] floatValue];
    178     // 获取collectionView的Size
    179     CGSize contentSize = self.collectionView.frame.size;
    180     // 最大高度+bottom
    181     contentSize.height = longestH + self.sectionInsets.bottom;
    182     return contentSize;
    183 }
    184 
    185 //第十三步:将每个item的布局返回
    186 // 返回每一个item的布局
    187 - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
    188 {
    189     // 返回每一个item的Attribute
    190     return self.itemAtrributes;
    191     
    192 }
    193 
    194 
    195 
    196 @end
    1 #import <UIKit/UIKit.h>
    2 
    3 @interface MyCollectionViewCell : UICollectionViewCell
    4 ///用来展示图片的控件
    5 @property (nonatomic,strong)UIImageView *imageView;
    6 
    7 @end
     1 #import "MyCollectionViewCell.h"
     2 
     3 @implementation MyCollectionViewCell
     4 
     5 //重写初始化方法
     6 - (instancetype)initWithFrame:(CGRect)frame{
     7     self = [super initWithFrame:frame];
     8     if (self) {
     9         self.imageView = [[UIImageView alloc] init];
    10         [self.contentView addSubview:self.imageView];
    11     }
    12     return self;
    13 }
    14 //设置控件的frame
    15 - (void)layoutSubviews{
    16     [super layoutSubviews];
    17     self.imageView.frame = self.bounds;
    18 }
    19 
    20 @end
     1 #import <Foundation/Foundation.h>
     2 
     3 @interface Model : NSObject
     4 
     5 ///图片的网址
     6 @property (nonatomic,strong)NSString *thumbURL;
     7 
     8 ///图片的宽
     9 @property (nonatomic,assign)NSInteger width;
    10 
    11 ///图片的高度
    12 @property (nonatomic,assign)NSInteger height;
    13 
    14 @end
    1 #import "Model.h"
    2 
    3 @implementation Model
    4 
    5 - (void)setValue:(id)value forUndefinedKey:(NSString *)key{
    6     
    7 }
    8 
    9 @end
  • 相关阅读:
    zoj 3820 Building Fire Stations(树上乱搞)
    wxWidgets+wxSmith版电子词典
    Android异步载入全解析之IntentService
    HDU 3832 Earth Hour(最短路)
    Android 应用程序窗口显示状态操作(requestWindowFeature()的应用)
    HighChart学习-更新数据data Series与重绘
    sar使用说明
    xcode多target
    Creating Contextual Menus创建上下文菜单
    安卓开发11:操作控件
  • 原文地址:https://www.cnblogs.com/DevinSMR/p/5259342.html
Copyright © 2011-2022 走看看