简体   繁体   中英

UISplitViewController, reuse DetailViewController (Swift)

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.

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