三种实现iOS瀑布流的思路总结

瀑布流介绍

瀑布流可以在保证图片原始比例的情况下,灵活的展现内容,相对于传统的使用相同大小的网格展现大量图片,效果上要好上很多,而实现瀑布流的方式有很多种,网上比较流行的有三种实现方式。 
1,使用UIScrollView,主要技术点在于视图的重用。 
2,使用UITableView,这种方式应该是最易想到的,因为需要展现几列就用几个tabelview就ok了,而且不需要考虑重用,因为苹果已经做好了,只需要考虑如何在几列tabelView滑动的时候,保持同步不出现BUG。 
3,使用UICollectionView,UICollectionView在iOS6中第一次被介绍,它与UITableView有许多相似点,但它多了一个布局类,而实现瀑布流,就与这个布局类有关。此种方式实现,也不需要考虑视图重用。

UITableView的重用机制做瀑布流思路

  1. 总先做成几列是事先要清楚,有多少条记录,这个可以从json或者xml中读取后知道(json或xml最好将图片的高度和宽度也显示出来,便于后面用到。
  2. 假设要做成3列,就用三个uitableview,宽度平均,高度动态,页面高度取uitableview中最高的。
  3. 三个uitableview初始化的时候用到tag(我越来越觉得tag在ios中的用处很大,就像js中读取html控件中的id一样),然后 showsVerticalScrollIndicator和scrollEnabled设为no,separatorStyle设为 UITableViewCellSeparatorStyleNone,添加到UIview中。

下面详细讲一下用UICollectionView做瀑布流

1.故事板中拖拽一个UICollectionView放在视图中

2.新建一个继承子UICollectionViewCell的子类MyCollectionViewCell,将单元格的Class选定为MyCollectionViewCell,并且设置Identifier为MyCell。

3.实现UICollectionViewDelegate,UICollectionViewDataSource,设置区域,设置区域中的Item个数,生成可复用的单元格:

<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">-(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSInteger</span>)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
}

-(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSInteger</span>)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSInteger</span>)section{
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">100</span>;
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSIndexPath</span> *)indexPath{
    MyCollectionViewCell *myCell=[collectionView dequeueReusableCellWithReuseIdentifier:
                                  @<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"MyCell"</span> forIndexPath:indexPath];
    [myCell setBackgroundColor:[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIColor</span> greenColor]];
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>  myCell;
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul>

viewDidLoad中设置一下数据源和代理:

<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.collectionView</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.delegate</span>=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span>;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.collectionView</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.dataSource</span>=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span>;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.collectionView</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.backgroundColor</span>=[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIColor</span> whiteColor];</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>

最终效果: 
三种实现iOS瀑布流的思路总结_第1张图片

进行masonry layout (布局)

很多情况下所有的单元格的宽度是一定的,只是高度不确定,这就是有些人说的定宽不定高,主要是从视觉上的美感来看,当然我们可以通过实现

<code class="hljs erlang has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">UICollectionViewDelegateFlowLayout</span>去改变单元格大小:
<span class="hljs-pp" style="box-sizing: border-box;">-<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">CGSize</span>)</span>collectionView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UICollectionView</span> *)</span>collectionView layout:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UICollectionViewLayout</span> *)</span>collectionViewLayout sizeForItemAtIndexPath:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSIndexPath</span> *)</span>indexPath{

    CGFloat height=100+<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-function_name" style="box-sizing: border-box;">arc4random</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">%100);</span>
    return  <span class="hljs-variable" style="box-sizing: border-box;">CGSizeMake</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">100</span>, height)</span>;

}</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

通过效果我们可以发现,同一行的单元格的圆心所在的Y轴坐标都是一样的: 
三种实现iOS瀑布流的思路总结_第2张图片 
设置存储所有高度的数组: 
//存储所有的高度的数组

<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">@property</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">strong</span>,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">nonatomic</span>) <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSMutableArray</span>  *heightArr;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

将高度添加到数组中:

<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">-(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">CGSize</span>)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSIndexPath</span> *)indexPath{

    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">CGFloat</span> height=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">100</span>+(arc4random()%<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">160</span>);
    [<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.heightArr</span> addObject:[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSString</span> stringWithFormat:@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"%f"</span>,height]];

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>  CGSizeMake(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">100</span>, height);

}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul>

修改每一行单元格的位置:

<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSIndexPath</span> *)indexPath{

    MyCollectionViewCell *myCell=[collectionView dequeueReusableCellWithReuseIdentifier:
                    @<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"MyCell"</span> forIndexPath:indexPath];

    [myCell setBackgroundColor:[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIColor</span> redColor]];
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSInteger</span> remainder=indexPath<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.row</span>%<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>;

    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSInteger</span> currentRow=indexPath<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.row</span>/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>;

    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">CGFloat</span>   currentHeight=[<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.heightArr</span>[indexPath<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.row</span>] floatValue];


    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">CGFloat</span> positonX=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">100</span>*remainder+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>*(remainder+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>);
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">CGFloat</span> positionY=(currentRow+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)*<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSInteger</span> i=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; i<currentRow; i++) {

        <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSInteger</span> position=remainder+i*<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>;

        positionY+=[<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.heightArr</span>[position] floatValue];
    }
   myCell<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.frame</span> = CGRectMake(positonX, positionY,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">100</span>,currentHeight) ;


    NSUInteger *randomNumber=arc4random_uniform(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">9</span>);

    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSString</span> *girlFilename = [<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSString</span> stringWithFormat:@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Girl%lu.jpg"</span>, (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span>)randomNumber];

    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIImageView</span> *imageView = [[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIImageView</span> alloc] initWithImage:[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIImage</span> imageNamed:girlFilename]];


    [myCell setBackgroundView:imageView];
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>  myCell;

}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li></ul>

最终效果 
三种实现iOS瀑布流的思路总结_第3张图片

iOS瀑布流三种实现思路总结

你可能感兴趣的:(ios,图片,瀑布流)