iOS 利用UICollectionView拖拽排序 实现的仿照腾讯新闻频道管理功能 XLChannelControl
来源:互联网 发布:远程网络教育的大学 编辑:程序博客网 时间:2024/05/22 14:29
一、实现效果
频道界面的显示 ------------》点击进行添加/删除--------》 按住可以进行拖拽排序
二、UICollectionView 拖拽排序的实现方法
1、大概思路
*拖拽排序的主要思路是利用在UICollectionView上添加一个长按的手势(UILongPressGestureRecognizer)实现的,实现步骤可以分三步:
第一步:通过长按操作找到需要被拖动的cell1
第二步:通过拖动cell1找到找到和它交换位置的cell2
第三步:交换cell1和cell2的位置
2、具体的代码实现
1)、创建一个UICollectionView,然后给其添加一个长按手势
-(void)buildUI{ UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init]; CGFloat cellWidth = (self.view.bounds.size.width - (ColumnNumber + 1) * CellMarginX)/ColumnNumber; flowLayout.itemSize = CGSizeMake(cellWidth,cellWidth); flowLayout.sectionInset = UIEdgeInsetsMake(0, CellMarginX, CellMarginY, CellMarginX); flowLayout.minimumLineSpacing = CellMarginY; flowLayout.minimumInteritemSpacing = CellMarginX; flowLayout.headerReferenceSize = CGSizeMake(self.view.bounds.size.width, 50); _collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:flowLayout]; _collectionView.showsHorizontalScrollIndicator = false; _collectionView.backgroundColor = [UIColor clearColor]; [_collectionView registerClass:[TestCell class] forCellWithReuseIdentifier:@"TestCell"]; _collectionView.delegate = self; _collectionView.dataSource = self; [self.view addSubview:_collectionView]; UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressMethod:)]; longPress.minimumPressDuration = 0.3f; [_collectionView addGestureRecognizer:longPress]; _dragingCell = [[TestCell alloc] initWithFrame:CGRectMake(0, 0, cellWidth, cellWidth/2.0f)]; _dragingCell.hidden = true; [_collectionView addSubview:_dragingCell];}
2)、利用UIGestureRecognizer在工作时的三种状态:开始、移动、停止这三种状态来分别实现三个主要功能
为了代码明了,分别创建三个方法,实现三个不同工能:
-(void)longPressMethod:(UILongPressGestureRecognizer*)gesture{ switch (gesture.state) { case UIGestureRecognizerStateBegan: [self dragBegin:gesture]; break; case UIGestureRecognizerStateChanged: [self dragChanged:gesture]; break; case UIGestureRecognizerStateEnded: [self dragEnd:gesture]; break; default: break; }}-(void)dragBegin:(UILongPressGestureRecognizer*)gesture{ }-(void)dragChanged:(UILongPressGestureRecognizer*)gesture{ }-(void)dragEnd:(UILongPressGestureRecognizer*)gesture{}
第一步:UIGestureRecognizerStateBegan实现定位需要被拖拽的cell1并进入准备状态
定位cell1的方法,是通过手指定位在UICollectionView的点,来找到相应的cell:
//获取被拖动IndexPath的方法-(NSIndexPath*)getDragingIndexPathWithPoint:(CGPoint)point{ NSIndexPath* dragingIndexPath = nil; //遍历所有屏幕上的cell for (NSIndexPath *indexPath in [_collectionView indexPathsForVisibleItems]) { //判断cell是否包含这个点 if (CGRectContainsPoint([_collectionView cellForItemAtIndexPath:indexPath].frame, point)) { dragingIndexPath = indexPath; break; } } return dragingIndexPath;}
代码:
-(void)dragBegin:(UILongPressGestureRecognizer*)gesture{ CGPoint point = [gesture locationInView:_collectionView]; _dragingIndexPath = [self getDragingIndexPathWithPoint:point]; if (!_dragingIndexPath) {return;} NSLog(@"拖拽开始 indexPath = %@",_dragingIndexPath); [_collectionView bringSubviewToFront:_dragingCell]; //更新被拖拽的cell _dragingCell.frame = [_collectionView cellForItemAtIndexPath:_dragingIndexPath].frame; _dragingCell.hidden = false; [UIView animateWithDuration:0.3 animations:^{ [_dragingCell setTransform:CGAffineTransformMakeScale(1.2, 1.2)]; }];}
第二步:在UIGestureRecognizerStateChanged状态下找到即将与cell1交换位置的cell2并执行交换位置的动作
这里交换位置是通过手指的移动获取和cell1交换位置的cell2,这里定义了两个全局变量:
//正在拖拽的indexpath NSIndexPath *_dragingIndexPath; //目标位置 NSIndexPath *_targetIndexPath;
_dragingIndexPath是通过第一步定位操作获取的,用于保存正在被拖动cell的indexPath;
_targetIndexPath与当前被拖动cell交换位置的cell的indexPath;
当手指移动时,让_dragingCell跟随手指的移动而移动,从而找到_targetIndexPath,并让cell1和cell2交换位置,交换位置后需要交换_dragingIndexPath和_targetIndexPath的值从而进行后续交换位置的操作。
定位_targetIndexPath的方法如下:
//获取目标IndexPath的方法-(NSIndexPath*)getTargetIndexPathWithPoint:(CGPoint)point{ NSIndexPath *targetIndexPath = nil; //遍历所有屏幕上的cell for (NSIndexPath *indexPath in _collectionView.indexPathsForVisibleItems) { //避免和当前拖拽的cell重复 if ([indexPath isEqual:_dragingIndexPath]) {continue;} //判断是否包含这个点 if (CGRectContainsPoint([_collectionView cellForItemAtIndexPath:indexPath].frame, point)) { targetIndexPath = indexPath; } } return targetIndexPath;}拖拽_dragingCell并交换位置的方法如下:
-(void)dragChanged:(UILongPressGestureRecognizer*)gesture{ NSLog(@"拖拽中。。。"); CGPoint point = [gesture locationInView:_collectionView]; _dragingCell.center = point; _targetIndexPath = [self getTargetIndexPathWithPoint:point]; NSLog(@"targetIndexPath = %@",_targetIndexPath); if (_targetIndexPath && _dragingIndexPath) { [_collectionView moveItemAtIndexPath:_dragingIndexPath toIndexPath:_targetIndexPath]; _dragingIndexPath = _targetIndexPath; }}效果如下:
第三步:UIGestureRecognizerStateEnded实现收尾工作
当手指离开屏幕拖拽结束时,隐藏_dragingCell,代码如下:
-(void)dragEnd:(UILongPressGestureRecognizer*)gesture{ NSLog(@"拖拽结束"); if (!_dragingIndexPath) {return;} CGRect endFrame = [_collectionView cellForItemAtIndexPath:_dragingIndexPath].frame; [UIView animateWithDuration:0.3 animations:^{ [_dragingCell setTransform:CGAffineTransformMakeScale(1.0, 1.0)]; _dragingCell.frame = endFrame; }completion:^(BOOL finished) { _dragingCell.hidden = true; }];}
效果如下:
XLChannelControl GitHub地址
*之前写过一个版本是利用ScrollView实现的,有兴趣的可以参考一下:点我下载
0 0
- iOS 利用UICollectionView拖拽排序 实现的仿照腾讯新闻频道管理功能 XLChannelControl
- 新闻频道管理的炫酷实现
- iOS仿照微信摇一摇功能实现
- [iOS]UICollectionView循环滚动功能的实现思路
- [iOS]UICollectionView循环滚动功能的实现思路
- 利用UICollectionView实现"新特性"功能demo
- [iOS UICollectionView拖拽排序] 菜单管理 拖拽/点选/交换位置
- [iOS UICollectionView拖拽排序] 菜单管理 拖拽/点选/交换位置
- 关于利用UICollectionView展示图片的实现
- 仿照memset的功能给出函数arrayset的具体实现
- 仿照QQ抖一抖的实现——窗口抖动功能
- 自定义Gridview实现拖拉改变顺序 仿新闻频道管理
- iOS 仿照今日头条 实现的滚动表格 XLSlideSwitch
- iOS UICollectionView 实现轮播图
- UICollectionView的重排功能
- 仿照火狐浏览器watch函数实现功能
- iOS 利用UICollectionView横向滚动、余弦函数曲线特性实现居中放大的卡片浏览工具 XLCardSwitch
- UICollectionView的无缝排序
- 大数据等最核心的关键技术:32个算法
- 打造“微信小程序”组件化开发框架
- (转)资源| TensorFlow版本号升至1.0,正式版即将到来
- tomcat启动报错“java.lang.NoSuchMethodException: org.apache.catalina.deploy.WebXml addFilter”
- 最强 Android Studio 使用小技巧和快捷键
- iOS 利用UICollectionView拖拽排序 实现的仿照腾讯新闻频道管理功能 XLChannelControl
- android手机屏幕适配
- WAMP之前还好用,今天突然启动不了了,图标一直是黄色的,一看是mysql启动不了。
- Mui 获取当前位置及在地图上显示
- Spring定时任务的几种实现
- 2016 年度开源中国新增开源软件排行榜 TOP 100
- apache 限制IP访问
- (转)Spring定时任务的几种实现
- 深入剖析Android音频之AudioTrack 2014-10-11 11:05