你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> 詳解IOS中若何完成瀑布流後果

詳解IOS中若何完成瀑布流後果

編輯:IOS開發綜合

起首是後果演示

特色:可以自在設置瀑布流的總列數(後果演示為2列)

固然iphone手機的體系相冊沒有應用這類結構後果,瀑布流仍然是一種很罕見的結構方法!!!上面來具體引見若何完成這類結構.

起首應用的類是UICollectionView

我們要做的是自界說UICollectionViewCell和UICollectionViewLayout

     1、自界說UICollectionViewCell類,只須要一個UIImageView便可,frame占滿全部cell.

     2、重點是自界說UICollectionViewLayout,留意必定要繼續於UICollectionViewLayout,萬萬別繼續於UIColletionViewFlowLayout.

     3、別的還須要盤算圖片高度.

為何要自界說UICollectionViewLayout ?

由於我們須要設置每一個item的高度和地位, 留意這裡是地位, 我們真的會設置每一個item的地位的信任我!!!自界說UICollectionViewLayout必需要重寫三個協定辦法,前面會講到.

為何要盤算圖片高度 ?

由於圖片寬度固定,所以須要依照圖片的比例來盤算高度,使圖片等比例顯示.如許的利益是,媽媽不再用擔憂我的照片被拉伸的奇形怪狀了...並且還須要用圖片的高度來盤算全部CollectionView的contentSize...打完出工!!!

主菜來了!!!

以下內容均在自界說的CustomCollectionViewLayout類裡邊

//自界說UICollectionViewLayout必需要重寫的三個協定辦法
//1.盤算每一個item的年夜小和地位
- (void)prepareLayout;
//2.前往每一個item的結構屬性
- (nullable NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect;
//3.前往collectionView的總高度
- (CGSize)collectionViewContentSize;

可以看到第三個辦法應用了Nullability和泛型,體系的辦法都添加了IOS 9新特征。

經由過程上邊的三個辦法名我們可以年夜致懂得須要去做甚麼.說一下第二個辦法,須要前往一個數組,數組寄存結構屬性(UICollectionViewLayoutAttributes)對象.那末我們須要寫一個屬性數組(attributesArray),將結構屬性放入這個屬性數組並前往.

還須要甚麼呢 ?看了文章開首的同伙應當留意到了,設置瀑布流的列數固然得有個屬性(numberOfColumns)來表現列數.

請留意,由於要在內部設置列數,所以這個屬性須要寫在自界說類的.h文件中

別的為了便利,界說一個屬性(itemWidth)來表現item的寬度

再界說一個屬性(contentHeight)來表現全部collectionView的contenView的高度

起首是初始化,並沒有甚麼成績

- (instancetype)init {
  self = [super init];
  if (self) {
    _attributesArray = [NSMutableArray array];
    // 默許值設置為2列
    _numberOfColumns = 2;
    _contentHeight = 0.0f;
    _cellMargin = 5.0f;/**< 用來表現間距的屬性 */
  }
  return self;
}

然後是getter辦法,只須要應用點語法便可獲得itemWidth的值(由於它就是固定的)

- (CGFloat)itemWidth {
  //一切邊距的和.兩列時有三個邊距, 三列時有四個邊距,邏輯壯大就是好...
  CGFloat allMargin = (_numberOfColumns + 1) * _cellMargin;
  //除去界限以後的總寬度
  CGFloat noMarginWidth = CGRectGetWidth(self.collectionView.bounds) - allMargin;
  //出去邊距的總寬度除以列數獲得每列的寬度(也就是itemWidth)
  return noMarginWidth / _numberOfColumns;
}

---接上去是難點---

必需重寫的第一個辦法

- (void)prepareLayout {
  // 界說變量記載高度最小的列,初始為第0列高度最小.
#pragma mark - 留意這個是從0開端算的啊!!!
  NSInteger shortestColumn = 0;
#pragma mark - 留意這個是從0開端算的啊!!!
  // 存儲每列的總高度.由於添加圖片的列高度會變,所以須要界說一個數組來記載列的總高度.
  NSMutableArray *columnHeightarray = [NSMutableArray array];
  // 設置列的初始高度為邊距的高度,沒缺點!!!
  for (int i = 0; i < _numberOfColumns; i++) {
    // 一切列初始高度均設置為cell的間距
    [columnHeightarray addObject:@(_cellMargin)];
  }
  // 遍歷collectionView中第 0 區中的一切item
  for (int i = 0; i < [self.collectionView numberOfItemsInSection:0]; i++) {
    //須要用到這個玩意,提早拿到.
    NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
    // 創立體系須要的結構屬性對象,看後邊的參數就曉得這就是每一個item的結構屬性了
    UICollectionViewLayoutAttributes *layoutAttributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath: indexPath];
    // 將結構屬性放入數組中,這個數組固然是一開端界說的結構屬性數組了
    [_attributesArray addObject:layoutAttributes];
    // 設置每一個item的地位(x, y, width, height)
    // 橫坐標的肇端地位
#pragma mark - 好比一共兩列,如今要放一張圖片上去,須要放到高度最小的那一列.
#pragma mark - 假定第0列最短,那末item的x坐標就是從一個邊距寬度那邊開端.
#pragma mark - (itemWidth + cellMargin)為一個全體
    CGFloat x = (self.itemWidth + _cellMargin) * shortestColumn + _cellMargin;
    // 縱坐標就是 總高度數組 中最小列對應的高度
#pragma mark - 圖片一直是添加在高度最小的那一列
    CGFloat y = [columnHeightarray[column] floatValue];/**<留意類型轉換 */
    // 寬度沒甚麼好說的
    CGFloat width = self.itemWidth;
#pragma mark - 這裡給自界說的類聲清楚明了一個協定,經由過程協定獲得圖片的高度,挪用機會就是須要item高度的時刻
#pragma mark - 將Item的寬度傳給署理人(ViewController),VC盤算好高度後將高度前往給自界說類
#pragma mark - 也就是↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
    CGFloat height = [self.delegate collectionView:self.collectionView
                        layout:self
                         width:self.itemWidth
               heightForItemAtIndexPath:indexPath];
    // 年夜功樂成,設置item的地位信息,沒甚麼好說
    layoutAttributes.frame = CGRectMake(x, y, width, height);
    // 上邊廢了半天勁放了一個item上去了,總高度數組是否是該更新一下數據了
    columnHeightArray[shortestColumn] = @([columnHeightArray[shortestColumn] floatValue] + height + _cellMargin);
    // 全部內容的高度,經由過程比擬獲得較年夜值作為全部內容的高度
    self.contentHeight = MAX(self.contentHeight, [columnHeightArray[shortestColumn] floatValue]);
    // 適才放了一個item上去,那末此時此刻哪一列的高度比擬低呢
    for (int i = 0; i < _numberOfColumns; i++) {
      //以後列的高度(適才添加item的那一列)
      CGFloat currentHeight = [columnHeightArray[shortestColumn] floatValue];
      // 掏出第i列中寄存列高度
      CGFloat height = [columnHeightArray[i] floatValue];
      if (currentHeight > height) {
        //第i列高度(height)最低時,高度最低的列(shortestColumn)固然就是第i列了
        shortestColumn = i;
      }
    }
  }
// 思慮下只應用上邊的代碼會湧現甚麼成績
// 其實不能影響心境,請不要驚恐...
// 提醒:這個辦法會被屢次挪用,數組
}

