How can I elegantly navigate from one embedded view to another (with layout in IB)? - ios

In this app the user can do either Activity A or B. When doing A, the viewer sees embedded View A; but also during A the viewer can choose to see embedded View B. (The same goes for Activity B, only with converse views.)
My setup in IB is diagrammed below. Not knowing any better way, I created twice as many activity scenes as I would have liked: For the "Do Activity A" branch, I have two side-by-side copies of the Activity A scene. The first one has an embed segue to View A; and the second, an embed segue to View B. (The "B" setup is the converse.)
To avoid more duplication, I did make both activity branches share Views A and B. And although the activity scenes were doubled, the classes that they link to (ActivityAViewController and ActivityBViewController) were not. I haven't yet noticed any complications from that. . . .
In contrast to other workarounds I've seen, I chose the above "push–pop" layout because Views A and B are expensive. I don't want to discard the primary view just to load the secondary, and I don't want to load both unnecessarily. Also, I want to do this in IB because the real app is more complicated, and seeing all of my layout there helps me understand and develop it. With that said, my approach still seems klutzy.
My questions are
Is there a better way to set this up in IB?
What happens with the activity scenes' shared view controllers? Is a separate class instance created for each, or do the two scenes end up sharing the same instance?
Similarly, what happens with the shared views?
Apple's explanations seem clear enough, though they assume more knowledge of Cocoa Touch and related jargon than I currently have. Any clarifications and insights will be appreciated.

Is there a better way to set this up in IB?
There are other ways to set it up. They all have tradeoffs. Your method has a certain look, and if you want to hook it up differently, it will look a little different. Your method also has the advantage that all of the navigation is handled by the Storyboard; no extra code is needed.
Alternatives include imbedding views A and B in their own little navigation controller. Then switching to view the other would involve clicking on that navigationController. This avoids the duplication of the outer Activity A and B controllers, but it would change the look by adding a navigationBar to the embedded views.
You could also do that and hide the navigation bar and pass a message from the outer Activity A or B controller to tell it when to push the other viewController. This has the disadvantage of some additional nontrivial coding; the Storyboard no longer manages the navigation for you.
You could also run this in a UITabBarController. That has the disadvantage of creating both Activity A and Activity B at the same time if you only need one, but you can freely switch between them without any recreation of any of the views.
What happens with the activity scenes' shared view controllers? Is a
separate class instance created for each, or do the two scenes end up
sharing the same instance?
Every segue (including embedded segues) creates a new viewController instance. No instances are shared.
Similarly, what happens with the shared views?
A new instance of A and B will be created each time.

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!

How to share controller amongst different iOS views

I am coming from a C# wpf background where you can have one ViewModel handling multiple Views. This is a great way to share data amongst unrelated views. However I can't figure out how to do the same thing in iOS, as you seem to need a Controller for each View.
What I am trying to achieve is to have a sign up sequence where the user populates 5 screens of data one by one. I was going to use a PageViewController for this and each click on Next would transfer them to the next page in the sequence. All the while, adding all their input data to a parent model object which stayed around for all five screens, at the end you can submit the whole lot to the database to sign up.
The only way I can see so far to do this is to create five separate ViewControllers, one for each screen of the sign up, and create the navigation logic to display them as you click through. However this a) seems overkill and b) means each subsequent screen and viewcontroller doesn't know about the information the user entered in the previous steps.
What is the correct way to do this in iOS?
You can do it in many ways. If you like to use UIPageViewController, you can actually have one view controller for all steps of the sign up process.
A main view controller would implement protocol UIPageViewControllerDataSource. It has two required methods, which return an instance of a content view controller. These instances can be of any UIViewController subclass, so you could have five separate view controller classes or you could have five instances of the same class.
Xcode has a project template "Page-Based Application". It might be a good sample code for you. There is one class DataViewController and it is instantiated for each page. If your case is really simple then this might be the best solution.
If you use multiple view controllers, you can pass data between them by overriding the method prepareForSegue(segue:sender:). The UIStoryboardSegue object has access to the destination view controller, you can cast it and set up the properties. (I am assuming you are using storyboards and segues.)
Another approach would be not to use UIPageViewController and implement the whole process within one view controller. There could be one view with five container subviews. Initially the first one would be shown, then the second one, and so on. This requires manual implementation of navigation between those steps, but gives a lot of flexibility. It's also more aligned with MVVM, because there is one-to-one mapping between a ViewModel and ViewController.
In general, iOS apps have lots of view controllers. It doesn't seem an overkill for me to use five in your case. It might be more code, but it's less complexity.

Complex storyboard navigation

