美文网首页
UICollectionViewCell (swift)菜单编辑

UICollectionViewCell (swift)菜单编辑

作者: 朱允见 | 来源:发表于2018-03-17 12:08 被阅读0次

写在前面

  • 最近不忙,看见一个好玩,而且很实用,既然闲来无事,就自己动手做出来,coder. 感觉还不错就是界面比较丑陋了点,不过没关系明白原理就好了!爱生活,爱钻研,爱分享
  • github 地址https://github.com/zyjian/EditCollectionViewCell
  • 记得留下你的脚印哦

进入主题

  • 首先我们还是先看看效果吧


    QQ20180316-183625.gif

需求分析

  • 类似今日头条首页的横向菜单,编辑,移动删除,都是可以的,这里我们做的是移动,删除也是同样的道理
  • 步骤拆解: 给每个cell 添加长按手势,长按进入编辑状态,此时可以拖动当前cell 移动到想要调整的位置。

原理分析

  • 主要是UIcollectionView 的一个方法的灵活使用:collectionView.moveItem(at: indexPathP, to: nextIndexPathP)
  1. 创建collectionView 并且构造数据源,这里是用的懒加载,注意这里我们使用的OC 的NSMutableArray,因为我们要使用exchange方法这样更简单
private var dataArray:NSMutableArray = {
        var array:NSMutableArray = NSMutableArray.init()
        for i in 0..<100 {
            array.add("第\(i)个")
        }
        return array
    }()
  1. 给cell 添加长按手势,并且将手势事件通过代理协议,传到viewController中
  2. 核心代码
extension ViewController:ItemCVCProtocl {
    func itemCVClongPress(long: UILongPressGestureRecognizer) {
        let cell:ItemCVC = long.view as! ItemCVC
        
        if long.state == .began {//长按开始
            
            //获取截图cell
            snapshotView = cell.snapshotView(afterScreenUpdates: true)!
            snapshotView?.center = cell.center
            collectionView.addSubview(snapshotView!)

            indexPathP = collectionView.indexPath(for: cell)!
            originalCell = cell
            originalCell.isHidden = true
            startPoint = long.location(in: collectionView)
            //colllectionViewAnimateCell(isgo: true)
        }else if(long.state == .changed){
            //移动
            let tranx : CGFloat = long.location(ofTouch: 0, in: collectionView).x - startPoint.x
            let trany : CGFloat = long.location(ofTouch: 0, in: collectionView).y - startPoint.y
            snapshotView?.center = __CGPointApplyAffineTransform((snapshotView?.center)!, CGAffineTransform.init(translationX: tranx, y: trany))
            //更新最新的开始移动
            startPoint = long.location(ofTouch: 0, in: collectionView)
            
            //计算截图和那个cell 交换
            for cell in collectionView.visibleCells {
                //跳过自己本身那个cell
                if collectionView.indexPath(for: cell) == indexPathP {
                    continue;
                }
                //计算中心距
                let space:CGFloat = sqrt(pow(snapshotView!.center.y-cell.center.y,2)+pow(snapshotView!.center.x-cell.center.x,2))
               
                //如果相交一半且两个视图Y的绝对值小于高度的一半就移动
                if space <= snapshotView!.bounds.width * 0.5
                    && (fabs(snapshotView!.center.y - cell.center.y) <= snapshotView!.bounds.height * 0.5) {
                    nextIndexPathP = collectionView.indexPath(for: cell)!
                    if nextIndexPathP.item > indexPathP.item {
                        for  i in indexPathP.item..<nextIndexPathP.item {
                            self.dataArray.exchangeObject(at: i, withObjectAt: i+1)
                        }
                    }else{
                        for  i in (nextIndexPathP.item ..< indexPathP.item).reversed() {
                            self.dataArray.exchangeObject(at: i, withObjectAt: i - 1)
                        }
                    }
                    //移动
                    collectionView.moveItem(at: indexPathP, to: nextIndexPathP)
                    indexPathP = nextIndexPathP;
                    break;

                }
            }
            
        }else if long.state == .ended {
            snapshotView?.removeFromSuperview()
            originalCell.isHidden = false
            //colllectionViewAnimateCell(isgo: false)

        }
    }
}

  • 注意:
  1. snapshotView = cell.snapshotView(afterScreenUpdates: true)! 截图这里是获取一个cell 副本,是两个不同的对象
          //移动
            let tranx : CGFloat = long.location(ofTouch: 0, in: collectionView).x - startPoint.x
            let trany : CGFloat = long.location(ofTouch: 0, in: collectionView).y - startPoint.y
            snapshotView?.center = __CGPointApplyAffineTransform((snapshotView?.center)!, CGAffineTransform.init(translationX: tranx, y: trany))

这里的 __CGPointApplyAffineTransform 创建一个平移的变化
__CGPointApplyAffineTransform((snapshotView?.center)!, CGAffineTransform.init(translationX: tranx, y: trany))
意思是相对于snapshotView?.center 这个点平移 X: tranx, y: trany,返回值是一个CGPoint

  1. 遍历collectionView中的cell(长按那个cell本身除外), 是否需要交换位置。
    需要移动的条件
    3.1 计算中心距 3.2 相交小于一半的时候

结尾寄语

艺术-海.png
如果你觉得不清晰的话,欢迎留言,互相学习共同进步!
最后再提醒一句文中的demo 在guhub地址是* github 地址https://github.com/zyjian/EditCollectionViewCell

相关文章

网友评论

      本文标题:UICollectionViewCell (swift)菜单编辑

      本文链接:https://www.haomeiwen.com/subject/rjerqftx.html