UI 進階之拖拽排序的實現
導讀
拖拽排序是新聞類的App可以說是必有的交互設計,如今日頭條,網易新聞等。拖拽排序是一個交互體驗非常好的設計,簡單,方便。
今日頭條的拖拽排序界面
我實現的長按拖拽排序效果
實現方案
1.給CollectionViewCell添加一個長按手勢,通過協議把手勢傳遞到collectionView所在的控制器中。
- (void)awakeFromNib{
self.layer.cornerRadius = 3;
self.layer.masksToBounds = YES;
//給每個cell添加一個長按手勢
UILongPressGestureRecognizer * longPress =[[UILongPressGestureRecognizeralloc]initWithTarget:selfaction:@selector(longPress:)];
longPress.delegate = self;
[self addGestureRecognizer:longPress];
}
- (void)longPress:(UILongPressGestureRecognizer *)longPress{
if (self.delegate && [self.delegaterespondsToSelector:@selector(longPress:)]) {
[self.delegatelongPress:longPress];
}
}
</code></pre>
2.開始長按時對cell進行截圖,并隱藏cell。
- (void)longPress:(UILongPressGestureRecognizer *)longPress{
//記錄上一次手勢的位置
static CGPointstartPoint;
//觸發長按手勢的cell
MovingCell * cell = (MovingCell *)longPress.view;
//開始長按
if (longPress.state == UIGestureRecognizerStateBegan) {
[self shakeAllCell];
//獲取cell的截圖
_snapshotView = [cellsnapshotViewAfterScreenUpdates:YES];
_snapshotView.center = cell.center;
[_collectionViewaddSubview:_snapshotView];
_indexPath= [_collectionViewindexPathForCell:cell];
_originalCell = cell;
_originalCell.hidden = YES;
startPoint = [longPresslocationInView:_collectionView];
}
3、在手勢移動的時候,移動截圖視圖,用遍歷的方法求出截圖移動到哪個cell的位置,再調用系統的api交換這個cell和隱藏cell的位置,并且數據源中的數據也需要調整順序
//手勢移動的時候
else if (longPress.state == UIGestureRecognizerStateChanged){
CGFloattranX = [longPresslocationOfTouch:0 inView:_collectionView].x - startPoint.x;
CGFloattranY = [longPresslocationOfTouch:0 inView:_collectionView].y - startPoint.y;
//設置截圖視圖位置
_snapshotView.center = CGPointApplyAffineTransform(_snapshotView.center, CGAffineTransformMakeTranslation(tranX, tranY));
startPoint = [longPresslocationOfTouch:0 inView:_collectionView];
//計算截圖視圖和哪個cell相交
for (UICollectionViewCell *cellin [_collectionViewvisibleCells]) {
//跳過隱藏的cell
if ([_collectionViewindexPathForCell:cell] == _indexPath) {
continue;
}
//計算中心距
CGFloatspace = sqrtf(pow(_snapshotView.center.x - cell.center.x, 2) + powf(_snapshotView.center.y - cell.center.y, 2));
//如果相交一半且兩個視圖Y的絕對值小于高度的一半就移動
if (space _indexPath.item) {
for (NSUInteger i = _indexPath.item; i _nextIndexPath.item ; i --) {
[self.array exchangeObjectAtIndex:i withObjectAtIndex:i - 1];
}
}
//移動
[_collectionViewmoveItemAtIndexPath:_indexPathtoIndexPath:_nextIndexPath];
//設置移動后的起始indexPath
_indexPath = _nextIndexPath;
break;
}
}
4.手勢停止時,移除截圖的view,顯示隱藏cell
//手勢停止時
}else if(longPress.state == UIGestureRecognizerStateEnded){
[self stopShake];
[_snapshotViewremoveFromSuperview];
_originalCell.hidden = NO;
}
其他
代碼還可以進一步封裝,寫一個數據管理類dataTool,dataTool作為collectionView的數據源,所有的數據源方法都寫到dataTool類中。手勢的代理方法也在里面實現,這樣控制器會簡潔很多,控制器就不需要關注拖拽排序的具體邏輯了。大家有空可以自己寫寫看,也許你們有更好的處理方案,可以評論交流一下。
來自:http://ios.jobbole.com/90805/
本文由用戶 cjdl8294 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!