I'm very new to iOS but have been put on a complex app. All the tutorials I have seen on storyboards, segues, views, etc. are very simple.
I have been able to use a segue to show a view and go back, but management doesn't care about segues. After moving through a complex app the user is supposed to be able to just jump way over to another part of the app, as if the user had gone back twice then selected another view, and then selected another view.
I'm just lost as to how to make this happen. Add a new direct segue in the storyboard editor? Or something to do with a custom segue created programatically? I need some hints on direction, like what methods to look at, what to google or a advanced tutorial and such. Thanks in advance.
Usually, the Navigation Controller allows single 'pop's of view controllers in the stack. This works great for master-detail apps and linear workflows.
When one view controller is connected to another in a web-like fashion, things get difficult to manage.
If you want to rely on the automatted management of a view controller stack but go back more than one item at once, have a look at unwind segues: What are Unwind segues for and how do you use them? -- the answer is illustrated really well.
If you can navigate in circles, it gets more intricate. Essentially, your navigation controller would put new objects of already intantiated classes onto the stack to maintain its breadcrumb trail all the way back to the root view controller.
In some cases, this is not desirable. You could use a UINavigationControllerDelegate which removes items from the stack when certain conditions are met.
Let's say you have 4 view controllers, A--D. The possible connections are: A - B - C - {B,D} - A. From D, when you're finished, you want to unwind to A. From C, you may want to add an additional item at B, but you don't want to keep track of all the B-C-B-C-B-C-... connections. In these cases, altering the navigation controller history is useful and won't break the expected behavior of the "back" button.

View Container vs Multiple ViewControllers vs Hidden Views Single ViewController

I have a View Controller and need to segue into another View Controller (which is customized based on what scenario I want to show). Trying to decide what is the best approach here in regards to simplicity vs efficiency
Three options I can think of:
(a) Have my View Controller segue into a View Controller that holds a View Container linked to multiple View Controllers
(b) Have my View Controller segue into a View Controller with multiple views that can be hidden and rearranged
(c) Have my View Controller segue into different View Controllers depending upon the criteria
I'm still uncertain how much each View Controller should differ from each other, but given that one View Controller might segue into another View Controller that's irrelevant for the other two scenarios, what are your guys' thoughts on the three approaches in terms of code complexity, ease of use, general efficiency in terms of speed/memory management. It's possible that the View Controllers that are being segued into might differ by just a little, but also by a lot!
I think all depends on difference between viewControllers for each scenario. BUT what I can certainly say is do not use varriant (B), because even if difference seems tiny now, as only it begins growing, your code that compose views will becomes more complicated and unreadable, at least in my case it usually happens. So, if you must show different viewControllers with same or pretty similar use (e.g. save for, show list, select item from list. go next, go previouse), try to use one viewController and load different views that are already composed. And if usage of those controllers different - use multiple controllers.

Strategy for implementing multiple view controllers

My application is for studying. It will have three screens, one for studying (reading), one for reviewing, and one which acts as the main menu (for managing documents and selecting study or review). The main menu will be the first screen when the app is loaded.
I am trying to decide on the best approach with regards to what view controllers and views I need.
Approach A:
(4 x View Controllers - root, menu, study, review)
This approach has a root view controller with no on-screen controls. It will always contain one of the other view controllers as a subview. For some reason I am attracted to this approach but I have seen no other examples of this so maybe I am being stupid. I am wondering if there is a reason why this is inherently wrong.
Approach B:
(3 x View controllers - root (menu), study, review)
In this approach the menu IS the root controller and the other controllers load in subviews of the menu. I think this is more of a standard way of doing things.
I would be grateful to hear any thoughts on which approach is best. I am a newbie to software development. I have worked through a number of books on iOS software development and messed around for a bit and now I am starting my first app for iPad.
Whenever you're determining how to layout your views and controllers, they're very often based on the application flow (from an end user's standpoint). So from your original question I'm not sure I exactly understand the flow- is the user forced to start at the main menu, and then from there is able to toggle between two mutually exclusive views (study & review)? If that's the case, I would recommend using a tab bar controller for the 'Study' and 'Review' views, as it allows for saving states of the views and switching between them without you having to do any extra work (from both of the approaches you described it sounds like you'd largely be recreating this behavior yourself). Then, for the main menu (which I assume is displayed when the app first starts?) You can simply open it modally (note you don't have to animate the opening, so it can instantly appear instead of sliding up from the bottom, and the user will never be the wiser). Once the user selects what they need to select in the main menu, dismiss the modal view and you're ready to go with your 2-tab controller.

Resources