美文网首页
UicollectionviewCell移动/交换位置

UicollectionviewCell移动/交换位置

作者: 遥遥领先M | 来源:发表于2020-01-06 13:42 被阅读0次
UicollectionviewCell交换位置
1  2  3  4
5  6  7  8
9  10 11 12

我只想换6号和4号手机。因此,重新排序后,单元格将

1  2  3  6
5  4  7  8
9  10 11 12

在本教程中,在程序的开头,集合视图如下所示-


1Kntp.png

如果我把星巴克放在罗斯·泰勒的上面,就会发生这种事。-


jubEP.png

注意莎拉·康纳有星巴克。
我想控制细胞的重新排列,这样罗斯·泰勒和星巴克的位置就会互换。
我该怎么做?

最佳答案:

简单的解决方案是通过简单地沿屏幕中的平移移动单元格,并在手势结束于另一个单元格的位置时交换(使用您自己的动画和数据源更新),实现您自己的交互式单元格排序行为。这是一个工作样本:

class ViewController: UIViewController, UICollectionViewDataSource {

    var arr: [String] = (0...100).map { return "\($0)" }

    lazy var collectionView: UICollectionView =  {
        let layout = UICollectionViewFlowLayout()
        let cv: UICollectionView = UICollectionView(frame: self.view.bounds, collectionViewLayout: layout)
        cv.register(Cell.self, forCellWithReuseIdentifier: Cell.id)
        layout.itemSize = CGSize(width: view.bounds.width/3.5, height: 100)
        cv.dataSource = self
        cv.addGestureRecognizer(longPressGesture)
        return cv
    }()

    lazy var longPressGesture: UILongPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(self.handleLongGesture(gesture:)))

    private var movingCell: MovingCell?

    override func viewDidLoad() {
        super.viewDidLoad()
        view = collectionView
    }

    @objc func handleLongGesture(gesture: UILongPressGestureRecognizer) {

        var cell: (UICollectionViewCell?, IndexPath?) {
            guard let indexPath = collectionView.indexPathForItem(at: gesture.location(in: collectionView)),
                let cell = collectionView.cellForItem(at: indexPath) else { return (nil, nil) }
            return (cell, indexPath)
        }

        switch(gesture.state) {

        case .began:
            movingCell = MovingCell(cell: cell.0, originalLocation: cell.0?.center, indexPath: cell.1)
            break
        case .changed:

            /// Make sure moving cell floats above its siblings.
            movingCell?.cell.layer.zPosition = 100
            movingCell?.cell.center = gesture.location(in: gesture.view!)

            break
        case .ended:

            swapMovingCellWith(cell: cell.0, at: cell.1)
            movingCell = nil
        default:
            movingCell?.reset()
            movingCell = nil
        }
    }

    func swapMovingCellWith(cell: UICollectionViewCell?, at indexPath: IndexPath?) {
        guard let cell = cell, let moving = movingCell else {
            movingCell?.reset()
            return
        }

        // update data source
        arr.swapAt(moving.indexPath.row, indexPath!.row)

        // swap cells
        animate(moving: moving.cell, to: cell)
    }

    func animate(moving movingCell: UICollectionViewCell, to cell: UICollectionViewCell) {
        longPressGesture.isEnabled = false

        UIView.animate(withDuration: 0.4, delay: 0, usingSpringWithDamping: 0.1, initialSpringVelocity: 0.7, options: UIViewAnimationOptions.allowUserInteraction, animations: {
            movingCell.center = cell.center
            cell.center = movingCell.center
        }) { _ in
            self.collectionView.reloadData()
            self.longPressGesture.isEnabled = true
        }
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return arr.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell: Cell = collectionView.dequeueReusableCell(withReuseIdentifier: Cell.id, for: indexPath) as! Cell
        cell.titleLable.text = arr[indexPath.row]
        return cell
    }

    private struct MovingCell {
        let cell: UICollectionViewCell
        let originalLocation: CGPoint
        let indexPath: IndexPath

        init?(cell: UICollectionViewCell?, originalLocation: CGPoint?, indexPath: IndexPath?) {
            guard cell != nil, originalLocation != nil, indexPath != nil else { return nil }
            self.cell = cell!
            self.originalLocation = originalLocation!
            self.indexPath = indexPath!
        }

        func reset() {
            cell.center = originalLocation
        }
    }

    final class Cell: UICollectionViewCell {
        static let id: String = "CellId"

        lazy var titleLable: UILabel = UILabel(frame: CGRect(x: 0, y: 20, width: self.bounds.width, height: 30))

        override init(frame: CGRect) {
            super.init(frame: frame)
            addSubview(titleLable)
            titleLable.backgroundColor = .green
            backgroundColor = .white
        }

        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
        }
    }
}
UicollectionviewCell移动位置
import UIKit

