Swift下使用UICollectionView 实现长按拖拽功能

导读

简单用Swift写了一个collectionview的拖拽点击排序效果;

拖拽排序是新闻类的App可以说是必有的交互设计,如今日头条,网易新闻等。

GitHub地址:https://github.com/wangliujiayou/Swift-dragLabel 欢迎Star.

效果

主要代码

手势长按移动

1.给CollectionViewCell添加一个长按手势.

private lazy var collectionView: UICollectionView = {
  let clv = UICollectionView(frame: self.view.frame, collectionViewLayout: ChannelViewLayout())
  clv.backgroundColor = UIColor.white
  clv.delegate = self
  clv.dataSource = self
  clv.register(ChannelViewCell.self, forCellWithReuseIdentifier: ChannelViewCellIdentifier)
  clv.register(ChannelHeaderView.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: ChannelViewHeaderIdentifier)
  let longPress = UILongPressGestureRecognizer(target: self, action: #selector(longPressGesture(_:)))
  clv.addGestureRecognizer(longPress)
  return clv
 }()

2.开始长按时对cell进行截图或拷贝一个cell,并隐藏cell.

 //MARK: - 长按开始
 private func dragBegan(point: CGPoint) {
  indexPath = collectionView.indexPathForItem(at: point)
  if indexPath == nil || (indexPath?.section)! > 0 || indexPath?.item == 0
  {return}
  let item = collectionView.cellForItem(at: indexPath!) as? ChannelViewCell
  item?.isHidden = true
  dragingItem.isHidden = false
  dragingItem.frame = (item?.frame)!
  dragingItem.text = item!.text
  //放大效果(此处可以根据需求随意修改)
  dragingItem.transform = CGAffineTransform(scaleX: 1.1, y: 1.1)
 }

3.在手势移动的时候,找到目标是的indexPatch,再调用系统的api交换这个cell和隐藏cell的位置,并且更新数据.

 //MARK: - 移动过程
 private func drageChanged(point: CGPoint) {
  if indexPath == nil || (indexPath?.section)! > 0 || indexPath?.item == 0 {return}
  dragingItem.center = point
  targetIndexPath = collectionView.indexPathForItem(at: point)
  if targetIndexPath == nil || (targetIndexPath?.section)! > 0 || indexPath == targetIndexPath || targetIndexPath?.item == 0 {return}
  // 更新数据
  let obj = selectedArr[indexPath!.item]
  selectedArr.remove(at: indexPath!.row)
  selectedArr.insert(obj, at: targetIndexPath!.item)
  //交换位置
  collectionView.moveItem(at: indexPath!, to: targetIndexPath!)
  //进行记录
  indexPath = targetIndexPath
 }

4.手势停止或取消时,移除view,显示隐藏cell. (这里手势取消也要掉用此方法)

//MARK: - 长按结束或取消
 private func drageEnded(point: CGPoint) {
  if indexPath == nil || (indexPath?.section)! > 0 || indexPath?.item == 0 {return}
  let endCell = collectionView.cellForItem(at: indexPath!)
  UIView.animate(withDuration: 0.25, animations: {
   self.dragingItem.transform = CGAffineTransform.identity
   self.dragingItem.center = (endCell?.center)!
  }, completion: {
   (finish) -> () in
   endCell?.isHidden = false
   self.dragingItem.isHidden = true
   self.indexPath = nil
  })
 }

点击移动

collectionView的点击方法,我这里分为两段,第一段为点击处理事件,第二段为点击添加添加标签(编辑状态下第一段可以点击排序)

 func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
  if indexPath.section > 0 {
   // 更新数据
   let obj = recommendArr[indexPath.item]
   recommendArr.remove(at: indexPath.item)
   selectedArr.append(obj)
   //移动方法
   collectionView.moveItem(at: indexPath, to: NSIndexPath(item: selectedArr.count - 1, section: 0) as IndexPath)
  } else {
   if isEdite {
    if indexPath.item == 0 {return}
    // 更新数据
    let obj = selectedArr[indexPath.item]
    selectedArr.remove(at: indexPath.item)
    recommendArr.insert(obj, at: 0)
    //移动方法
    collectionView.moveItem(at: indexPath, to: NSIndexPath(item: 0, section: 1) as IndexPath)
   } else {
    if switchoverCallback != nil {
     //处理点击的闭包
     switchoverCallback!(selectedArr, recommendArr, indexPath.item)
     _ = navigationController?.popViewController(animated: true)
    }
   }
  }
 }

