前言:
排序思路: 拖拽排序的主要思路是利用在UICollectionView
上添加一個長按的手勢(UILongPressGestureRecognizer
)實現(xiàn)的愁拭。 通過監(jiān)聽手勢拖拽開始,拖拽中亏吝,拖拽結束的事件岭埠,然后根據(jù)不同的狀態(tài)做相應的操作。
效果圖如下:
一蔚鸥、在UICollectionView
上添加一個長按的手勢,并在UICollectionView
上面添加一個浮動隱藏的cell,便于拖拽
// 添加長按手勢
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPressRecognizer:)];
longPress.minimumPressDuration = 0.3;
[self.mainView addGestureRecognizer:longPress];
// 添加浮動視圖
self.dragingItem = [[WEYuqingChannelCell alloc] initWithFrame:CGRectMake(0, 0, cellWidth, cellWidth/2.0f)]; self.dragingItem.hidden = true;
[self.mainView addSubview:self.dragingItem];
二枫攀、拖拽過程的監(jiān)聽
2.1 通過長按操作找到需要被拖動的cell1
2.2 通過拖動cell1找到找到和它交換位置的cell2
2.3 交換cell1和cell2的位置
2.4 替換數(shù)據(jù)源,把起始位置的數(shù)據(jù)模型刪除株茶,然后將起始位置的數(shù)據(jù)模型插入到拖拽位置
// 長按手勢處理
- (void)longPressRecognizer:(UILongPressGestureRecognizer *)longPress{
CGPoint point = [longPress locationInView:self.mainView];
switch (longPress.state) {
case UIGestureRecognizerStateBegan:{
[self dragBegin:point];
NSLog(@"拖拽開始");
break;
}
case UIGestureRecognizerStateChanged:{
[self dragChanged:point];
NSLog(@"拖拽中");
break;
}
case UIGestureRecognizerStateEnded: {
[self dragEnd];
NSLog(@"拖拽結束");
[self userSortMontiorCompany];
break;
}
default:{
break;
}
}
}
// 拖拽開始 找到被拖拽的item
- (void)dragBegin:(CGPoint)point{
self.dragingIndexPath = [self getDragingIndexPathWithPoint:point];
if (!self.dragingIndexPath) {return;}
[self.mainView bringSubviewToFront:self.dragingItem];
WEYuqingChannelCell *item = (WEYuqingChannelCell*)[self.mainView cellForItemAtIndexPath:self.dragingIndexPath];
item.isMoving = YES;
// 更新被拖拽的item
self.dragingItem.hidden = NO;
self.dragingItem.frame = item.frame;
self.dragingItem.model = item.model;
[self.dragingItem setTransform:CGAffineTransformMakeScale(1.1, 1.1)];
}
// 正在被拖拽中
- (void)dragChanged:(CGPoint)point{
if (!self.dragingIndexPath) {return;}
self.dragingItem.center = point;
self.targetIndexPath = [self getTargetIndexPathWithPoint:point];
// 交換位置 如果沒有找到self.targetIndexPath則不交換位置
if (self.dragingIndexPath && self.targetIndexPath) {
// 更新數(shù)據(jù)源
[self rearrangeInUseTitles];
//更新item位置
[self.mainView moveItemAtIndexPath:self.dragingIndexPath toIndexPath:self.targetIndexPath];
self.dragingIndexPath = self.targetIndexPath;
}
}
// 拖拽結束
- (void)dragEnd{
if (!self.dragingIndexPath) {return;}
CGRect endFrame = [self.mainView cellForItemAtIndexPath:self.dragingIndexPath].frame;
[self.dragingItem setTransform:CGAffineTransformMakeScale(1.0, 1.0)];
[UIView animateWithDuration:0.3 animations:^{
self.dragingItem.frame = endFrame;
}completion:^(BOOL finished) {
self.dragingItem.hidden = YES;
WEYuqingChannelCell *item = (WEYuqingChannelCell*)[self.mainView cellForItemAtIndexPath:self.dragingIndexPath];
item.isMoving = NO;
}];
}
// 獲取被拖動IndexPath的方法
- (NSIndexPath*)getDragingIndexPathWithPoint:(CGPoint)point{
NSIndexPath* dragIndexPath = nil;
//最后剩一個怎不可以排序
if ([self.mainView numberOfItemsInSection:0] == 1) {return dragIndexPath;}
for (NSIndexPath *indexPath in self.mainView.indexPathsForVisibleItems) {
//下半部分不需要排序
if (indexPath.section > 0) {continue;}
// 在上半部分中找出相對應的Item
if (CGRectContainsPoint([self.mainView cellForItemAtIndexPath:indexPath].frame, point)) {
// if (indexPath.row != 0) {
// dragIndexPath = indexPath;
// }
dragIndexPath = indexPath;
break;
}
}
return dragIndexPath;
}
// 獲取目標IndexPath的方法
- (NSIndexPath*)getTargetIndexPathWithPoint:(CGPoint)point{
NSIndexPath *targetIndexPath = nil;
for (NSIndexPath *indexPath in self.mainView.indexPathsForVisibleItems) {
// 如果是自己不需要排序
if ([indexPath isEqual:self.dragingIndexPath]) {continue;}
//第二組不需要排序
if (indexPath.section > 0) {continue;}
//在第一組中找出將被替換位置的Item
if (CGRectContainsPoint([self.mainView cellForItemAtIndexPath:indexPath].frame, point)) {
// if (indexPath.row != 0) {
// targetIndexPath = indexPath;
// }
targetIndexPath = indexPath;
}
}
return targetIndexPath;
}
//拖拽排序后需要重新排序數(shù)據(jù)源
- (void)rearrangeInUseTitles {
WEYuqingChannelModel *model = [self.dataArray objectAtIndex:self.dragingIndexPath.row];
[self.dataArray removeObject:model];
[self.dataArray insertObject:model atIndex:self.targetIndexPath.row];
}
三、UI處理完畢图焰,調用數(shù)據(jù)排序接口就可以了
#pragma mark - 頻道排序
- (void)userSortMontiorCompany {
NSMutableArray *idArr = @[].mutableCopy;
for (WEYuqingChannelModel *model in self.dataArray) {
[idArr addObject:model.ID];
}
NSString *idStr = [idArr componentsJoinedByString:@","];
[WEHttpRequest requestWithConfig:^(WEUrlRequestConfig * _Nonnull request) {
request.methodType = WEHttpMethodPOST;
request.baseUrl = HostUrl;
request.url = @"docinfo/channel/sort";
request.parameters = @{@"cnId":idStr};
request.availableType = WERequestAvailableTypeLoged;
[request setValue:[WELoginManager sharedInstance].accessToken forHeaderField:kAccessToken];
} success:^(NSDictionary * _Nullable responseObject) {
NSLog(@"打印日志启盛。%@",responseObject);
[[NSNotificationCenter defaultCenter] postNotificationName:@"channelStatusChanged" object:nil];
} failed:^(NSError * _Nullable error) {
}];
}