Search code examples
ios3dtouch

3d touch on single photo. iOS, Swift


Can I add 3d touch to a single photo that is not in a collection view or a table view. everything i seem to see on it uses a collection view.

I have a single picture that shows on a view with information but the picture is a small square I have it so that I can tap the photo and it opens in a view controller but i wanted to add peek to it.


Solution

  • Yes, all you need to do is conform to UIViewControllerPreviewingDelegate. When a deep press is registered the

    func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController?
    

    method will be called. If you return a non-nil view controller a peek and pop interaction will be initiated.

    For example, here ViewController as a small centered image view. When the view is 3D touched we can check to see if the location is inside the image view. If so, we can preview the next view controller:

    class ViewController: UIViewController {
    
        @IBOutlet weak var imageView: UIImageView!
    
        override func viewDidLoad()
        {
            super.viewDidLoad()
            if traitCollection.forceTouchCapability == .available
            {
                registerForPreviewing(with: self, sourceView: view)
            }
            else
            {
                print("3D Touch Not Available")
            }
        }
    
    }
    
    extension ViewController: UIViewControllerPreviewingDelegate
    {
        func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController?
        {
            let convertedLocation = view.convert(location, to: imagePhoto)
            if imagePhoto.bounds.contains(convertedLocation)
            {
                // Init the peek view controller, set relevant properties, and return it
                let otherViewController = self.storyboard?.instantiateViewController(withIdentifier: "\(OtherViewController.self)") as? OtherViewController
                otherViewController?.image = imageView.image
                previewingContext.sourceRect = imageView.frame
                return otherViewController
            }
            else
            {
                return nil
            }
        }
    
        func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController)
        {
            // Present or push the view controller
            present(viewControllerToCommit, animated: true)
        }
    }
    

    Where OtherViewController is a view controller with an image view that takes up the entire view.

    Which gives a result of:

    enter image description here