其他

此代码只是一个效果,没有怎么封装,如果仔细看过的朋友可以知道其实没有多么复杂

点击移动

collectionView.moveItem(at: indexPath, to: NSIndexPath(item: 0, section: 1) as IndexPath)

拖拽移动

collectionView.moveItem(at: indexPath!, to: targetIndexPath!)

主要就是这两个方法,其他都是处理逻辑以及视图效果.

提示

如果你们是从iOS9开始适配的话,那么可以用系统的Api,非常简单好用,大家这里可以自己去试试.

 // Support for reordering
 @available(iOS 9.0, *)
 open func beginInteractiveMovementForItem(at indexPath: IndexPath) -> Bool // returns NO if reordering was prevented from beginning - otherwise YES
 @available(iOS 9.0, *)
 open func updateInteractiveMovementTargetPosition(_ targetPosition: CGPoint)
 @available(iOS 9.0, *)
 open func endInteractiveMovement()
 @available(iOS 9.0, *)
 open func cancelInteractiveMovement()

源码可以从这里下载

以上所述是小编给大家介绍的Swift下使用UICollectionView 实现长按拖拽功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • iOS中关于Swift UICollectionView横向分页的问题

    下面通过图文并茂的形式给大家介绍UICollectionView横向分页的问题,具体内容详情如下所示: 情况 直接看图 滚前 滚后 已经设置collectionView的isPagingEnabled为true了,可是出现了这种情况,原因就是collectionView的contentSize不够. <UICollectionView: 0x7fc565076000; frame = (0 0; 375 197); clipsToBounds = YES; gestureRecognizers

  • iOS自定义UICollectionViewFlowLayout实现图片浏览效果

    以前瀑布流的时候使用过UICollectionView,但是那时使用的是系统自带的UICollectionViewFlowLayout布局,今天看文章,看到UICollectionViewFlowLayout自定义相关的东西,于是动手写了一个简单图片浏览的demo,熟练一些UICollectionViewFlowLayout自定义布局. #import <UIKit/UIKit.h> @interface JWCollectionViewFlowLayout : UICollectionVie

  • iOS应用中UICollectionViewCell定制Button

    UICollectionViewCell定制Button 效果 特点 1.能够动态设置每行显示的按钮的个数,以及控件的摆放格式 2.实现单选或者多选的功能,实现点击事件 3.自定制按钮的显示样式 用法 1.下载源码后,将文件中的GridCollectionView.h/.m文件, CustomCollectionViewCell.h/.m文件, TypeCellClass.h/.m文件导入工程中. 2.注意:你所创建的cell要继承CustomCollectionViewCell.然后你的cel

  • IOS使用UICollectionView实现无限轮播效果

    一.案例演示 本案例Demo演示的是一个首页轮播的案例,支持手动轮播和自动轮播.知识点主要集中在UICollectionView和NSTimer的使用. 二.知识储备 2.1.UICollectionView横向布局 只需要设置UICollectionViewFlowLayout的scrollDirection为UICollectionViewScrollDirectionHorizontal即可. 2.2.NSTimer的基本使用 NSTimer的初始化: 复制代码 代码如下: + (NSTi

  • IOS简单实现瀑布流UICollectionView

    UICollectionView 比tableView 灵活,功能也强大很多.系统实现了流式布局,但用处还有很多限制. 要想实现更灵活的布局,就咬重写UICollectionViewLayout. 先看下实现效果: 废话不多说,直接上代码: 先看WaterfallCollectionLayout.m #import "WaterfallCollectionLayout.h" #define colMargin 5 #define colCount 4 #define rolMargin

  • iOS 解决UICollectionView 计算 Cell 大小的问题

    前言 API 不熟悉导致的问题,想当然的去理解果然会出问题,这里记录一下 UICollectionView 使用问题. 正文 陷阱一:minimumLineSpacing.minimumInteritemSpacing 很容易就把这两个属性设置为 0 ,这两个属性是最小行间距和最小列间距,注意是最小!!也就是说实际上可以 > 0 ,并不是间距就是 0 陷阱二:sectionInset 设置 cell 的边距.一开始我以为是每一个 cell 的边距,相邻之间会叠加效果,实际上并不是这样的,这个属性

  • Swift下使用UICollectionView 实现长按拖拽功能

    导读 简单用Swift写了一个collectionview的拖拽点击排序效果; 拖拽排序是新闻类的App可以说是必有的交互设计,如今日头条,网易新闻等. GitHub地址:https://github.com/wangliujiayou/Swift-dragLabel 欢迎Star. 效果 主要代码 手势长按移动 1.给CollectionViewCell添加一个长按手势. private lazy var collectionView: UICollectionView = { let clv

  • android RecyclerView侧滑菜单,滑动删除,长按拖拽,下拉刷新上拉加载

    本文介绍的库中的侧滑效果借鉴自SwipeMenu,并对SipwMenu的源码做了修改与Bug修复,然后才开发出的SwipeRecyclerView. 需要说明的是,本库没有对RecyclerView做大的修改,只是ItemView的封装.看起来是对RecyclerView的修改,其实仅仅是为RecyclerView添加了使用的方法API而已. 本库已经更新了三个版本了,会一直维护下去,根据小伙伴的要求,以后也会添加一些其它功能. SwipeRecyclerView将完美解决这些问题: 以下功能全

  • Android中RecyclerView实现滑动删除与拖拽功能

    前言 从Android 5.0开始,谷歌推出了新的控件RecyclerView,相对于早它之前的ListView,优点多多,功能强大,也给我们的开发着提供了极大的便利,今天自己学习一下RecyclerView轻松实现滑动删除及拖拽的效果. 如下图. 相信研究过RecyclerView的同学,应该很清楚该怎么实现这样的效果,若是用ListView,这样的效果实现起来可能就有点麻烦,但是在强大的RecyclerView面前这样的的效果只需很少的代码,因为谷歌给我们提供了强大的工具类ItemTouch

  • vue3使用自定义指令实现el dialog拖拽功能示例详解

    目录 实现el-dialog的拖拽功能 通过自定义指令实现拖拽功能 实现拖拽功能 使用方式 实现el-dialog的拖拽功能 这里指的是 element-plus 的el-dialog组件,一开始该组件并没有实现拖拽的功能,当然现在可以通过设置属性的方式实现拖拽. 自带的拖拽功能非常严谨,拖拽时判断是否拖拽出窗口,如果出去了会阻止拖拽. 如果自带的拖拽功能可以满足需求的话,可以跳过本文. 通过自定义指令实现拖拽功能 因为要自己操作dom(设置事件),所以感觉还是使用自定义指令更直接一些,而且对原

  • 基于JavaScript实现右键菜单和拖拽功能

    下面先给大家介绍下js实现的右键菜单功能,具体详情如下所示: 这一章解决的问题 1.实现右键菜单功能代码. 2.阻止默认事件的实际应用. <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>右键菜单</title> <style type="text/css"> #menu {

  • Vue自定义指令拖拽功能示例

    下面给大家分享vue自定义指令拖拽功能代码,具体代码如下所示: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>实例方法</title> <meta name="viewport" content="width=device-width, initial-scale=1

  • JS实现的简单拖拽功能示例

    本文实例讲述了JS实现的简单拖拽功能.分享给大家供大家参考,具体如下: 1.实例代码: <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>js实现拖拽</title> <style> #water{ width:400px; height:188px; background-color: #ff6600; } #water:hov

  • Draggable Elements 元素拖拽功能实现代码

    当然我们可以研究js库的源码, 也可以自己去发明轮子试试看, 其过程还是挺有趣的...下面我就来实现下页面元素的拖拽功能 现在就开始着手实现, 让我们从最顶层的方法讲起, 它用于初始化一个drag object, 方法的声明如下 function DragObject(cfg) 这里的cfg我们用一个对象来传入, 有点像Extjs里配置属性 复制代码 代码如下: var dragObj = new DragObject({ el: 'exampleB', attachEl: 'exampleBH

  • JQuery UI的拖拽功能实现方法小结

    JQuery UI提供的API极大简化了拖拽功能的开发.只需要分别在拖拽源(source)和目标(target)上调用draggable和droppable两个函数即可. 拖拽原理 首先要明确几个概念. ource:拖拽源,要拖动的元素. taerget:拖放目标,能够放入source的容器. 拖拽的动作分解如下: 1. drag start:在拖拽源(source)上按下鼠标并开始移动 2. drag move: 移动过程中 3. drag enter: 移动进入目标(target)容器 4.

  • jQuery实现的简单拖拽功能示例

    本文实例讲述了jQuery实现的简单拖拽功能.分享给大家供大家参考,具体如下: <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>拖拽</title> <style> *{ padding: 0; margin: 0; } div{ width: 100px; height: 100px; ba

随机推荐