Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ability to shorten UIDragInteraction's long press timing

I am currently using UIDragInteraction and UIDropInteraction made available in iOS 11 to make a simple drag and drop feature, where user could drag an UIImageView onto a UIView.

I realized that one unintuitive element to this is that the UIDragInteraction requires a long press of at least a second to work. I was wondering if there is a way to shorten the long press duration? The docs on Apple doesn't seem to highlight this.

Thanks!

Implementation pasted below for reference:

class ViewController: UIViewController {

    @IBOutlet var imageView: UIImageView!
    @IBOutlet var dropArea: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()

        let dragInteraction = UIDragInteraction(delegate: self)
        imageView.addInteraction(dragInteraction)
        dragInteraction.isEnabled = true
        let dropInteraction = UIDropInteraction(delegate: self)
        dropArea.addInteraction(dropInteraction)
    }
}

extension ViewController: UIDragInteractionDelegate {
    func dragInteraction(_ interaction: UIDragInteraction, itemsForBeginning session: UIDragSession) -> [UIDragItem] {
        guard let image = imageView.image
            else { return [] }

        let itemProvider = NSItemProvider(object: image)
        return [UIDragItem(itemProvider: itemProvider)]
    }
}

extension ViewController: UIDropInteractionDelegate {
    func dropInteraction(_ interaction: UIDropInteraction, sessionDidUpdate session: UIDropSession) -> UIDropProposal {
        return UIDropProposal(operation: .copy)
    }

    func dropInteraction(_ interaction: UIDropInteraction, performDrop session: UIDropSession) {
        guard let itemProvider = session.items.first?.itemProvider,
            itemProvider.canLoadObject(ofClass: UIImage.self)
            else { return }

        itemProvider.loadObject(ofClass: UIImage.self) { [weak self] loadedItem, error in
            guard let image = loadedItem as? UIImage
                else { return }

            DispatchQueue.main.async {
                self?.dropArea.image = image
            }
        }
    }
}
like image 326
daspianist Avatar asked Jan 09 '18 19:01

daspianist


People also ask

What affects duration of drug action?

Duration of drug action depends on several factors: the absolute amount of drug given; the pharmaceutical preparation; the reversibility of drug action; the half-life of the drug; the slope of the concentration-response curve; the activity of metabolites, and the influence of disease on drug elimination.

What are the 3 types of drug interactions?

There are three types of drug interactions: Drug-drug interaction: A reaction between two (or more) drugs. Drug-food interaction: A reaction between a drug and a food or beverage. Drug-condition interaction: A reaction that occurs when taking a drug while having a certain medical condition.

How can the risk of drug interaction be minimized?

Use drug interaction checkers. Check out the Drugs.com Drug Interactions Checker. Enter all prescriptions, over-the-counters, vitamins, dietary supplements and herbal remedies you are taking. If you find a drug interaction do not stop taking your medicine but discuss it with your healthcare provider.


2 Answers

There's no obvious way to do this, but I was just facing the same problem and took a peek into the gesture recognizers of the view that the dragInteraction is attached to. It a _UIDragLiftGestureRecognizer which is not part of the public API, but turns out this is just a subclass of UILongPressGestureRecognizer.

So, after having added your UIDragInteraction to your view, and after having added that view to the view hierachy (since I'm using a custom UIView subclass I just added it into didMoveToSuperview()), you can do something like this:

if let longPressRecognizer = gestureRecognizers?.compactMap({ $0 as? UILongPressGestureRecognizer}).first {
    longPressRecognizer.minimumPressDuration = 0.1 // your custom value
}
like image 55
julsh Avatar answered Oct 20 '22 17:10

julsh


I was trying to do this from Xamarin.iOS inside an UIView implementing the IUIDragInteractionDelegate interface. In its constructor I made a SetupDragNDrop method that allows to drag the view without that default delay/latency to catch the view. I leave the code down below in case it's useful for somebody else:

    #region Private Fields
    private UIDragInteraction _UIDragInteraction;
    #endregion

    void Initialize()
    {
        SetupDragNDrop();
    }

    private void SetupDragNDrop()
    {
        UserInteractionEnabled = true;
        _UIDragInteraction = new UIDragInteraction(this);
        AddInteraction(_UIDragInteraction);

        // On iPad, this defaults to true. On iPhone, this defaults to 
        // false. Since this app should work on the iPhone, enable the the 
        // drag interaction.
        _UIDragInteraction.Enabled = true;

        SetupDragDelay();
    }

    private void SetupDragDelay()
    {

        UILongPressGestureRecognizer longPressGesture = new UILongPressGestureRecognizer();

        GestureRecognizers?.ToList().ForEach(gesture =>
        {
            var x = gesture as UILongPressGestureRecognizer;
            if (x != null)
            {
                longPressGesture = x;
            }
        });

        longPressGesture.MinimumPressDuration = 0.0;
    }
like image 44
Juansero29 Avatar answered Oct 20 '22 17:10

Juansero29