Setup: Create a boilerplate iOS Master-Detail app in Xcode and run it. Everytime you click on a master item it re-creates the detailVC and configures it to display the new data.
Premise: Often this is what I want, but other times it does little more than change the text in a single label. Doesn't it make more sense to re-use the existing DetailVC? (at least in this case)
So what's the best way to do this?
Contemplation: When I look at the boilerplate code I see the MasterVC creates class scoped var for the detailVC.
var detailViewController: DetailViewController? = nil
It sets this value in viewDidLoad
, but it then never uses it for anything. Huh? In prepare(for:sender:)
we get this code
let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController
which creates a new instance of the DetailViewController
. If you put a break point in after it's created and compare it to the class var detailViewController
you can see they are different.
The UIStoryboardSegue
is creating my new DetailViewController
which can easily be confirmed by looking at the documentation.
You do not create segue objects directly. Instead, the storyboard runtime creates them when it must perform a segue between two view controllers.
I could remove the segue on row select and manually call the method on my detailVC and that's probably the easiest, but segues are so purty and visual in IB. I could could probably create a custom segue. What else could I do and is there a clear "best" way?
In case someone else has this question, here is my solution until someone comes up with something better.
Go to Interface Builder and remove the showDetail
segue which goes from the master tableview to the detailVC. Then go into the MasterViewController class and remove the prepare(for:sender:)
function.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showDetail" {
if let indexPath = tableView.indexPathForSelectedRow {
let object = objects[indexPath.row] as! NSDate
let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController
controller.detailItem = object
controller.navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem
controller.navigationItem.leftItemsSupplementBackButton = true
}
}
}
Create a new function in Table View area (this new function is part of UITableViewDelegate
)
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
detailViewController?.detailItem = object
}
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.