iOS MVC architecture - separate view other than the view of view controller - ios

Overview
I am doing an iOS project using the MVC architecture. Pardon my ignorance, I am just confused, I am looking for a good design.
The view I am planning to use will have some buttons on it and some labels and text fields. My view wouldn't need any custom
implementation of drawRect.
All my logic as to what needs to be done when a button is pressed or event occurs is in my view controller
I have a couple of doubts:
for the above scenario, is it still better (good practice) to create a separate view (a view other than view controller's view) ? If so why ?
Other than drawing and displaying the view (in my project, I don't have much of it) what else should a view's implementation code
contain ?
I would like to disable a set of buttons when the user touches on a textfield and the keyboard comes up.
a) So should I place this logic of disabling some buttons in the separate view's implementation (view created in question 1) ?
b) From my parent view (view created in question 1), can I create outlets to the buttons (which are subviews) to disable some of the buttons ? I am not able to do this. Or should I use the method subviews and loop through the button that i am looking for ?
My understanding
Model contains the data
View is responsible for displaying and shouldn't contain business
logic.
View controller is the only one to interact between the model and the view and contains the business logic

There's no need to create a separate view -- the view controller's view (usually just a plain UIView) can certainly contain your buttons and text fields. If you did want to put some of those in a separate container (perhaps so that you could move them as a group), you could use a plain old UIView for that.
Views are responders, so UIView subclasses can override the touch handling methods if you want to do any special touch handling.
a) It's common to put the code that manages views (such as disabling buttons) in the view controller. b) Again, you'd normally put the outlets for your buttons in the view controller.
When people talk about "business logic" they usually mean the logic that's required to maintain and operate on the data that the application deals with. That sort of thing is often best placed in the model. On the other hand, code that manages views, such as enabling or disabling buttons or moving data from the model into views (or vice versa) belongs in the view controller.

