When we're constructing our app's view controller - view architecture (I believe I'm using that word correctly, as it concerns the relationships of objects and how they work together and what roles they play, rather than what frameworks we use etc):
The view is a UIResponder, and it receives touch events. The view controller also receives those touch events. But View Controller is a controller object, and responding to touch events is controller logic, so the view controller should be responsible for knowing what to do depending on which view is touched, right?
So is it better practice to put all the touch logic in view controller objects, and not put it in the view object? Essentially, ignoring the fact that views can respond to touches.
If we put all the logic in View Controller objects, is it a good idea to have a View Controller object for each view that needs a fair amount of touch logic? So, instead of one View Controller with a bunch of subviews as interface elements, containing all the touch interaction code, we have each sub view be the main view of its own View Controller object, and have all those view controllers be children of a parent view controller.
Is that a good approach?
Thanks for your help
If the view is going to encapsulate some kind of reusable logic and perhaps state, like UIButton, or UITextField, do, then it makes sense for the view to handle its own touch events and translate them into UIControlEvents since the viewController really only cares about the events and not the particulars of any touch detail. In other cases, such as if you are allowing drag and drop between elements, it may make more sense to put this logic in the viewController. In some cases, like UITableView you split the difference and put as much of the generic functionality in the view but delegate back some responsibilities to the ViewController to allow functionality to be customized.
Related
For now I have a single login view controller that hide and adds subviews dynamically based on user interaction. Is it better to have multiple UIViews with one view controller, or multiple view controllers?
The benefit of having children UIViewControllers would be if you needed to care about the view lifecycle in any of the children. For instance, if in some of your subviews (child views) you needed to know if it appeared to trigger some logic, then it would be good to use children UIViewControllers.
Another reason might be, if you wanted to use view controller transitions within your custom container, as described by Apple in the UIViewController class reference:
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/index.html#//apple_ref/occ/instm/UIViewController/transitionFromViewController:toViewController:duration:options:animations:completion:
But, to me it doesn't sound like you would need this, it sounds like you would just show/hide your views, or otherwise animate them.
But if your views don't care about any of that, and just need to render UI elements, I'd say using children UIViewControllers adds additional complexity without much benefit.
This is under the assumption that either way, all your views are living on the single UIViewController's view. If you are pushing and popping view controllers inside a UINavigationController, or presenting ViewControllers modally, you definitely should use UIViewControllers for that.
Also, you definitely shouldn't put all your view code inside that single view controller. You should use subclasses of UIView, or some other mechanism of making sure you separate your components.
For example you might have:
LoginViewController - organizes and hides and shows the individual views
SignInView - shows the sign in form
RegisterView - shows the register form
...etc
Of course its better to have multiple view controllers for many reasons:
Each view controller has its own code/logic/functionality.
Better for memory management. Once you're done from a view controller, system will automatically deallocates it from memory. Using multiple views will be overload in your system when some views are not used.
Better organisation for your project. You will just present/dismiss/push/pop view controllers and pass data between each other. Instead you will deal with horrible logic for hiding and showing UIViews.
Using one view controller will have a massive amount of code which in long term the project will be an impossible mission to manage.
Having multiple view controllers is better in the sense that you would have more ease at coding them individually. Also Navigation will be good which is good for User Experience.
Memory Management will be efficient.
The MVC architecture(Model View Controller) will instead become Massive View Controller which will be a headache while debugging.
Check out this answer for more clarity. I think you are confused between ViewController and View.
Check out the accepted answer of this question in the link. Hope it helps.
About viewController's "viewDidLoad" and "viewWillAppear" methods
As far as i know, to follow MVC pattern guidelines, you shouldn't have controllers inside a view (ie. server requests, delegates, etc.), however some of the Apple's sample codes have animations inside the view (mainly CABasicAnimation instances in order to animate its layer).
My question is if having some controller logic inside your view violates the MVC design pattern, and if so, what's the best alternative, for example if we want a UIView that it will always animate (ie. bounce) when doing some action, and you don't want to implement that logic for each UIViewController that has an instance of the view.
You can simply create a UIViewController that contains the logic of animation of the view, beeing the view owner.
After this you use it like a singleton, and add its view to all the places you want, by having the controller always animating the view.
BUT to answer at your first question, yes it breaks the pattern if you put controller code inside a view.
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
I have a view controller with another view controller as a child controller, and
a table view controller also as a child controller. My first child is like a toolbar with several buttons, but without any methods. What I need is, when a button from the first child is tapped, this view must call a method with the button's tag (all the buttons have
different tag) from the table view controller to filter the list. So, what I need to know control the interaction between these child controllers?
Thank you.
Handling changes, actions, or user interaction in other views is the essential use case of delegates. The best practice is to have the first view controller be the delegates of the child view controllers, and then as events happen in the children, they calls certain methods on their delegates to notify it. In response to the delegate calls you could then reload the table view, disable/enable buttons, or any other updates you need to do.
Other options for keeping values/state in sync between views are:
Core Data - best used for data
Key-Value Observation - best used for data
NSNotifications sent through NSNotificationCenter - best used for actions
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.