GJ Nilsen GJ Nilsen - 23 days ago 6
iOS Question

Having problems with Xcode 8.1 and unwind segues

I can't get unwind segue to work with the latest

Xcode 8.1
GM. I'm just wondering if I'm the only one, or someone else is experiencing the same. I have set up the view-controllers as before, it worked in
Xcode
8.0, but now I'm having no luck. Tried to clean and so on, but nothing helps. I would like someone else could test it as well before I file a radar...

The
view controller
that first instantiated the
view controller
is having the following code:

@IBAction func unwindToSettingsTableViewController(_ segue: UIStoryboardSegue) {
print("unwind")
}


I also tried without the underscore, but that did not help.
When setting up this, one should be able to
ctrl
drag from files owner to exit, and get up the unwind segues:
No unwind segue showing up here...
So either am I doing it completely wrong (I dont think so, it worked perfectly fine before), or there is a bug in
Xcode 8.1


I tried to do the same in a new project, and then it worked properly. So I guess there is something wrong with my project or storyboard file.

Update

Since the storyboards are holding rather small scenes, I just deleted it, and recreated it again, using the same classes for the view controllers and so on. And now it works. So having exactly the same code, but a fresh storyboard, makes me think it is some bug.

Answer

I found the reason for the weird behaviour. It needs a little explanation on how we build our apps to understand the hows and whys.

First of all, instead of having big ViewControllers, we tend to split them into smaller chunks. This way, we always know where the "business logic" is, where to find the data source, outlets and actions, and so on. A typical TableViewController is made like this:

SampleTVC.swift

class SampleTableViewController: UITableViewController {
    @IBOutlet var someLabel: UILabel!
    @IBOutlet var someButton: UIButton!

    @IBAction func unwindHere(_ segue: UIStoryBoardSegue) {
        doSomething()
    }

}

SampleDelegate+DataSource.swift

extension SampleTableViewController {
    override func numberOfSections(in tableView: UITableView) -> Int
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
}

SampleFetchedResultsController.swift

extension SampleTableViewController: NSFetchedResultsControllerDelegate {
    var fetchedResultsController: NSFetchedResultsController<Item>
    func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>)
    func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType)
    func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?)
    func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>)
}

I tried here to connect up the code with a TVC made up of these smaller bits, and no way, no rewind segue pops up.

So, putting all the extensions in the same file as the SampleTableViewController, it would still not work.

The solution was to remove all the extensions, and put all functions into the class itself, then it worked as it should. It does not make much sense, it's clearly a bug.

Comments