UIStoryboard Segue Shuffle - ipad

New project, using storyboards for the first time. So many things I did easily with nibs is frustrating me to no end.
I want to be able to hop around and shuffle my views at will. I have figured out unwinds and pushes and all goes well as long as I continue linearly forward in the storyboard path. At some point I want to hop laterally back to a view that may already be somewhere on the stack, or not. This doesn't seem to work as expected.
Using UINavigationController.
Say, at one point I have 3 different views moving forward. I push one of them and go about business along that "fork". Now at some point I want to hop over to one of the other 3 paths at that fork without backtracking through the stack.
Previously, I might just instantiate the correct view controller from nib, push, then remove the view controllers from the stack that are between the "fork" and the current view. Or, if that view controller was already on the stack, I could shuffle it around by manipulating the array directly.
How can I do this with segues?
I tried making segues to and from each of the three view controllers at the fork. What a mess. I keep getting errors, segue not found, when I know they are there. I tried "replace" segues, they didn't work as I expected. Not to mention my storyboard looks like a spiderweb.
I don't like to be stuck in the old ways. If storyboards are the future, I want to be on board sooner rather than later but I could have been so much further along if I'd stuck with what I know. Any storyboard wizards willing to school me with suggestions?

Since nobody answered, my solution turned out to be abandoning the navigation controller entirely and use a variation of the method detailed here by Michael Luton:
http://sandmoose.com/post/35714028270/storyboards-with-custom-container-view-controllers
If anyone has need for this, I can say that it works very nicely and is quite simple to implement.

Related

Programmatically transitioning between two UIViewControllers (Xcode 9, Swift 4)

The app I am currently working on requires that I do not use ANY storyboards. Therefore I need to do everything programmatically. One thing I seem to be struggling with is switching between two UIViewControllers.
The issue is that every time I call the self.present() method; it creates a brand new instance of the class I would like to show. So when I go into Xcode's visual debugger, I see over 15 different views that are all stacked and are merely instantiations of one another. Ex: View1, View2, View1, View2, View1, View2, View1... This constant repetition of the views is significantly hurting the performance of my app. So my question:
Is there a way that I can switch between my two UIViewControllers without constantly creating a new instance of each one?
Again, I am doing all of this with ALL storyboards DELETED. So the solution I necessary needs to be implemented using ONLY code.
I think you should create main ViewController.
if you keep your two instance view controller, create two controller in mainViewController. Then keep that in main viewController.
And push view controller you want to present in navigation of main view controller
if you want to change second view controller pop navigation controller and push another, or just push other controller.
if you want keep your instance view controller i think it's best option for you
I think that it is really important to realize the fact that the view controller will show up multiple times in the debugger because that is something that can throw off the performance of the app. I really like the way you mention that in your comment. This is one of the main differences that can outstand you from another programmer in the same field. One of the most easiest and simple ways to fix this problem would be using the self.dismiss() method. Another way to dismiss this view controller would be to use a navigation controller to fix this problem. A navigation controller will push the main view controller out of the way and it will not create multiple instances of it. This will be the most efficient as it doesn't require a lot of code and a mere initialization of the UINavigationController class implemented in the UIKit. This is one of the most important tools and resources that you must make use of while coding in xcode and developing your skills in the swift ios field. Since this problem is not one of the most common to find on the internet, it is very beneficial for you to post it on this forum page and will really be helpful for some other programmers unaware of such methods and ways to code. One of the questions that I have for you is the fact that you don't want to use storyboards. Why don't you want to use storyboards and only make it proGrAMitcally? This is one of the very questions that manages to astound me. The storyboard is an implementation that makes it very easy for xcode and swift users to work around the tedious work that has to be done while working in the coding aspect. It only takes a few lines of code and you can get a seGu done very easily. The switch is very easily done and you can find this method on some youtube channels. For this type of work, I recommend VigneshSriniswami Patel and ShaniLakshmiVishnuJiSwami, these content creators will help guide you to becoming an xcode master.
Hope I helped!

Is there any way to create and use an unwind segue programmatically?

