Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drag and drop - UIGestureRecognizer - View added not where I want to

I have this 2 tableViews (All Services available and service offered) in a splitViewController. The idea is that then the cell is moved across the center of the screen, it moves to the service offered table view. Everything works except then the touch `.began, the cell is being added to the top of the tableView covering the navBar. enter image description here

On .changed it follows my finger enter image description here

I would like the view/cell to be added where the touch began, on top of the "ServiceCell" I am touching. I tried adding it to the splitViewController.view but I think there is something wrong with my logic.

Here the code:

func didLongPressCell (gr: UILongPressGestureRecognizer) {
    let serviceCell:ServiceCell =  gr.view as! ServiceCell
    switch gr.state {
    case .began:

        let touchOffsetInCell = gr.location(in: gr.view)
        let dragEvent = DragganbleServiceCell()
        mDraggableServiceCell = dragEvent.makeWithServiceCell(serviceCell: serviceCell, offset: self.tableView.contentOffset, touchOffset: touchOffsetInCell)
        self.splitViewController?.view.addSubview(mDraggableServiceCell!)

    case .changed:
        let cp:CGPoint = gr.location(in: self.view)
        let newOrigin = CGPoint(x: (cp.x), y: (cp.y) - (mDraggableServiceCell?.touchOffset?.y)!)
        UIView.animate(withDuration: 0.1, animations: {
            self.mDraggableServiceCell?.frame = CGRect(origin: newOrigin, size: (self.mDraggableServiceCell?.frame.size)!)  
        })

    case .ended:
        let detailViewNC = self.splitViewController?.viewControllers[1] as! UINavigationController
        let detailView = detailViewNC.topViewController as! ServiceOfferedTableViewController
        if (mDraggableServiceCell?.frame.intersects(detailView.tableView.frame))! {

        onDragEnded(serviceCell:serviceCell)
        }else{

        mDraggableServiceCell?.removeFromSuperview()

        }
    default:
        print("Any other action?")
    }
}

In DraggableServiceCell:

class DragganbleServiceCell: ServiceCell {

    var originalPosition:CGPoint?
    var touchOffset:CGPoint?

    func makeWithServiceCell(serviceCell:ServiceCell, offset:CGPoint, touchOffset:CGPoint)->DragganbleServiceCell{

        let newFrame =  CGRect(x: serviceCell.frame.origin.x, y: serviceCell.frame.origin.y, width: serviceCell.frame.size.width, height: serviceCell.frame.size.height)
        let dragCell = DragganbleServiceCell(frame: newFrame)
       dragCell.touchOffset = touchOffset
        dragCell.service = serviceCell.service
        dragCell.serviceName.text = serviceCell.service?.service_description
        return dragCell
    }

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        self.containingView.backgroundColor = UIColor.rgb(230, green: 32, blue: 31)
        self.serviceName.textColor = .white
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
like image 960
Mat Avatar asked Oct 18 '22 20:10

Mat


1 Answers

Your problem is in makeWithServiceCell(serviceCell:ServiceCell, offset:CGPoint, touchOffset:CGPoint) -> DragganbleServiceCell. The frame of your serviceCell is relative to the tableView that contains it instead of UISplitViewController's view and you are never using the offset or touchOffset values to correct that. So try adjusting the frame in the same way you are doing it in the .changed event.

You might even find that the convert(_:to:) method on UIView might be useful to do CGPoint transformations between two views. See more details here.

like image 163
Mihai Fratu Avatar answered Oct 30 '22 20:10

Mihai Fratu