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