zoukankan      html  css  js  c++  java
  • OC

    概述


    • 实现效果

    • 设计思路

      • 采用MVC架构,即模型—视图-控制器架构
      • 使用MJExtension框架实现字典转模型
      • 使用MJRefresh框架实现上拉和下拉刷新

        • 上拉刷新,加载新的数据
        • 下拉刷新,加载更多的数据
      • 使用SDWebImage框架加载图片

    模型


    • 商品模型需要包含以下属性

      /**商品控件宽度*/
      @property (nonatomic, assign) CGFloat w;
      /**商品控件高度*/
      @property (nonatomic, assign) CGFloat h;
      /**商品图片*/
      @property (nonatomic, copy) NSString *img;
      /**商品价格*/
      @property (nonatomic, copy) NSString *price;

    视图


    • 通过xib来实现自定义cell(继承自UICollectionViewCell),xib的结构如图

    • 视图的代码实现

      • 包含商品模型属性

        /**商品模型*/
        @property (nonatomic, strong) LYPShop *shop;
      • 引用xib中的控件

        //展示商品图片
        @property (weak, nonatomic) IBOutlet UIImageView *imageView;
        //显示商品价格
        @property (weak, nonatomic) IBOutlet UILabel *priceLabel;
      • 重写商品模型的setter,使xib中的控件显示乡音的内容

        - (void)setShop:(LYPShop *)shop
        {
            _shop = shop;
        
            //使用SDWebImage设置商品图片
            [self.imageView sd_setImageWithURL:[NSURL URLWithString:shop.img] placeholderImage:[UIImage imageNamed:@"loading"]];
            //设置商品价格
            self.priceLabel.text = shop.price;
        }

    控制器


    • 创建展示商品的容器,即UICollectionView对象,并初始化

      - (void)setupCollectionView
      {
          //通过封装的自定义布局,创建布局
          LYPWaterFlowLayout *layout = [[LYPWaterFlowLayout alloc] init];
      
          //设置layout的代理
          layout.delegate = self;
      
          //创建collectionView
          UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:layout];
          self.collectionView = collectionView;
      
          //设置数据源
          collectionView.dataSource = self;
          //将collectionView添加到控制器的view中
          [self.view addSubview:collectionView];
      }
    • 注册通过xib自定义的cell

      /**设置cell的重用标示*/
      static NSString *const LYPShopID = @"shop";
      - (void)registerCell
      {
          //注册cell
          [self.collectionView registerNib:[UINib nibWithNibName:NSStringFromClass([LYPShopCell class]) bundle:nil] forCellWithReuseIdentifier:LYPShopID];
      }
    • 设置商品模型数组

      • 添加成员属性

        /**所有的商品模型数组*/
        @property (nonatomic, strong) NSMutableArray *shops;
      • 通过懒加载的方式,初始化模型数组

        - (NSMutableArray *)shops
        {
            if (_shops == nil)
            {
                _shops = [NSMutableArray array];
            }
            return _shops;
        }
    • 实现刷新功能

      • 刷新的业务逻辑,如图

      • 设置上拉刷新和下拉刷新控件

        - (void)setupRefresh
        {
        	//下拉刷新控件
            self.collectionView.header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadNewShops)];
            //view加载完毕,开始下拉刷新
            [self.collectionView.header beginRefreshing];
        
            //上拉刷新控件
            self.collectionView.footer = [MJRefreshAutoNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreShops)];
            //一开始隐藏footer
            self.collectionView.footer.hidden = YES;
        }
      • 实现加载数据功能

        /**下拉刷新*/
        - (void)loadNewShops
        {
            //通过该函数模拟网络延迟
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        
                //将字典转成模型
                NSArray *shops = [LYPShop objectArrayWithFilename:@"1.plist"];
        
                //清空之前所有的商品模型信息
                [self.shops removeAllObjects];
                //将最新的商品模型信息添加到模型数组中
                [self.shops addObjectsFromArray:shops];
        
                //刷新数据
                [self.collectionView reloadData];
                //结束刷新
                [self.collectionView.header endRefreshing];
            });
        }
        /**上拉刷新*/
        - (void)loadMoreShops
        {
            //通过该函数模拟网络延迟
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                //通过该函数模拟网络延迟
                NSArray *shops = [LYPShop objectArrayWithFilename:@"1.plist"];
                //将新加载的商品模型信息添加到模型数组中
                [self.shops addObjectsFromArray:shops];
        
                //刷新数据
                [self.collectionView reloadData];
                //结束刷新
                [self.collectionView.footer endRefreshing];
            });
        }
    • 设置collectionView的数据源

      • 遵守协议UICollectionViewDataSource
      • 设置cell的个数

        - (NSInteger)collectionView:(nonnull UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
        {
            //设置上拉刷新控件的状态,无商品时不显示
            self.collectionView.footer.hidden = self.shops.count == 0;
            //返回cell的个数
            return self.shops.count;
        }
      • 创建indexPath位置的cell

        - (UICollectionViewCell *)collectionView:(nonnull UICollectionView *)collectionView cellForItemAtIndexPath:(nonnull NSIndexPath *)indexPath
        {
            //通过重用标示从缓存池中取,若取不到,则自动创建
            LYPShopCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:LYPShopID forIndexPath:indexPath];
        
            //给视图cell的模型赋值,使其设置cell中控件的显示内容
            cell.shop = self.shops[indexPath.item];
        
            return cell;
        }
    • 实现layout的代理方法,定制布局

      • 设置每个cell的高度

        - (CGFloat)waterFlowLayout:(LYPWaterFlowLayout *)waterFlowLayout heightForItemAtIndex:(NSInteger)index itemWith:(CGFloat)itemWith
        {
            LYPShop *shop = self.shops[index];
            //通过比例计算cell的高度
            return itemWith * shop.h / shop.w;
        }
      • 设置列数

        - (NSInteger)columnCountInWaterFlowLayout:(LYPWaterFlowLayout *)waterFlowLayout
        {
            return 2;
        }
      • 设置行间距

        - (CGFloat)rowMarginInWaterFlowLayout:(LYPWaterFlowLayout *)waterFlowLayout
        {
            return 20;
        }
      • 设置列间距

        - (CGFloat)columnMarginInWaterFlowLayout:(LYPWaterFlowLayout *)waterFlowLayout
        {
            return 40;
        }
      • 设置内边距

        - (UIEdgeInsets)edgeInsetsInWaterFlowLayout:(LYPWaterFlowLayout *)waterFlowLayout
        {
            return UIEdgeInsetsMake(20, 10, 10, 30);
        }

    改变布局


    • 可以简单地通过改变返回列数的代理方法,来改变布局

      - (NSInteger)columnCountInWaterFlowLayout:(LYPWaterFlowLayout *)waterFlowLayout
      {
      	//返回3列
          return 3;
      }
    • 效果如图

     
     
  • 相关阅读:
    Linux makefile讲解
    Linux问题集锦
    Linux 用户和组管理
    鸟哥的Linux私房菜——第八章
    考驾照的波折~
    Expression Blend实例中文教程(1)
    Silverlight & Blend动画设计系列十三:三角函数(Trigonometry)动画之飘落的雪花(Falling Snow)
    Silverlight & Blend动画设计系列十二:三角函数(Trigonometry)动画之自由旋转(Free-form rotation)
    Silverlight & Blend动画设计系列十一:沿路径动画(Animation Along a Path)
    Silverlight & Blend动画设计系列十:Silverlight中的坐标系统(Coordinate System)与向量(Vector)运动
  • 原文地址:https://www.cnblogs.com/funny11/p/4980469.html
Copyright © 2011-2022 走看看