天天看点

iOS 11 tableView 拖动cell界面闪烁的问题

使用两种逻辑实现 

private func dragCell(cell:UITableViewCell?){

        if #available(iOS 11.0, *)  {

            cell?.userInteractionEnabledWhileDragging = true

        }else {

            let pan = UILongPressGestureRecognizer(target: self, action: #selector(self.longPressGesture))

            cell?.addGestureRecognizer(pan)

        }

    }

//MARK: iOS 11以下 拖动实现

extension CRAddTripListController{

    @objc func longPressGesture(_ recognise: UILongPressGestureRecognizer) {

        let currentPoint: CGPoint = recognise.location(in: tableView)

        let currentIndexPath = tableView.indexPathForRow(at: currentPoint)

        guard let indexPath = currentIndexPath else {

            initCellImageView()

            return

        }

        guard indexPath.row < self.routeLineModel?.count ?? 0 else {

            initCellImageView()

            return

        }

        switch recognise.state {

        case .began:

            longPressGestureBegan(recognise)

            break

        case .changed:

            longPressGestureChanged(recognise)

            break

        default:

            self.touchPoints.removeAll()

            if let cell = tableView.cellForRow(at: sourceIndexPath! ){

                cell.isHidden = false

            }

            guard let routeLine = self.routeLineModel else {return}

            var tempArr:[CRPointsModel] = [CRPointsModel]()

            for line in routeLine {

                if line is CRPointsModel {

                    tempArr.append(line as! CRPointsModel)

                }

            }

            (self.parent as? CREditTripMapViewController)?.addLine(routeLineArr: tempArr)

            initCellImageView()

            break

        }

    }

    private func longPressGestureBegan(_ recognise: UILongPressGestureRecognizer) {

        self.gestureRecognizer = recognise

        let currentPoint: CGPoint = recognise.location(in: tableView)

        let currentIndexPath = tableView.indexPathForRow(at: currentPoint)

        if (currentIndexPath != nil) {

            sourceIndexPath = currentIndexPath

            currentCell = tableView.cellForRow(at: currentIndexPath! ) as! CRTripListCell

            cellImageView = getImageView(currentCell)

            cellImageView.frame = currentCell.frame

            tableView.addSubview(cellImageView)

            self.currentCell.isHidden = true

        }

    }

    private func longPressGestureChanged(_ recognise: UILongPressGestureRecognizer) {

        let selectedPoint: CGPoint = recognise.location(in: tableView)

        var selectedIndexPath = tableView.indexPathForRow(at: selectedPoint)

        if selectedIndexPath == nil || selectedIndexPath?.row == 0 {

            ///第一个cell 不可以移动

            selectedIndexPath = IndexPath(row: 1, section: 0)

        }

        if tableView.numberOfSections == 1 {

            self.touchPoints.append(selectedPoint)

            if self.touchPoints.count > 2 {

                self.touchPoints.remove(at: 0)

            }

            var center = cellImageView.center

            center.y = selectedPoint.y

            // 快照随触摸点x值改变量移动

            let Ppoint = self.touchPoints.first

            let Npoint = self.touchPoints.last

            let moveX = Npoint!.x - Ppoint!.x

            center.x += moveX

            cellImageView.center = center

            if ((selectedIndexPath != nil) && selectedIndexPath != sourceIndexPath) {

                tableView.beginUpdates()

                let cellmode = routeLineModel![sourceIndexPath!.row]

                objc_sync_enter(self)

                self.routeLineModel!.remove(at: sourceIndexPath!.row)

                if selectedIndexPath!.row < self.routeLineModel!.count {

                    self.routeLineModel!.insert(cellmode, at: selectedIndexPath!.row)

                }else {

                    self.routeLineModel!.append(cellmode)

                }

                self.mapDrawingLine(model: self.sortCRJourneyDetailModel(model: self.routeLineModel))

                objc_sync_exit(self)

                self.tableView.moveRow(at: sourceIndexPath!, to: selectedIndexPath!)

                tableView.endUpdates()

                sourceIndexPath = selectedIndexPath

            }

        }

    }

    private func initCellImageView() {

        self.cellImageView.alpha = 0.0

        self.cellImageView = UIImageView()

        self.cellImageView.removeFromSuperview()

        tableView.reloadData()

    }

    // MARK: - 截图

    private func getImageView(_ cell: UITableViewCell) -> UIImageView {

        UIGraphicsBeginImageContextWithOptions(cell.bounds.size, false, 0)

        cell.layer.render(in: UIGraphicsGetCurrentContext()!)

        let image = UIGraphicsGetImageFromCurrentImageContext()

        UIGraphicsEndImageContext()

        let imageView = UIImageView(image: image)

        return imageView

    }

}

//MARK: iOS 11 拖动实现

extension CRAddTripListController:UITableViewDragDelegate,UITableViewDropDelegate{

    @available(iOS 11.0, *)

    func tableView(_ tableView: UITableView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {

        let cellmode = self.routeLineModel![indexPath.row]

        if cellmode is CRPointsModel {

            let image = UIImage()

            let provider = NSItemProvider(object: image)

            let item = UIDragItem(itemProvider: provider)

            return [item]

        }else {

            return []

        }

    }

    // MARK: UITableViewDropDelegate

    @available(iOS 11.0, *)

    func tableView(_ tableView: UITableView, performDropWith coordinator: UITableViewDropCoordinator) {

    }

    @available(iOS 11.0, *)

    func tableView(_ tableView: UITableView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UITableViewDropProposal {

        return UITableViewDropProposal(operation: .move, intent: .insertAtDestinationIndexPath)

    }

    @available(iOS 11.0, *)

    func tableView(_ tableView: UITableView, canHandle session: UIDropSession) -> Bool {

        // Only receive image data

        return session.canLoadObjects(ofClass: UIImage.self)

    }

}