Q1. for the above scenario, is it still better (good practice) to create a separate view (a view other than view controller's view) ? If so why ?
If you create your view by Interface Builder, that's a separate view I think. ;) But if you try to create a view hierarchy programmatically without using a n/xib, you can put all your view layouts in loadView method, and populate the data in viewDidLoad, that's what the View-Controller does. And also, you can create a UIView class to implement the layout of the view, just like n/xib, but programmatically.
As the DOC said,
... One can merge the MVC roles played by an object, making an object, for example, fulfill both the controller and view roles—in which case, it would be called a view controller. ...
... A view controller is a controller that concerns itself mostly with the view layer. It “owns” the interface (the views); its primary responsibilities are to manage the interface and communicate with the model. Action methods concerned with data displayed in a view are typically implemented in a view controller. An NSWindowController object (also part of the document architecture) is an example of a view controller. ...
The MVC in Cocoa is a litte different as what you known. You can refer the official doc HERE.
Q2. Other than drawing and displaying the view (in my project, I don't have much of it) what else should a view's implementation code contain ?
You can customize your view, e.g., set text color or font style for your button, etc.
Q3.a. So should I place this logic of disabling some buttons in the separate view's implementation (view created in question 1)
It is better to put logic in controller (or view-controller), just as MVC prefer.
Q3.b. From my parent view (view created in question 1), can I create outlets to the buttons (which are subviews) to disable some of the buttons ? I am not able to do this. Or should I use the method subviews and loop through the button that i am looking for ?
You can set tag (setTag:) for your buttons and get the right one you want. But keep in mind, firstly you need to let the button shown to parent.

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.

Associating a custom UICollectionViewController with a subview

I have a view controller in my main page, which includes a tableview;
in the row of the tableview, I have dragged and added a collection view.
In the storyboard I can click drag the delegate and data source of the collection view to the main view controller (easy enough).
However I like to bind these to a custom subclass of UICollectionViewController (to have a self contained MVC for collections) and not reply on the main page's view controller. How can I do this? (associate custom controller class with the collection view?)
Would I have to use a container view controller? What is the right approach for something like this?
I am newbie to iOS and would greatly appreciate any guidance.
You could drag a container view into the row, instead of the collection view. Then drag the collection view into the container's associated view controller scene. Change the class (in InterfaceBuilder's identity inspector tab on right) to be your custom view controller class.
--- end of answer ---
Now with that said, consider embracing more of an MVVM approach than MVC. By this I mean simply to not bother splitting out to separate view controllers for the sake of MVC, but instead to keep all your view controllers simple. Have each own one (or more) ViewModels, where all the business logic lives that's associated with that view controller. Each ViewModel (which is just an NSObject or even a Swift struct if you wish) can be independently unit tested without involving any UI at all. The view controllers just literally wire up the data from the ViewModels to the controls & views, and configures the controls & views while relying on the viewModel for any decision-making. It'll radically improve your architecture for minimal effort. Hope this helps!

Container controller view sizing

I'm currently building a custom view controller container for my iOS project and I nearly understand what I'm doing. The one thing I'm stuck on is how do you (properly - aka not a hack) add a view controller in PART of the Parent controller's frame. See how there are multiple view controllers/views in the email app? How does one build a custom controller container that designates the location of such sub-view controllers? How do you properly add such a controller? I'd like to know the "correct" way as designated by apple (best practice).
EDIT: After looking at this some more I was thinking a possible way would be to create views with custom sizing and then push those to the parent. Is this the correct way?
You sort of answered it yourself. The view you have as an example uses a UISplitViewController to show two separate views (left and right). Each of those views has a view controller that owns it. Note that the left side includes all of the view, like the search, nav bar, and toolbar. So just create two separate view controllers and add them to a UISplitViewController and you should be golden! The views themselves are created however you normally create views. Storyboards, NIBs, or in code works.

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

transitionFromView:toView:duration:options:completion: confusion

I am trying to utilize transitionFromView:toView:duration:options:completion: but in uiview class reference this point is confusing me. What it means?
This method modifies the views in their view hierarchy only. It does
not modify your application’s view controllers in any way. For
example, if you use this method to change the root view displayed by a
view controller, it is your responsibility to update the view
controller appropriately to handle the change.
Please view the sample project https://anonfiles.com/file/521cbb41b086eae987fe27eb98278aba
In this project I just called transitionFromView:toView:duration:options:completion: and everything is working fine and did nothing what is mentioned in the above point.
You are more likely asking for an explanation of Apple's documentation than a specific question, if I understand your posting correctly.
Nevertheless I'll give you this explanation and I hope, it will help you:
You write:
Everything is working fine..
and that is, because you a doing well here!
According to the MVC design pattern (Model-View-Controller), you are using the classes UIViewController (the "C") and UIView (the "V") in your code.
A view contains the visual representation of objects (like labels, buttons, subviews, ...) without an logic for their behavior.
A viewcontroller provides the logic, e. g. IBAction methods and any other methods that you may implement.
Each UIViewController has its own "view" property containing the view, whose behavior the controller does manage. This view normally contains additional views, e. g. labels, images and buttons. They are subviews and are stored in the view's "subviews" array property. Btw, each view has such a subviews property - that is, how we can implement complex view hierarchies.
In your situation (multiple subviews that are managed by one common viewcontroller), the method
transitionFromView:toView:duration:options:completion:
hides "fromView" and unhides "toView" with the support of animations. It is a transition between to views. The paragraph from the documentation shall prepare you as a developer, that this method only manages the change of the visual representation and does not provide additional "services" for your view controller for the further management for the participating views.
That means, that you have to manage e. g. the state of the views (which view actually provides interaction for the user) by your own code. It seems to me, that you have managed this well!
In a wider scope, iOS supports UIViewController container as well - they can contain child view controllers (which again contain their view with its subviews). In such an architecture, there is another transition method from the SDK,
transitionFromViewController:toViewController:duration:options:animations:completion:
which allows you to implement transitions not between two views, but between two view controllers.
I hope this is not too much text and helps to make things clearer for you.

Resources