private let cellID: String = "CellId"

class MCViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
    
    lazy var cells: [String] = {
        var tmpArray: [String] = []
        for i in 0..<100 {
            var text = "\(i)"
            tmpArray.append(text)
        }
        return tmpArray
    }()
    
    @IBOutlet weak var collectionView: UICollectionView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 消除顶部白条
        //self.automaticallyAdjustsScrollViewInsets = false
        
        // 添加长按手势, 不使用CollectionViewController的时候需要自行设置手势
        let longPressGes = UILongPressGestureRecognizer(target: self, action: #selector(longPressAction(_:)))
        self.collectionView.addGestureRecognizer(longPressGes)
    }
    
    
    /// 响应长按手势(排序)
    ///
    /// - Parameter gesture: 需要传入手势检测器,因为要判断长按的位置等等属性
    @objc func longPressAction(_ gesture: UILongPressGestureRecognizer) {
        // 判断长按的状态
        switch gesture.state {
        case .began:
            // 获取选择位置
            // indexPathForItem获取Item所处的indexPath
            // indexPath是表格或列表推算出当前row和col的属性
            // ***GestureRecognizer的location方法返回在所处view的一个CGPoint属性
            guard let selectedIndexPath = self.collectionView.indexPathForItem(at: gesture.location(in: collectionView)) else { return }
           collectionView.beginInteractiveMovementForItem(at: selectedIndexPath)
        case .changed:
            // 移动了
            collectionView.updateInteractiveMovementTargetPosition(gesture.location(in: collectionView))
        case .ended:
            // 结束移动
            collectionView.endInteractiveMovement()
        default:
            collectionView.cancelInteractiveMovement()
        }
    }
    
}

extension MCViewController {
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return self.cells.count
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellID, for: indexPath) as! MCTextCollectionViewCell
        cell.textLabel.text = cells[indexPath.item]
        
        return cell
    }
    
    // 实现重排的关键
    func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
        let tmpCell = cells.remove(at: sourceIndexPath.item)
        cells.insert(tmpCell, at: destinationIndexPath.item)
    }
}
import UIKit

private let cellID: String = "CellId"

class MCCollectionViewController: UICollectionViewController {
    
    lazy var cells: [String] = {
        var tmpArray: [String] = []
        for i in 0..<100 {
            var text = "\(i)"
            tmpArray.append(text)
        }
        return tmpArray
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }

}

extension MCCollectionViewController {
    
    // MARK: UICollectionViewDataSource
    
    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return self.cells.count
    }
    
    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellID, for: indexPath) as! MCTextCollectionViewCell
        cell.textLabel.text = cells[indexPath.item]
        
        return cell
    }
    
    // 实现重排的关键
    override func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
        let tmpCell = cells.remove(at: sourceIndexPath.item)
        cells.insert(tmpCell, at: destinationIndexPath.item)
    }
}

相关文章

  • UicollectionviewCell移动/交换位置

    UicollectionviewCell交换位置 我只想换6号和4号手机。因此,重新排序后,单元格将 在本教程中,...

  • UICollectionViewCell 位置获取

    // 获取 cell 在屏幕中的位置 , 根据 cell 的 x ,判断cell的位置,是否显示 line

  • UICollectionViewCell 移动攻略

    最近产品出了一个需要移动UICollectionViewCell需求,其中有点小挫折,与大家分享一下。 UICol...

  • iOS 长按移动UITableViewCell

    之前写了一篇有关于UICollectionViewCell的长按移动的文章:iOS 长按移动UICollectio...

  • tableViewCell拖拽移动并且交换

    开发过程中,可能会遇上要求拖拽cell,移动到指定的位置,然后交换cell的位置。tableView协议可以满足,...

  • UICollectionViewCell的移动以及删除

    最近,在一些iOS开发群里看到好多人都在询问一些UICollectionViewCell的移动以及删除的轮子,本着...

  • 数组中插入一个元素

    数组两项元素交换位置 把数组里的某一项移动到某一位置(常见拖拽的时候drop函数里用)

  • 交换位置

    2014年1月19日 0:34:22 晴 他不知道为什么,他俩竟然交换了位置。 他曾经热情地对祂,并把祂放在一个...

  • 交换位置

    一个太阳高照的下午,可爱的小兔子、聪明的乌龟和毛茸茸的小松鼠一起拿着书,兴高采烈地来到公园里认认真真地看...

  • CollectionView总结 OC 2020

    UICollectionViewCell 实现UICollectionViewCell自适应文字宽度https:/...

网友评论

      本文标题:UicollectionviewCell移动/交换位置

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