---難點曾經停止---

沒有懂得的同伙請重點看上邊的難點辦法.

必需重寫的第二個辦法

// 2.前往的是, 每一個item對應的結構屬性
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {
  return _attributesArray;
}

必需重寫的第三個辦法

// 3.前往CollectionView的轉動規模
- (CGSize)collectionViewContentSize {
  return CGSizeMake(0, _contentHeight);
}

ViewController裡邊關於CollectionView的創立和協定辦法就沒甚麼好說的了.

看下自界說類CustomCollectionViewLayout的創立和屬性的賦值情形:

CustomCollectionViewLayout *layout = [[CustomCollectionViewLayout alloc] init];
layout.numberOfColumns = 2;/**< 在ViewController裡設置瀑布流的列數,2列或3列為最好 */
layout.delegate = self;/**< 指定VC為盤算高度協定辦法的署理人 */

再看下協定辦法的完成部門(在ViewController.m中完成)

- (CGFloat)collectionView:(UICollectionView *)collectionView
          layout:(UICollectionViewLayout *)collectionViewLayout
          width:(CGFloat)width
 heightForItemAtIndexPath:(nonnull NSIndexPath *)indexPath {
  UIImage *image = _imagesArray[indexPath.row];
  // 依據傳過去的寬度來設置一個適合的矩形, 高度設為CGFLOAT_MAX表現以寬度來盤算高度
  CGRect boundingRect = CGRectMake(0, 0, width, CGFLOAT_MAX);
  // 經由過程體系函數來獲得終究的矩形,須要引入頭文件
  // #import <AVFoundation/AVFoundation.h>
  CGRect imageCurrentRect = AVMakeRectWithaspectRatioInsideRect(image.size, boundingRect);
  return imageCurrentRect.size.height;
}

總結

到這裡呢,在IOS完成瀑布流就算是停止了,有興致的同伙可以本身著手試一下,願望本文對年夜家開辟IOS有所贊助。

【詳解IOS中若何完成瀑布流後果】的相關資料介紹到這裡,希望對您有所幫助! 提示:不會對讀者因本文所帶來的任何損失負責。如果您支持就請把本站添加至收藏夾哦!

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved