Ekrem Duvarbasi
Ekrem Duvarbasi

Reputation: 187

Unwind without Storyboard

I am replacing my current views in storyboard with xib files. But I encountered an issue about unwind.

In Xib files, I can't create unwind segues. And could not find to regular way to this. When I search on web this issue, I just found about "How to perform unwind segue programmatically." This is not what I wanted. I need a way to perform an unwind operation programmatically.

I found How an Unwind Segue Determines its Destination View Controller in Apple Documentation and thought I can do this programmatically. But, the viewControllerForUnwindSegueAction:fromViewController:withSender: method (now it is forUnwindSegueAction(_:from:withSender:)) is deprecated and new method for this operation(childContaining(_:)) uses an UIStoryboardUnwindSegueSource instance that cannot be initialized programmatically.

So, I can see two option.

  1. Determine unwind points in app and create operations to do this manually for each of them
  2. Create an unwind performer object works like Apple's unwind executor but uses it's own methods.

As I see, the second option is better. But, As I said on beginning of my question. I could not find anything in web, It is like just me encountered this situation and I am sure it is not true. I think I search this with wrong keywords and I need some help to solve this. I want to learn somethings before select one of this options:

Here is some of my Google searches

Unwind without storyboard

Unwind without interface builder

How to create unwind segue without storyboard

Upvotes: 0

Views: 386

Answers (1)

matt
matt

Reputation: 534885

You are not alone and you are not the first person to have this problem. I call this the problem of reverse routing.

To illustrate the problem, I'll show a storyboard version of a relatively complex unwind situation:

enter image description here

We have a tab bar controller with two children. The first child is a navigation controller which has pushed one view controller (the green v.c. at the end of the first row) on top of its root view controller (the yellow v.c.). The second child is a normal view controller that has presented one view controller (the white v.c. at the end of the second row).

The goal is to unwind from the white v.c. to the yellow v.c. in the top row.

If you're using a storyboard, this is trivial. The yellow v.c. contains an unwind method (the name isn't actually important), and you "hook" the exit segue from the button in the white v.c. to that method. At runtime, the user taps the button, and the runtime "magically" dismisses the white v.c., switches the tab bar controller to the first child, and pops the green v.c., leaving us in the yellow v.c. as desired.

Now do that in code! Uh, yeah, sure. How? That's the problem.

The irony is palpable. Clearly the runtime knows how to solve this problem, because it does solve the problem when you use an unwind segue in the storyboard. But there is no built-in programmatic analog when you are not using a storyboard. There is no unwind command that causes the complex unwind mechanism to become activated and do the same thing that would happen if this were a storyboard-based app.

This is a huge flaw in UIKit. Apple basically requires us to use storyboards. But everyone knows that any app developed by a team is likely to avoid storyboards, because reconciling versions of a storyboard through git is darned near impossible. So Apple doesn't seem to live in the real world; they have not provided the runtime support needed for real world development of apps.

A simple solution — simple to the point of crudeness — is just to unwind "by hand". The app has a "coordinator" object whose job is to take care of this sort of backward routing. If you are in the white v.c. and you want to "unwind" to the yellow v.c., your coordinator simply has to know that this is something we might want to do, and it knows what the necessary steps are in order to get there.

Basically, what I'm saying is that the coordinator must be supplied with a fixed list of all the backward routes the app will ever need to perform, along with instructions for how to perform them. Given where we are and where we want to go back to, the coordinator just performs the corresponding steps.

(You, the OP, will observe that I have not told you anything you don't already know. What I have outlined is, apparently, exactly your option 1. And that is correct. What I'm telling you is: option 2 would be nice, but it doesn't exist and isn't worth trying to write, so just fall back on option 1.)

Upvotes: 1

Related Questions