Displaying instances of view controllers within Xcode without disturbing the current hierarchy - ios

I am producing an application written in swift in Xcode, I have reached a point in development in which I need to be capable of instancing views. Ideally I would alter the hierarchy of my program to contain a 'Main' or 'Parent' view, the main view would be responsible for displaying the views given to it.
Instancing other view controllers and passing the instance to the main view would be my goal, however, i am inexperienced with Xcode and swift, I am unsure how to go about including a main view without altering my entire storyboard hierarchy.
Here is an image to give a visual description of the current structure.
The intention is to alter the hierarchy to include a main/ parent / master view, the view would be an empty display item which will display all views as and when needed, ideally I would keep the tab control method.
Mainly and most importantly the view will allow instances of view controllers to be displayed, closed and refreshed without impacting other aspects of the app.
Code seems irrelevant here as my views are handled by the storyboard. Something which would be really helpful to me here would be a brief explanation of how I can handle instancing with the new hierarchy.
Thank you in advance for any help regarding this matter

A view controller can serve as a custom parent view controller of one or more child view controllers, displaying their views in any desired manner within its own view's interface.
You can instantiate a view controller in any desired manner. If you wish to pluck a view controller instance out of the storyboard (because you have already designed its view there), call:
https://developer.apple.com/documentation/uikit/uistoryboard/1616214-instantiateviewcontroller
Your view controller in the storyboard will need to have a storyboard ID string so that you can identify it.
After you've plucked a view controller from the storyboard in that way, to display its view in your interface, you must do the following dance:
The parent calls https://developer.apple.com/documentation/uikit/uiviewcontroller/1621394-addchild
The parent captures the view controller's view and sticks it into the interface as a subview of the parent's own view.
The parent calls https://developer.apple.com/documentation/uikit/uiviewcontroller/1621405-didmove
The two view controllers now stand in a legal parent-child relationship and both view controllers will work properly. They can even refer to one another.
If you wish to remove the child view controller's view from the interface, you must reverse the dance:
The parent calls https://developer.apple.com/documentation/uikit/uiviewcontroller/1621381-willmove with a nil parameter
The parent removes the child view controller's view from the interface
The parent calls https://developer.apple.com/documentation/uikit/uiviewcontroller/1621425-removefromparent
Please read "Implementing a Container View Controller" on the main view controller docs page:
https://developer.apple.com/documentation/uikit/uiviewcontroller

Related

Creating individual View Controllers for each view iOS?

This is a very simple simple question, and I believe the answer is “yes, it’s a best practice,” but I just wanted to ask the question.
When creating new views in your storyboard in Xcode, is it a good idea to create individual custom view controller files to handle each view specifically?
Meaning, if I create a new view called “login quiz,” should I create a “loginQuizViewController” that will handle all the code I write for that view?
Short answer:
Yes, each storyboard scene generally has a unique view controller class associated with it. A view controller has a root view, which in turn may have many subviews below that, and each subview might have further subviews. This collection of views is collectively known as the “view hierarchy”.
Long answer:
Yes, each storyboard “scene” has a view controller associated with it. And generally this view controller class is a particular UIViewController subclass which is unique to that particular Interface Builder scene. But you don’t necessarily have to have a view controller subclass and might, for example, use one of the existing classes (e.g. this is not uncommon for navigation controller scenes or tab bar controller scenes).
But if you have any custom logic associated with a particular storyboard scene, then, yes, you would generally have a unique view controller subclass for that particular scene.
Two minor clarifications:
You refer to the “quiz view”.
That’s fine for colloquial purposes, but for the sake of clarity, when we’re talking about everything for this quiz, it’s really a complex hierarchy of views, not just a one.
A single “quiz” scene will be associated with a unique view controller class, and the instance of that view controller class will have a single “root view” (identified with the view property), but that view will have a whole bunch of subviews (e.g. image views, buttons, labels, etc.), and some of those may have subviews of their own.
So one storyboard scene has its own unique view controller class, but is associated with a whole hierarchy of views.
We often think of a scene, and its associated view controller, as representing everything you might see at any given point in time, but it’s not always a one-to-one relationship. Sometimes what you see is composed of several storyboard scenes and their respective view controllers.
For example, if you are using a navigation controller, the navigation controller takes care of the navigation bar at the top, and your view controller might take care of everything under the navigation bar. What is visible on screen is composed of these two view controllers.
Or, in a more extreme example, we can define our own view controller containers. In the example below, when we present A, we can define the bottom half of the screen to be managed by a completely separate scene, B, which has its own view controller:
In this case, both A and B have their own IB scenes and their own respective view controllers. Achieve this by adding a “container view” to the A scene (the light blue UIView in the above screen snapshot).
But the main point is that what you see on screen may be captured by a single storyboard scene and view controller, or it might be composed of several.
A view controller can and probably will contain multiple views apart from the root view it has. That means that usually a view controller owns one ore more views that are subview's of it's own root view. Those views are often also controlled by the same view controller.
When coming from the storyboard most items you see are actually representations of view controllers (others are placeholders). "Login Quiz" sounds like a screen in conceptual terms, so (without knowing your details) it would probably make sense to create a LoginQuizViewController.

