iOS 瀑布流

前阵子需要做一个需求,在iPhone上实现瀑布流效果。

第一眼看到这个需求,我想到的两种解决方案分别是:

1. 使用多个UITableView,然后控制它们同时滚动;

 2. 使用一个UIScrollView,然后参考UITableView的实现自己做一个符合需求并且以后可以重用的控件。

 

我首先尝试了第一个方案,并且Google过控制多个UITableView同时滚动的代码,在StackOverflow里面找到一段蛮详细的代码了,不过在复杂的用户操作下,仍然会出现滚动不同步的情况。

最终,我放弃了这个方案。

 

而第二个方案的关键点就在于参考UITableView实现时,如何重用单元格。

下面是我实现的重用代码:

01- (void)onScroll 
02
03    for (int i = 0; i < self.columns; ++i) { 
04        NSUInteger basicVisibleRow = 0; 
05        WaterFlowViewCell *cell = nil; 
06        CGRect cellRect = CGRectZero; 
07           
08        NSMutableArray *singleRectArray = [self.cellRectArray objectAtIndex:i]; 
09        NSMutableArray *singleVisibleArray = [self.visibleCells objectAtIndex:i]; 
10           
11        if (0 == [singleVisibleArray count]) { 
12            // There is no visible cells in current column now, find one. 
13            for (int j = 0; j < [singleRectArray count]; ++j) { 
14                cellRect = [(NSValue *)[singleRectArray objectAtIndex:j] CGRectValue]; 
15                if (![self canRemoveCellForRect:cellRect]) { 
16                    WFIndexPath *indexPath = [WFIndexPath indexPathForRow:j inColumn:i]; 
17                    basicVisibleRow = j; 
18                       
19                    cell = [self.waterFlowDataSource waterFlowView:self cellForRowAtIndexPath:indexPath]; // nil ? 
20                    cell.indexPath = indexPath; 
21                    cell.frame = cellRect; 
22                    if (!cell.superview) [self addSubview:cell]; 
23                    NSLog(@"Cell Info : %@\n", cell); 
24                       
25                    [singleVisibleArray insertObject:cell atIndex:0]; 
26                    break
27                
28            
29        } else
30            cell = [singleVisibleArray objectAtIndex:0]; 
31            basicVisibleRow = cell.indexPath.row; 
32        
33           
34        // Look back to load visible cells 
35        for (int j = basicVisibleRow - 1; j >= 0; --j) { 
36            cellRect = [(NSValue *)[singleRectArray objectAtIndex:j] CGRectValue]; 
37            if (![self canRemoveCellForRect:cellRect]) { 
38                WFIndexPath *indexPath = [WFIndexPath indexPathForRow:j inColumn:i]; 
39                if ([self containVisibleCellForIndexPath:indexPath]) { 
40                    continue
41                
42                   
43                cell = [self.waterFlowDataSource waterFlowView:self cellForRowAtIndexPath:indexPath]; // nil ? 
44                cell.indexPath = indexPath; 
45                cell.frame = cellRect; 
46                if (!cell.superview) [self addSubview:cell]; 
47                NSLog(@"Cell Info : %@\n", cell); 
48                   
49                [singleVisibleArray insertObject:cell atIndex:0]; 
50            } else
51                break
52            
53        
54           
55        // Look forward to load visible cells 
56        for (int j = basicVisibleRow + 1; j < [singleRectArray count]; ++j) { 
57            cellRect = [(NSValue *)[singleRectArray objectAtIndex:j] CGRectValue]; 
58            if (![self canRemoveCellForRect:cellRect]) { 
59                WFIndexPath *indexPath = [WFIndexPath indexPathForRow:j inColumn:i]; 
60                if ([self containVisibleCellForIndexPath:indexPath]) { 
61                    continue
62                
63                   
64                cell = [self.waterFlowDataSource waterFlowView:self cellForRowAtIndexPath:indexPath]; // nil ? 
65                cell.indexPath = indexPath; 
66                cell.frame = cellRect; 
67                if (!cell.superview) [self addSubview:cell]; 
68                NSLog(@"Cell Info : %@\n", cell); 
69                   
70                [singleVisibleArray insertObject:cell atIndex:0]; 
71            } else
72                break
73            
74        
75           
76        // Recycle invisible cells 
77        for (int j = 0; j < [singleVisibleArray count]; ++j) { 
78            cell = [singleVisibleArray objectAtIndex:j]; 
79            if ([self canRemoveCellForRect:cell.frame]) { 
80                [cell removeFromSuperview]; 
81                [self addReusableCell:cell]; 
82                [singleVisibleArray removeObject:cell]; 
83                --j; 
84                NSLog(@"Removable Cell Info : %@\n", cell); 
85            
86        
87    
88}
主要思想就是,1. 找到一个需要展示的Cell;2. 以这个Cell开始,向前、向后推进,为需要展现出来的Cell分配;3. 遍历可见Cell,回收不可见的对象。最后,把代码稍微做了抽离,弄了个小Demo,放到GitHub: https://github.com/siqin/WaterFlow
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值