0

I am re-creating a simple version of the snapchat app and have run into a small annoying issue that I can't seem to figure out a fix for.

I've taken a look at a few answers like this one but no luck.

The overall concept is the same as snapchat user clicks cell, an image is displayed for an x amount of time then disappears.

Here is what happens currently: enter image description here

As you can see there is a slight delay between the click and the image actually being presented.

Here is the CustomeIvageView I use in order to do the actual image loading:

    import UIKit

    class CustomImageView: UIImageView {

        func loadImage(urlString: String){

            guard let url = URL(string: urlString) else {return}
            URLSession.shared.dataTask(with: url) { (data, response, err) in
                if let err = err {
                    print("failed to fetch user profile photoes", err)
                }

                guard let imageData = data else {return}
                let photoImage = UIImage(data: imageData)


                DispatchQueue.main.async {
                    self.image = photoImage
                }
            }.resume()
        }
    }

And then in my view controller, I have this:

class PictureViewController: UIViewController {

    var snap: Snap? {
        didSet{
            usernameLabel.text = snap?.fromUser?.username
            guard let imageUrl = snap?.imageUrl else {return}
            previewImageView.loadImage(urlString: imageUrl)
        }
    }

    lazy var previewImageView: CustomImageView = {
        let iv = CustomImageView()
        iv.contentMode = .scaleAspectFill
        return iv
    }()


    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(previewImageView)
        previewImageView.anchor(top: view.topAnchor, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)


        guard let timer = snap?.timer else {return}

        let delayTime = Double(timer)
        delay(delayTime){
            self.handleCancel()
        }
    }

    func delay(_ delay:Double, closure:@escaping ()->()) {
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(Int64(delay * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC), execute: closure)
    }

    func handleCancel(){
        self.dismiss(animated: false) {
        }
    }

EDIT: Showing where I set PictureViewController. I omitted code for brevity.

import UIKit
import Firebase

class ChatViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout{

    var recievedSnaps = [Snap]()
    var mappedSnaps = [String: [Snap]]()
    let cellId = "cellId"

    let picMessageView = PictureViewController()

    override func viewDidLoad() {
        super.viewDidLoad()

        //Removed code for brevity

    }

     //OMITTED CODE FOR BREVITY


    override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        let cell = collectionView.cellForItem(at: indexPath) as! ChatCell

        picMessageView.snap = cell.snap

        self.present(picMessageView, animated: false, completion: nil)


    }

}
mufc
  • 695
  • 3
  • 16
  • 31

1 Answers1

0

I tried your code and it is working fine except for the part when you are dismissing the PictureViewController. You need to call the dismiss inside the main UI thread so that it will executed properly.

func handleCancel(){
    DispatchQueue.main.async {
      self.dismiss(animated: false, completion: nil)      
    }
}
Christian Abella
  • 5,747
  • 2
  • 30
  • 42