仿网易新闻栏目选择页面的基本效果,今天抽了点时间教大家如何实现UICollectionView拖动的效果!
其实实现起来并不复杂,这里只是基本的功能,没有实现细节上的修改,连UI都是丑丑的样子,随手画的。
相信大家都使用过网易新闻客户端,里面的效果确定被不少人模仿,很多同类型的app都采用了人家的UI样式,那么今天就教大家如何去实现。
这是简略的效果图,样子是有点丑,将就看看吧:
给UICollectionView添加一个手势或者其他方式,在长按时手动触发拖动开始,在移动过程中又要不断手动地更新位置,而在完成时手动触发完成操作,在取消时也要手动触发取消移动操作。
而要实现移动,必须设置是否可移动。比如我们的demo中第一个分区是要求移动的,而第二个分区是不允许移动的,因此我们需要通过代理来设置是否可移动。
在移动完成时,会有代理回调,此时我们要做的就是交换数据源来更新。
首先我们必须要明确,这几个API是在iOS9之后才能使用的。这几个API来配合起来使用,才能最终达到我们期望的效果。
// 开始 - (BOOL)beginInteractiveMovementForItemAtIndexPath:(NSIndexPath *)indexPathNS_AVAILABLE_IOS(9_0); // 更新位置 - (void)updateInteractiveMovementTargetPosition:(CGPoint)targetPositionNS_AVAILABLE_IOS(9_0); // 完成 - (void)endInteractiveMovementNS_AVAILABLE_IOS(9_0); // 取消 - (void)cancelInteractiveMovementNS_AVAILABLE_IOS(9_0);
这四个API组合起来才是完整的动作。
我们需要将手势放到CollectionView上,因为我们要的是操作全范围的!
self.collectionView.pagingEnabled = NO; UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]initWithTarget:selfaction:@selector(onLongPressed:)]; [self.collectionViewaddGestureRecognizer:longPress];
这个基本是固定的,大家可以copy一下我的代码过去用就可以了:
- (void)onLongPressed:(UILongPressGestureRecognizer *)sender { CGPoint point = [senderlocationInView:sender.view]; NSIndexPath *indexPath = [self.collectionViewindexPathForItemAtPoint:point]; // 只允许第一区可移动 if (indexPath.section != 0) { return; } switch (sender.state) { caseUIGestureRecognizerStateBegan: { if (indexPath) { [self.collectionViewbeginInteractiveMovementForItemAtIndexPath:indexPath]; } break; } caseUIGestureRecognizerStateChanged: { [self.collectionViewupdateInteractiveMovementTargetPosition:point]; break; } caseUIGestureRecognizerStateEnded: { [self.collectionViewendInteractiveMovement]; break; } default: { [self.collectionViewcancelInteractiveMovement]; break; } } }
这里是只有在编辑状态下且第一分区才能拖动重排,所以通过添加条件来控制是否可移动:
- (BOOL)collectionView:(UICollectionView *)collectionViewcanMoveItemAtIndexPath:(NSIndexPath *)indexPath { if (self.isEditing && indexPath.section == 0) { return YES; } return NO; }
我们只有第一分区可以操作,而这里只有一个数组,所以直接交换一下数据源就OK了:
- (void)collectionView:(UICollectionView *)collectionViewmoveItemAtIndexPath:(NSIndexPath *)sourceIndexPathtoIndexPath:(NSIndexPath *)destinationIndexPath { if (sourceIndexPath.section == 0 && destinationIndexPath.section == 0) { [self.firstListexchangeObjectAtIndex:sourceIndexPath.itemwithObjectAtIndex:destinationIndexPath.item]; } }
在点击第一分区时或者第二分区的cell时,会自动移动到第二分区或者第一分区。我们希望有移动的动画效果的话,就需要通过collectionview提供的API来完成,而编辑状态下有删除按钮,而到二分区时就不能显示,而在一分区在编辑状态下又可以显示:
#pragma mark - UICollectionViewDelegate - (void)collectionView:(UICollectionView *)collectionViewdidSelectItemAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.section == 0) { if (self.isEditing) { TestModel *model = [self.secondListhyb_objectAtIndex:indexPath.item]; [self.firstListaddObject:model]; [self.secondListremoveObject:model]; NSInteger index = self.firstList.count - 1; if (self.firstList.count == 0) { index = 0; } TestColumnCell *cell = (TestColumnCell *)[collectionViewcellForItemAtIndexPath:indexPath]; cell.isEditing = NO; [collectionViewmoveItemAtIndexPath:indexPathtoIndexPath:[NSIndexPathindexPathForItem:indexinSection:1]]; [self saveColumns]; } else { // 选择某一个 } } else { TestModel *model = [self.firstListhyb_objectAtIndex:indexPath.item]; [self.secondListaddObject:model]; [self.firstListremoveObject:model]; NSInteger index = self.secondList.count - 1; if (self.secondList.count == 0) { index = 0; } if (self.isEditing) { TestColumnCell *cell = (TestColumnCell *)[collectionViewcellForItemAtIndexPath:indexPath]; cell.isEditing = YES; } [collectionViewmoveItemAtIndexPath:indexPathtoIndexPath:[NSIndexPathindexPathForItem:indexinSection:0]]; [self saveColumns]; } [collectionViewreloadData]; }
大家不要找我要完整的Demo了啊,这里已经包含所有核心重排功能的代码了。本篇文章仅仅是将个人所写的demo的部分抽出来,不希望大家看到别的demo功能,因此就不公开了!
专注于IT行业技术专题,提供IT专题优质文章,欢迎关注标哥的技术博客!加入技术交流群,点击“最新公告”查看!
站长QQ:632840804,微信号:huangyibiao520
本站接收来自大家的投稿,只需要将`.md`文件及所需要的图片文件,整体放到文件夹并压缩,并注明作者及原文链接,发到邮箱: huangyibiao520@163.com 或者 632840804@qq.com
版本声明:本文由本站辛勤的作者在标哥的技术博客原创撰写并发布,欢迎分享本文,转载请保留出处和链接!