實現效果
設計思路
使用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的數據源
設置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;}
效果如圖
新聞熱點
疑難解答