TL;DR
Just remove the VC in the middle from the stack.
For example, have you ever thought about this? First, the Push transition from screen A to screen B, and then from screen B to screen C with the same Push transition. After that, I want to skip B and return directly to screen A by returning from screen C! Often, for example, when screen B is a two-step verification screen, in this case when returning from screen C, it is nonsense to return to the two-step verification screen, so when you want to skip that screen and return to the previous screen. ..
backBarButtonItem
The first thing you can think of is customizing the back button on the NavigationBar and running navigationController? .PopToViewController
yourself when this button is tapped. But unfortunately, the navigationbar's back button is backBarButtonItem
instead of leftBarButtonItem
. You can't customize the behavior of this button.
that? No? navigationItem.backBarButtonItem
supports{get set}
, right?
Yes, it is. However, what you can set here is the back button when you move to the next screen. In other words, this is the setting when the return destination is yours. In addition, setting action
to backBarButtonItem
will be ignored by UIKit. Only the display of backBarButtonItem
can be set here.
By the way, there are some articles that it fits UINavigationControllerDelegate
and you can customize the behavior of the back button by setting navigationController? .Delegate
to yourself, but that is a lie. can not. In the first place, UINavigationControllerDelegate
is not responsible for customizing the transition destination.
leftBarButtonItem
If you can't customize the back button, the next thing to think about is to replace it with leftBarButtonItem
. Sure, this would allow popToViewController
to run, so you can go back to a particular VC. However, there are two disadvantages.
The first is that the <
mark peculiar to the back button is not displayed. This is a common mark on his UIKit, so removing it would be inconsistent and especially uncomfortable for heavy iOS users. Of course, it is possible to forcibly create and display a <
image on your own, but it still feels strange compared to the genuine <
mark.
The other is that you cannot return by swiping the edge from the left end. This is also a gesture operation common to his UIKit, and it is one of the specifications that is indispensable especially now that the large screen iPhone has become mainstream. If this disappears, the only way to return to the previous screen is to press the back button on the upper left, which is very difficult to press. Of course, it is possible to implement an edge swipe gesture on your own, but it is still troublesome.
In addition to the above disadvantages, depending on the design, the title of screen A must be set with leftBarButtonItem
on screen C, so it is unpleasant to make it slightly Fat.
In fact, if you change your approach, this is surprisingly very easy to solve: just remove the screen you want to skip from the navigationController? .ViewControllers
array in the first place. In the first place, if you want to skip screen B when you return, you don't need screen B anymore. Then, if you have already transitioned to screen C, if you delete the previous screen B, NavigationBar will set it to return to screen A without permission, so <
and screen name display or edge swipe You don't have to do any troublesome work such as setting gestures, so it's very comfortable because it works with a straightforward implementation of UIKit.
ViewControllerB
navigationController?.pushViewController(vc, animated: true) //Push transition to next screen C
navigationController?.viewControllers.removeAll(where: { $0 === self }) //Immediately after that it removes itself from the NavigationController's viewControllers stack
Of course this isn't perfect, there's one subtle issue: the name of screen B appears in place of the back button for a moment right after transitioning to screen C. The display is only for a moment, and when the transition is complete, screen B disappears from the stack and changes to the name of screen A.
By the way, there is a similar process in Apple's official app, which is where you enter the passcode setting screen from the settings app. This screen also has an authentication process once before entering the passcode setting screen, and when returning, of course, it returns to the setting list screen without going to the authentication screen. So what Apple is doing is that the authentication screen is a modal transition, not a push transition, and once the authentication is successful, the passcode screen is pushed to the passcode screen and the authentication screen is dismissed.
This kind of processing also looks natural without any discomfort, but in the first place, the "transition destination" displayed from the setting list screen is "passcode setting", not "authentication". That's why I don't feel any discomfort even if I make a modal transition on the authentication screen. This is because the user expects the "passcode setting screen" in the "Push transition". However, on the contrary, if he makes a Modal transition while describing the transition destination as "Screen B", he will feel uncomfortable.
Even difficult functions can sometimes be solved easily with a slight change in approach.
Recommended Posts