What are the benefits of using a UINavigationController over adding a view with addSubView?

Let's say I have two pages with two UIViewControllers, UIViewController1 & UIViewController2.
If I want to show a UIViewController2 on top of UIViewController1 I have three options:
using UINavigationController pushViewController.
using presentViewController.
addSubView : UIViewController1.view.addSubView(UIViewController2.view)
If I need to a transition between my views, I prefer the third option because it gives me much more control over the views.
Is there any difference between these three options in terms of performance?
Before iOS 6 you were not supposed to do option 3. View controllers were meant to control the entire screen. In iOS 6 Apple added support for parent and child view controllers. You could make another view controller your child and add it's content views to yours.
If you are going to use option 3 then that's what you need to do. If you don't you will have a variety of problems.
There is even support for parent/child view controller built into storyboards. You can add a container view to a view controller, and then control drag from the container view onto another view controller's scene. When you do that the system creates an "embed segue" that sets up the child view controller inside the container view and wires up the parent/child relationship for you.
Your first 2 options are for when you want the new view controller to replace, or at least cover, the first view controller. Option 3 is for when you want a region of your screen to be managed by another view controller.
Option 3 (using a child view controller) does mean that both view controllers will be active and in memory at the same time, so you can't release the covered view controller's data storage while it's inactive like you can in a push or modal presentation. However unless your view controllers hold and present huge data structures this isn't much of a concern. In both a push and a modal presentation the covered view controller sticks around in memory anyway, waiting to be uncovered. You have to take special steps in order to free any memory while a view controller's view is covered and then reallocate it when it is displayed again - something that is unusual.
Just for two view controllers, it will not create major difference. UINavigationController is mainly used to maintain navigation stack.
But as you are having just two view controllers, you can use alternate way also.
If you are looking for transitions with NavigationController, you can use UIView Transitions for customisation of push pop animation.
Please refer following links for UIView Transitions
https://www.objc.io/issues/12-animations/custom-container-view-controller-transitions/
http://www.raywenderlich.com/86521/how-to-make-a-view-controller-transition-animation-like-in-the-ping-app
https://www.captechconsulting.com/blogs/ios-7-tutorial-series-custom-navigation-transitions--more
http://applidium.github.io/ADTransitionController/

What is the difference between a container view and a container view controller?

I've just begun learning iOS programming and do not seem to understand the difference between these two terms.
I've been learning about container views and the apple documents constantly refer to a 'container view controller'. However, I see no class called UIContainerViewController. The storyboard lets me create a specific type of view known as a container view by the means of drag and drop and a standard view controller is created automatically with the creation of this container view and an embed segue is attached.
1 - Is this newly automatically created view controller the container view controller, since it looks like it is responsible for handling the content displayed in the container view that I just created?
2 - or is the original view controller which contains the container view called the container view controller?
3 - The apple document defines a container view controller with this statement - "A container view controller contains content owned by other view controllers." I don't quite understand what it means. Could someone explain it to me?
If there's any additional information required, please leave a comment and I will edit my question to include it.
To answer my own question a bit more systematically,
1 - The newly created view controller is not the container view controller. It is to be treated as an independent view controller. The embed segue specifies precisely that, a segue from the original view controller to the new one. However, the container view is still part of the old view controller and only indicates which other view controller's views will be displayed there.
2 - Yes. This is because the original view controller contains the container as a view. It is ultimately responsible as to choosing which other view controller's views is displayed in the container. Hence it performs the duties of a controller for that container.
3 - "A container view controller contains content owned by other view controllers" : This definition is now made clear. The original view controller displays views that are actually part of (owned by) an other view controller. Hence, as per the definition, the original view controller is the container view controller, having the newly created view controller as the child view.
In short, a container view controller lets you put view controllers inside other view controllers. the storyboard just provides you with a convenient tool that will cause a view controller to be placed in another view controller automatically. if you were to do it in code, you would need to create both view controllers and remove the view of the one vc and place it in the other, all the storyboard is doing is saving you that hassle.

