简体   繁体   中英

Closing a view controller through its delegate in Swift

I have the following protocols:

protocol MyDelegate: class {
    func closeViewController()
}

protocol MyProtocol: class {
    weak var delegate: SomeClass? {get set}
}

And the following class:

class SomeClass: MyDelegate {
    var myViewController: UIViewController

    init(myViewController: UIViewController){
        self.myViewController = myViewController
        self.myViewController.delegate = self
    }    

    func closeViewController() {
        myViewController.dismiss(animated: true, completion: nil)
    }
}

The idea here is that SomeClass takes a view controller and sets itself as the view controller's delegate.

The View controller is defined like so:

class SomeViewController: UIViewController, MyProtocol {
    weak var delegate: SomeClass?

    ...

    @IBAction func close(_ sender: Any) {
        delegate?.closeViewController()
    }

    ...
}

where the close function is mapped to a close button in storyboard.

I initialize both SomeClass and my view controller inside another view controller.

var someViewController = // initialized here
var someClass = SomeClass(myViewController: someViewController)
self.present(someViewController, animated: true, completion: nil)

However, when I press the close button, nothing happens at all. The view controller does not dismiss.

On the other hand, if I change the close() function in my ViewController to be:

@IBAction func close(_ sender: Any) {
    self.dismiss(animated: true, completion: nil)
}

Then it dismisses itself as expected, showing that the function is correctly mapped to the button.

How do I go about dismissing my view controller from another class?

You have declared delegate property as weak and there isn't any strong reference of SomeClass object. Object should be nil by the time close button callback and closeViewController() is never called.

If I may suggest that you've made this much more complicated than it needs to be. I would ditch the protocol altogether and just implement a simple delegate pattern.

class SomeViewController {
    func close() {
        print("did close")
    }
}

class SomeObject {
    weak var delegate: SomeViewController?
    func close() {
        delegate?.close()
    }
}

let viewController = SomeViewController()
let object = SomeObject()
object.delegate = viewController

object.close() // prints "did close"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM