{"comment":{"url":"https://api.github.com/repos/LLSpring/ZYDraggingSort/comments/20179936","html_url":"https://github.com/LLSpring/ZYDraggingSort/commit/946f8302b95c403264f8fdcd410dd04ab6ee561f#commitcomment-20179936","id":20179936,"user":{"login":"LLSpring","id":19663705,"avatar_url":"https://avatars.githubusercontent.com/u/19663705?v=3","gravatar_id":"","url":"https://api.github.com/users/LLSpring","html_url":"https://github.com/LLSpring","followers_url":"https://api.github.com/users/LLSpring/followers","following_url":"https://api.github.com/users/LLSpring/following{/other_user}","gists_url":"https://api.github.com/users/LLSpring/gists{/gist_id}","starred_url":"https://api.github.com/users/LLSpring/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/LLSpring/subscriptions","organizations_url":"https://api.github.com/users/LLSpring/orgs","repos_url":"https://api.github.com/users/LLSpring/repos","events_url":"https://api.github.com/users/LLSpring/events{/privacy}","received_events_url":"https://api.github.com/users/LLSpring/received_events","type":"User","site_admin":false},"position":null,"line":null,"path":null,"commit_id":"946f8302b95c403264f8fdcd410dd04ab6ee561f","created_at":"2016-12-14T02:24:38Z","updated_at":"2016-12-14T02:24:38Z","body":"###导读\r\n>拖拽排序是新闻类的App可以说是必有的交互设计，如今日头条，网易新闻等。拖拽排序是一个交互体验非常好的设计，简单，方便。\r\n\r\n####今日头条的拖拽排序界面\r\n![今日头条的拖拽排序界面.png](http://upload-images.jianshu.io/upload_images/1338042-7d5fa67d9b03b5a9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)\r\n\r\n\r\n####我实现的长按拖拽排序效果\r\n![长按拖拽排序.gif](http://upload-images.jianshu.io/upload_images/1338042-dd15e90dd9e752fc.gif?imageMogr2/auto-orient/strip)\r\n\r\n####实现方案\r\n\r\n1.给CollectionViewCell添加一个长按手势，通过协议把手势传递到collectionView所在的控制器中。\r\n    - (void)awakeFromNib{\r\n        self.layer.cornerRadius = 3;\r\n        self.layer.masksToBounds = YES;\r\n        //给每个cell添加一个长按手势\r\n        UILongPressGestureRecognizer * longPress =[[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPress:)];\r\n        longPress.delegate = self;\r\n        [self addGestureRecognizer:longPress];\r\n    }\r\n\r\n    - (void)longPress:(UILongPressGestureRecognizer *)longPress{\r\n        if (self.delegate && [self.delegate respondsToSelector:@selector(longPress:)]) {\r\n            [self.delegate longPress:longPress];\r\n        }\r\n    }\r\n\r\n2.开始长按时对cell进行截图，并隐藏cell。\r\n\r\n    - (void)longPress:(UILongPressGestureRecognizer *)longPress{\r\n        //记录上一次手势的位置\r\n        static CGPoint startPoint;\r\n        //触发长按手势的cell\r\n        MovingCell * cell = (MovingCell *)longPress.view;\r\n        //开始长按\r\n        if (longPress.state == UIGestureRecognizerStateBegan) {\r\n            [self shakeAllCell];\r\n            //获取cell的截图\r\n            _snapshotView  = [cell snapshotViewAfterScreenUpdates:YES];\r\n            _snapshotView.center = cell.center;\r\n            [_collectionView addSubview:_snapshotView];\r\n            _indexPath= [_collectionView indexPathForCell:cell];\r\n            _originalCell = cell;\r\n            _originalCell.hidden = YES;\r\n            startPoint = [longPress locationInView:_collectionView];\r\n        }\r\n\r\n3、在手势移动的时候，移动截图视图，用遍历的方法求出截图移动到哪个cell的位置，再调用系统的api交换这个cell和隐藏cell的位置，并且数据源中的数据也需要调整顺序\r\n\r\n        //手势移动的时候\r\n        else if (longPress.state == UIGestureRecognizerStateChanged){\r\n        CGFloat tranX = [longPress locationOfTouch:0 inView:_collectionView].x - startPoint.x;\r\n        CGFloat tranY = [longPress locationOfTouch:0 inView:_collectionView].y - startPoint.y;\r\n        //设置截图视图位置\r\n        _snapshotView.center = CGPointApplyAffineTransform(_snapshotView.center, CGAffineTransformMakeTranslation(tranX, tranY));\r\n        startPoint = [longPress locationOfTouch:0 inView:_collectionView];\r\n        //计算截图视图和哪个cell相交\r\n        for (UICollectionViewCell *cell in [_collectionView visibleCells]) {\r\n            //跳过隐藏的cell\r\n            if ([_collectionView indexPathForCell:cell] == _indexPath) {\r\n                continue;\r\n            }\r\n            //计算中心距\r\n            CGFloat space = sqrtf(pow(_snapshotView.center.x - cell.center.x, 2) + powf(_snapshotView.center.y - cell.center.y, 2));\r\n\r\n            //如果相交一半且两个视图Y的绝对值小于高度的一半就移动\r\n            if (space <= _snapshotView.bounds.size.width * 0.5 && (fabs(_snapshotView.center.y - cell.center.y) <= _snapshotView.bounds.size.height * 0.5)) {\r\n                _nextIndexPath = [_collectionView indexPathForCell:cell];\r\n                if (_nextIndexPath.item > _indexPath.item) {\r\n                    for (NSUInteger i = _indexPath.item; i < _nextIndexPath.item ; i ++) {\r\n                        [self.array exchangeObjectAtIndex:i withObjectAtIndex:i + 1];\r\n                    }\r\n                }else{\r\n                    for (NSUInteger i = _indexPath.item; i > _nextIndexPath.item ; i --) {\r\n                        [self.array exchangeObjectAtIndex:i withObjectAtIndex:i - 1];\r\n                    }\r\n                }\r\n                //移动\r\n                [_collectionView moveItemAtIndexPath:_indexPath toIndexPath:_nextIndexPath];\r\n                //设置移动后的起始indexPath\r\n                _indexPath = _nextIndexPath;\r\n                break;\r\n            }\r\n        }\r\n4.手势停止时，移除截图的view，显示隐藏cell\r\n\r\n    //手势停止时\r\n    }else if(longPress.state == UIGestureRecognizerStateEnded){\r\n        [self stopShake];\r\n        [_snapshotView removeFromSuperview];\r\n        _originalCell.hidden = NO;\r\n    }\r\n"}}
{"actor":{"display_login":"LLSpring"}}