What should be in View Controllers and what should be in Views?

I am at the beginning of developing an iOS app I am having trouble understanding the MVC (Model-View-Controller) design pattern. I thought I had it down but the more I read the more confused I get. I don't know if this should be an iOS specific question or if the same goes for every use of MVC. I am not using storyboards btw, I want to do it all programmatically.
I believe I understand the basic relationship between Controllers and Models, it's the separation of Views and Controllers that I don't get. Let's say I want to create a UIButton and display it on the screen. Should I initiate the button in the Controller or the View? The controller is responsible for what should be displayed, correct? Wouldn't you just call on a View to display that and not worry about creating the button in the Controller? From what I understand, View Controllers are just Controllers and should therefore control the View, not be the View. It seems like most people do just about everything in the View Controllers. I guess my question boils down to what code goes where?
UIViewController is controller part in the MVC pattern of code.
M(Model)
C(ontroller)
V(View)
Controllers handle navigation between different views , etc.
From here you can get more idea : view and viewcontroller
A view is an object that is drawn to the screen. It may also contain other views (subviews) that are inside it and move with it. Views can get touch events and change their visual state in response. Views are dumb, and do not know about the structure of your application, and are simply told to display themselves in some state.
A view controller is not drawable to the screen directly, it manages a group of view objects. View controllers usually have a single view with many subviews. The view controller manages the state of these views. A view controller is smart, and has knowledge of your application's inner workings. It tells the dumb view objects what to do and how to show themselves.
A view controller is the glue between you overall application and the screen. It controls the views that it owns according to the logic of your application
About View Controllers
View controllers are a vital link between an app’s data and its visual appearance. Whenever an iOS app displays a user interface, the displayed content is managed by a view controller or a group of view controllers coordinating with each other. Therefore, view controllers provide the skeletal framework on which you build your apps.
iOS provides many built-in view controller classes to support standard user interface pieces, such as navigation and tab bars. As part of developing an app, you also implement one or more custom controllers to display the content specific to your app.
Not sure about any iOS specifics but from a PHP standpoint controllers are there to get any data that is needed for the view (via models) and then pass that data to the view.
The view is there to render things to the screen only and should have no logic in it.
So from a website point of view if you wanted to display a users name on the screen:
The controller would request the username from the model
The model would get the username and return it to the controller
The controller would then pass the username to the view
And the view would then render the username.
Hope that helps.
To be not specific, but on a upper layer, you can say as following :
You can put controller code in class extending UIViewControllers
You can put view code in class extending UIView
You can put model code in class extending NSObject

iOS container view controller - Why does transitionFromViewController need the fromViewController?

When using custom container view controller, I don't quite understand why the presenting view controller needs to specify the from, because being the container class, it should already know what's in the view hierarchy, no?
transitionFromViewController:toViewController:duration:options:animations:completion:
Container view controllers sometimes need to put the views of the contained controllers into specific subviews of their own view. (For example, a SplitViewController reimplementation might have left and right positioning views holding the master and detail controller views respectively.) Providing the fromViewController tells UIViewController where in the view hierarchy the new controller's view should be inserted, and also which specific view should be removed after the animation.
(contrary to another answer, the frames of the views aren't set for you at all. You do that, before the call, and in the animation block. The "Creating Custom Container View Controllers" system guide in the docs has a pretty good example.)
As it happens, actually using transitionFromViewController:... appears to be optional. You can manage your view hierarchy manually, with or without animations, and it works fine. I'm still forming my opinions, but I think I prefer to do it manually, to more easily handle cases where one of the VCs is nil.
This is done this way to allow you to have a view controller that has views with viewControllers in it. The from defines the originating view controller and gives the system the ability to position the animations appropriately.
Imaging you had a view with 4 views in it like tiles. the main view controller can consecutively call this on its "child" view controllers and with the from -> to specification, it won't make the assumption that the caller is the from viewController.

Resources