I have a series of three view controllers, the first two of which are wrapped in a UINavigationController, and are managed by the default Main.storyboard file. Let's call them A and B, respectively. I have more view controllers throughout the file, each instantiated and managed separately, though I am working on moving them into all-code solutions. The aforementioned third view controller I have already in code (C) is one that at various times is instantiated and presented by B.
A and B have a normal segue relationship setup in Interface Builder and called via code. I do the same with C from B, via code (instantiate and presentViewController(_:)). There are a few cases where an action in C invalidates B's raison d'ĂȘtre, and thus I must dismiss both.
So far, I have been calling dismissViewControllerAnimated(_:) from C, and then checking in B's viewDidAppear(_:) whether it should be dismissed, and dismissing it the same way if so. During this process, the user is thrown back though the VC hierarchy, watching as empty views fly back to whence they came, leaving time for them to experiment with controls that no longer work, and may crash the app. This is a rather disconcerting user experience that I wish to do away with. I could simply disable everything, but that's a lot of controls that I'd rather not mess with if I can avoid it...
I understand that IB supports "unwind segues," which can dismiss an entire VC hierarchy simultaneously, though those only seem to handle view controllers in the storyboard. Is there any way to get this behavior (dismiss everything to A) programmatically, without having to revert much of the work I've already done, considering that part of my hierarchy is contained in a UINavigationController?
UPDATE:
So, I got the dismissal to work properly, by passing a reference to the presenting view, and calling its dismiss segue before leaving. That approach came with its own issues and navigation controller weirdness, but with some tweaking it might be usable.
Honestly, it would be much easier to remove the feature entirely at this point, as it's mostly a convenience.
For the sake of science, I'm going to keep at it until I decide ether way, and answer back here for anyone googling this way.
UPDATE:
Ew... It seems this code was older than I thought. I actually have two navigation controllers, to support a custom modal animation into and out of B, with a custom unwind segue there (there you go). In order to get the animation I want, I may as well toss C into the storyboard and make a custom unwind segue.
If I don't care about animation, simply disabling animation on the custom unwind got both B and C to vanish promptly, and together. Trouble is, it's a bit jolting for my taste...
vacawama's suggestion actually makes a lot of sense, and serves me right for not checking the documentation! UIViewController already keeps a reference to its presentingViewController. Going back by two is a pinch, simply climbing back that hierarchy and dismissing the one I want. Works like a charm, without animation doesn't happen at all...
Gonna post an answer here soon with what I've found thus far.
So, science prevails, and a solution is found.
It's really a pain to do if you don't like writing custom segues and animators. Gonna do that eventually, but for now it's more profitable to just not enable the feature at all. (Thank goodness it's easy to toggle on my end).
I found that running my dismiss segue (I use a custom one) on B, then dismissing C did the trick, so long as I didn't use animations for either. Nothing unexpected there at all!
Further, I could get the same effect in one line (animation doesn't matter, so neither does custom segue) by running:
presentingViewController?.presentingViewController?.dismissViewControllerAnimated(true, completion: nil)
from C's equivalent of goAllTheWayBack().
Gross, but it got the job done. A bit more tweaking, like actually using the storyboard (ugh) for its unwind segue and writing a custom animator, it'd look fancier than a pig in a blanket!
I'd about declare this horse good and dead. Thanks all!
Have you tried Atomic Object's approach
TL;DR
use IB and ctrl-drag 'C' view controller (yellow) to 'Exit',
select 'prepareForUnwind',
give the unwind segue an identifier,
then you can perform the unwind programmatically and it will skip 'B' view controller.

Changing look of segue arrows

Maybe it is a silly question. But is there a way to change the path the segue arrows take in the storyboard?
Because i have quite a lot of controllers and views and it is hard to see all the segues. And my app is not finished there are more views still to come.
I have not found a way to change the path of the arrows other than changing the place of the controller it comes from or goes to. That makes it worst most of the time.
Greeting Adarkas

Xcode Using XIBs to move non-modally to view controllers

I currently have my first app, which uses a storyboard. From the first view, I can be 8 model views deep before returning back to the start.
I think using XIBs (not storyboards) is better for my application. I would like to learn how to do all the views in code but all the books and tutorials treat code as a black plague. Hard to learn if no one teaches anymore.
My concern with my 8 deep modal string of views is that memory is consumed by each view and not released until I fall back to the start - releasing each one as I fall back.
My application is a state machine (so I want to simple move from one view to another), releasing all aspects of the view just being left. As I move from one state to the next, I release the current view as I move to the next one.
Can someone point me in the right direction?
Thanks.
You have a couple of choices. You could create a custom container controller (which would exist for the life of the run), and switch out which controller is embedded in it. As long as you have nothing pointing to the one that you replace, it will be deallocated.
A simpler solution, but one I don't really like to use, is to replace the window's root view controller with the next controller you want to go to, which will also cause the replaced one to be deallocated.

iOS Custom View Controller

I am trying to have the ability to switch views in and out. The screens are generated on the fly and there may be anywhere from 30-100 of them that will be presented sequentially. A NavigationController may work, but I may be creating a hundred or so screens so I am worried it will run out of memory if I push that many views. Maybe this could work if I only ever added one screen at a time to the NavigationController, and when a new one is added remove all screens and then add the new one. But this may cause strange animations.
I tried creating a custom View Switcher that could load each of the views on the fly following the chapter 6 example in the apress book. The problem is that on rotations the events do not make it to the View Controller for the currently visible view. So it ends up doing weird things on screen rotations.
Another approach that I am thinking may work is to use a tab bar controller and make the tabs invisible. Then I can just use tabs 1 and 2 to hold the current view, and the last view and ping pong back and forth. Then memory is not as much of an issue as using a NavigationController.
Does anyone have any other ideas? I feel like there should be an easier way to do this that I am just not seeing.
How about creating a singleton "ScreenManager" that loads, adds and removes your views on your root view controller? This way you can make sure that the view hierarchy isn't convoluted and out of your control. It's also a good idea design-wise and should be very easy and efficient with memory management.

Resources