0

I have pursued the internet for an answer and following steps in apple documentation but to no avail. I have two view controllers. One which contains a list of favourite items (FavouriteTableViewController), another which contains the details of the item being added to the list of favourites (ExplorationDetailViewController).

I have a save button on the navigation bar (from a navigation controller scene) in the ExplorationDetailViewController that I want to click to kick off the unwind segue. I have carried out the following steps, but when I click on the save button, it is completely unresponsive. I am including the most relevant code for the unwind.

I have created prepareforsegue function in ExplorationResultViewController from where I will be passing data for an image and a label to the other ViewController as part of the unwind segue

class ExplorationResultViewController: UIViewController {
    var exploration_result: Favourites?
    @IBOutlet weak var ExplorationLabel: UILabel!
    @IBOutlet weak var ExplorationPhoto: UIImageView!

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        // Pass the selected object to the new view controller.
        super.prepare(for: segue, sender: sender)


        let photo = ExplorationPhoto.image
        let name = ExplorationLabel.text ?? ""

        exploration_result = Favourites(name: name, photo: photo)
    }

Then in the FavouriteTableViewController, I have added an unwindtoHere method which adds image and label to the list.

class FavouritesTableViewController: UITableViewController {

    // MARK: Properties
    var favourites = [Favourites]()

    // MARK: Actions
    @IBAction func unwindToFavouriteList(sender: UIStoryboardSegue) {
        if let sourceViewController = sender.source as? ExplorationResultViewController, let favourite = sourceViewController.exploration_result{
            // Add a new meal.
            let newIndexPath = IndexPath(row: favourites.count, section: 0)
            favourites.append(favourite)
            tableView.insertRows(at: [newIndexPath], with: .automatic)

        }

Then going into my storyboard, I control+drag the Save button in the ExplorationDetailViewController and connect it to the exit item at the top of the scene. My unwind method appears in the pop up as: 'unwindToFavouriteListWithSender'. I select this.

I should be good to go now, but when I run the simulator and click the Save button, it is absolutely unresponsive. See StoryBoard Design Please help

Sherry
  • 353
  • 3
  • 15
  • using (_ sender:) did not make it any better. With regards to the second experiment, am I correct to say that the bare minimum required for unwind to work is the the `@IBAction func unwindToFavouriteList(sender: UIStoryboardSegue) {}` and connecting save button to the exit item and picking unwindToFavouriteListWithSender from popup. I have removed the function body and still no response when I hit the save button. – Sherry Jan 04 '19 at 18:43
  • Would it help if I sent you a working example? – matt Jan 04 '19 at 18:51
  • “completely unresponsive” I wonder if the problem is the button. Can you get this button to do anything at all? Does it dim when tapped? Can you hook it to a different action? Maybe you’ve put it into the navbar incorrectly or something. Contrariwise can you make a button in the main view trigger the unwind instead? – matt Jan 04 '19 at 19:32
  • The button is responsive. When I kill the unwind segue and add an IBAction to the button so that it changes a label text on the same view, when I press the button, it does that successfully. Unwind segue doesn't work however, even if do it using a button on the main view rather than the navigation bar. so it looks to me like the unwind segue functionality isn't working. Could it be bug with Xcode 10beta6 that I am using? What do you mean by not adding the button correctly to the navbar. Does the navbar add any extra complexity to it. – Sherry Jan 05 '19 at 13:50
  • Note that I have embedded the nav controller between another view (not FavouriteTableViewController) and ExplorationDetailViewController where I am segueing modally. – Sherry Jan 05 '19 at 13:50
  • Well, as I've said, either I can show you a simple working example or you can show me a project with your actual architecture reduced to simplest possible terms demonstrating the issue and I'll try to fix it for you. It's _not_ a "bug with Xcode"; you're doing _something_ wrong, I just don't know what. – matt Jan 05 '19 at 20:18
  • please show me a simple example. I will prepare my project to demonstrate the issue as well. For the simple example, to best represent my architecture, can you use three views, view1 with modal segue to view2 with navigation controller embedded between them. save button on the navigation bar of view 2. Clicking this save button does an unwind segue into view 3 and adds information to view 3 in the process. – Sherry Jan 05 '19 at 20:35
  • Sorry, that makes no sense. Unwind segue goes _backwards_ — it unwinds. I cannot unwind _from_ view 2 to view 3 unless view 3 was put onto the interface _earlier_. Maybe that's your problem — you are trying to unwind to something that doesn't already exist? – matt Jan 05 '19 at 21:51
  • I've given an answer based on the apparent misconception in your last comment. See if that helps... – matt Jan 05 '19 at 21:56

1 Answers1

2

From your comments, I'm guessing that the problem is that there is no FavouritesTableViewController in the view controller hierarchy at the time that the Save button is pressed. You cannot unwind to something that isn't already present: "unwind" means go back to something that was instantiated earlier and remains present, above the current view controller in the view controller hierarchy.

For example, let's say we have

UINavigationController -> (root view controller) -> FavouritesTableViewController
    -> (push) ExplorationResultViewController

Now we can unwind from the Exploration controller to the Favourites controller, because the Favorites controller is already in the hierarchy before the Exploration controller. It sounds like maybe you are not appreciating that fact.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • that might be it. New to this so don't quite appreciate view controller hierarchy. When I am hitting button in ExplorationResultViewController to unwind, the FavouritesTableViewController is not in the ViewController hierarchy. The way my storyboard is setup, the user has no need to open up FavouriteTableViewController before hitting save button on ExplorationResultViewController. But I still want to add information in the ExplorationResultView into the FavouriteTableView and transition to FavouriteTableView without having to preload FavouriteTableView into the hierarchy. How do I do this? – Sherry Jan 06 '19 at 19:20
  • I have attached an image to the original question of my storyboard design. The flow of the app is that it opens to View1. View 4(FavouriteTableViewController) is only loaded if favourites button in the navBar in view 1 is clicked. The user doesn't have to do this is. Natural flow is, Hit grey in View1, it goes into view2. Hit grey button in view2, it segues to view 3(ExplorationDetailViewController) with navigation controller embedded inbetween. When user hits save button in View 3, I would like for it to transition to view4 and add info from view3 into the table list of view4. – Sherry Jan 06 '19 at 19:33
  • "When user hits save button in View 3, I would like for it to transition to view4" But you said "user doesn't have to do this". If user has not already loaded view 4, you cannot "unwind" to view 4. — I'm just repeating now what I already said. I think I've answered the question. The question of what to do _instead_ of an unwind is a _different_ question, surely. – matt Jan 06 '19 at 21:06
  • yes.Thanks matt. I've realised that its wasn't an unwind function but more of a pushing data forward to another view. I have just implemented a push segue to the screen and used prepareforsegue to move data. and that works fine. Thanks for resolving this. – Sherry Jan 06 '19 at 21:22
  • Hugely helpful answer. It's easy to check `self.navigationController?.viewControllers` to see if the target is even in the stack. In my case, the storyboard was loading a custom class in the segue setup that replaced the origin controller with the destination controller. – lilbiscuit Mar 26 '20 at 20:56