首页 > 代码库 > iOS-TableView拖动Cell更换次序

iOS-TableView拖动Cell更换次序

效果:

长按某个Cell,Cell会有一个明显的弹起放大效果。这时候,你可以通过拖动cell和其他Cell更换顺序。

 

实现的原理:

1,浮层

长按后,UITableViewCell上会出现一个浮层,同时UITableViewCell隐藏。并且浮层可拖动。(对UITableViewCell生成一个快照)

 1 #pragma mark - Helper methods
 2 
 3 /** @brief Returns a customized snapshot of a given view. */
 4 - (UIView *)customSnapshoFromView:(UIView *)inputView {
 5     UIView* snapshot = nil;
 6     
 7     if ([[[UIDevice currentDevice] systemVersion] doubleValue] < 7.0) {
 8         //ios7.0 以下通过截图形式保存快照
 9         snapshot = [self customSnapShortFromViewEx:inputView];
10     }else{
11         //ios7.0 系统的快照方法
12         snapshot = [inputView snapshotViewAfterScreenUpdates:YES];
13     }
14     
15     snapshot.layer.masksToBounds = NO;
16     snapshot.layer.cornerRadius = 0.0;
17     snapshot.layer.shadowOffset = CGSizeMake(-5.0, 0.0);
18     snapshot.layer.shadowRadius = 5.0;
19     snapshot.layer.shadowOpacity = 0.4;
20     
21     return snapshot;
22 }
23 
24 - (UIView *)customSnapShortFromViewEx:(UIView *)inputView
25 {
26     CGSize inSize = inputView.bounds.size;
27     // 下面方法,第一个参数表示区域大小。第二个参数表示是否是非透明的。如果需要显示半透明效果,需要传NO,否则传YES。第三个参数就是屏幕密度了
28     UIGraphicsBeginImageContextWithOptions(inSize, NO, [UIScreen mainScreen].scale);
29     [inputView.layer renderInContext:UIGraphicsGetCurrentContext()];
30     UIImage *image= UIGraphicsGetImageFromCurrentImageContext();
31     UIGraphicsEndImageContext();
32     UIImageView* snapshot = [[UIImageView alloc] initWithImage:image];
33     
34     return snapshot;
35 }

2,更换某对UITableViewCell的位置

?
1
2
3
4
// ... update data source.
[_items exchangeObjectAtIndex:indexPath.row withObjectAtIndex:sourceIndexPath.row];             
// ... move the rows.
[_tableView moveRowAtIndexPath:sourceIndexPath toIndexPath:indexPath];

datasource里面的data的位置替换,同时将tableView的Cell位置替换。

 1 - (void)longPressGestureRecognized:(id)sender {
 2     
 3     UILongPressGestureRecognizer *longPress = (UILongPressGestureRecognizer *)sender;
 4     UIGestureRecognizerState state = longPress.state;
 5     
 6     CGPoint location = [longPress locationInView:_tableView];
 7     NSIndexPath *indexPath = [_tableView indexPathForRowAtPoint:location];
 8     
 9     static UIView       *snapshot = nil;        ///< A snapshot of the row user is moving.
10     static NSIndexPath  *sourceIndexPath = nil; ///< Initial index path, where gesture begins.
11     
12     switch (state) {
13         case UIGestureRecognizerStateBegan: {
14             if (indexPath) {
15                 sourceIndexPath = indexPath;
16                 
17                 UITableViewCell *cell = [_tableView cellForRowAtIndexPath:indexPath];
18                 
19                 // Take a snapshot of the selected row using helper method.
20                 snapshot = [self customSnapshoFromView:cell];
21                 
22                 // Add the snapshot as subview, centered at cell‘s center...
23                 __block CGPoint center = cell.center;
24                 snapshot.center = center;
25                 snapshot.alpha = 0.0;
26                 [_tableView addSubview:snapshot];
27                 [UIView animateWithDuration:0.25 animations:^{
28                     
29                     // Offset for gesture location.
30                     center.y = location.y;
31                     snapshot.center = center;
32                     snapshot.transform = CGAffineTransformMakeScale(1.05, 1.05);
33                     snapshot.alpha = 0.98;
34                     
35                     cell.alpha = 0.0f;
36                 } completion:^(BOOL finished) {
37                     cell.hidden = YES;
38                 }];
39             }
40             break;
41         }
42             
43         case UIGestureRecognizerStateChanged: {
44             CGPoint center = snapshot.center;
45             center.y = location.y;
46             snapshot.center = center;
47             
48             // Is destination valid and is it different from source?
49             if (indexPath && ![indexPath isEqual:sourceIndexPath]) {
50                 
51                 // ... update data source.
52                 [_items exchangeObjectAtIndex:indexPath.row withObjectAtIndex:sourceIndexPath.row];
53                 
54                 // ... move the rows.
55                 [_tableView moveRowAtIndexPath:sourceIndexPath toIndexPath:indexPath];
56                 
57                 // ... and update source so it is in sync with UI changes.
58                 sourceIndexPath = indexPath;
59             }
60             break;
61         }
62             
63         default: {
64             // Clean up.
65             UITableViewCell *cell = [_tableView cellForRowAtIndexPath:sourceIndexPath];
66             [UIView animateWithDuration:0.25 animations:^{
67                 
68                 snapshot.center = cell.center;
69                 snapshot.transform = CGAffineTransformIdentity;
70                 snapshot.alpha = 0.0;
71                 
72                 cell.alpha = 1.0f;
73             } completion:^(BOOL finished) {
74                 cell.hidden = NO;
75                 [snapshot removeFromSuperview];
76                 snapshot = nil;
77                 
78             }];
79             sourceIndexPath = nil;
80             break;
81         }
82     }
83 }

3,  ......似乎没有其他了吧?

你看,是不是很简单呢!只需要上面几行代码,你就可以实现一个稍微有点好看的UITableViewCell变换位置的效果了。

下载Demo