Reputation: 3058
I am trying to emulate the iOS contacts segueing between two view controllers.
I have a simple Person
class given by:
class Person {
var name = ""
}
and a UIViewController
that contains an array of Person
, which is embedded in a UINavigationController
:
class PeopleViewController: UIViewController {
var people = [Person]()
var selectedPerson: Person?
switch segueIdentifier(for: segue) {
case .showPerson:
guard let vc = segue.destination as? PersonViewController else { fatalError("!") }
vc.person = selectedPerson
}
}
This controller uses a Show segue to PersonViewController
to display the selectedPerson
:
class PersonViewController: UIViewController {
var person: Person!
}
PeopleViewController
can also add a new Person
to the array of Person
. The NewPersonViewController
is presented modally, however:
class NewPersonViewController: UIViewController {
var person: Person?
}
If a new Person
is added, I want NewPersonViewController
to dismiss but show the new Person
in the PersonViewController
that is part of the navigation stack. My best guess for doing this is:
extension NewPersonViewController {
func addNewPerson() {
weak var pvc = self.presentingViewController as! UINavigationController
if let cvc = pvc?.childViewControllers.first as? PeopleViewController {
self.dismiss(animated: false, completion: {
cvc.selectedPerson = self.person
cvc.performSegue(withIdentifier: .showPerson, sender: nil)
}
}
}
}
However, (1) I'm not too happy about forcing the downcast to UINavigationController
as I would have expected self.presentingViewController
to be of type PeopleViewController
? And (2), is there a memory leak in the closure as I've used weak var pvc = self.presentingViewController
for pvc
but not for cvc
? Or, finally (3) is there a better way of doing this?
Many thanks for any help, suggestions etc.
Upvotes: 0
Views: 45
Reputation: 5123
(1) I'm not too happy about forcing the downcast to UINavigationController as I would have expected self.presentingViewController to be of type PeopleViewController?
There is nothing wrong in downcasting. I would definitely remove force unwrapping.
(2), is there a memory leak in the closure as I've used weak var pvc = self.presentingViewController for pvc but not for cvc?
I think, there is none.
(3) is there a better way of doing this?
You can present newly added contact from NewContactVC. When you about to dismiss, call dismiss on presentingVC.
// NewPersonViewController.swift
func addNewPerson() {
// New person is added
// Show PeopleViewController modally
}
Note: Using presentingViewController this way will dismiss top two/one Modal(s). You will see only top view controller getting dismissed. If you can't determine how many modals going to be, you should look-into different solution or possibly redesigning navigation flow.
// PeopleViewController.swift
func dismiss() {
if let presentingVC = self.presentingViewController?.presentingViewController {
presentingVC.dismiss(animated: true, completion: nil)
} else {
self.dismiss(animated: true, completion: nil)
}
}
Upvotes: 0