Apple John
Apple John

Reputation: 77

self dismiss does not work on iOS 12 but works on higher versions

I have a small snippet of code to dismiss the presented VC:

UIView.animate(withDuration: 0.3, animations: { [weak self] in
            
    guard let self = self else {
        return
    }
            
    DispatchQueue.main.async {
        self.stackViewMain.frame = CGRect(origin: CGPoint(x: self.stackViewMain.frame.origin.x, y: self.view.bounds.height), size: self.stackViewMain.bounds.size)
    }
}) { _ in
    weak var weakSelf = self
    self.dismiss(animated: true, completion: {
        weakSelf?.viewModel.animationdDidFinishControllerWillDismiss()
    })
}

So the issue is in this part:

self.dismiss(animated: true, completion: {
    weakSelf?.viewModel.animationdDidFinishControllerWillDismiss()
})

I just found out that self.dismiss is not being run and completionHandler is not being fired on iOS 12 but everything works as expected on iOS 13.

Can someone explain me why it does not work and how can I fix it?

Upvotes: 1

Views: 413

Answers (1)

Zhou Haibo
Zhou Haibo

Reputation: 2068

Animation part is wrong.

  • You don't need to use DispatchQueue. Animation is always on main thread, Read this

  • Remove all weak self. Animations and completion are not retained by self so there is no risk of strong retain cycle. Read this

I have tested this on iOS 12 and everything works fine. See below example.

You just show a snipper of code, I guess there is retain cycle exist so you cannot dismiss current VC. You may use Debug Memory graph in Xcode to check it.

import UIKit

class ViewControllerA: UIViewController {
    
    lazy var dismissButton: UIButton = {
        let bt = UIButton(frame: CGRect(x: 0, y: 0, width: view.frame.size.width / 4, height: view.frame.size.width / 6.5))
        bt.setTitle("Click", for: .normal)
        bt.backgroundColor = .systemRed
        bt.layer.cornerRadius = 12
        bt.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
        return bt
    }()
    
    lazy var aView: UIView = {
        let v = UIView(frame: CGRect(x: 0, y: 50, width: view.frame.size.width / 2, height: view.frame.size.width / 2))
        v.backgroundColor = .brown
        return v
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.backgroundColor = .systemGreen
        view.addSubview(dismissButton)
        view.addSubview(aView)
        dismissButton.center = view.center
        aView.center.x = self.view.center.x
    }
    
    @objc func buttonTapped() {
        UIView.animate(withDuration: 2, animations: {
            self.aView.frame.size.width /= 2
            self.aView.frame.size.height /= 2
        }) { finished in
            self.dismiss(animated: true, completion: {
                print("dismiss")
            })
        }
    }
}

Upvotes: 1

Related Questions