MVC: Is a custom UITableViewCell a view or controller or both? - ios

I used to consider a CustomUITableViewCell.xib as the view and the corresponding CustomUITableViewCell.swift class as the controller of a table view cell.
Is this correct? A youtube video I stumbled upon considers the class as the view: https://youtu.be/n06RE9A_8Ks?t=177
Edit:
To clarify the question: Which one of the following is the view and controller? Are both considered the view?
CustomUITableViewCell.xib
CustomUITableViewCell.swift

I'd absolutely consider it a "view" (in terms of MVC). It's of the group of logic that (along with the .xib) handles 1 particular view of information, rather than orchestrating some aspect of the general logic of the app.
I also consider a UIViewController as belonging to the "view" part of MVC for the same reason. Of course, if you put far more business logic into your view controllers than that which is necessary to support the single view, then your view controller is some mix of MVC. For example, if your view controller chooses what scene of the app comes next, your view controller then participates in controller logic and it's not really following MVC. Your view controller is forced to do a lot of single view-related work, though, because there's a single view it's responsible for and that the view-work is more practically done in the UIViewController rather than the UIView.
So when you ask about a cell view class's stance in MVC, if it's doing single view work, then it's a "View". If you mix in controller work or model work, then you've muddied up the separation of responsibilities that MVC espouses.

In my personal opinion it is a view. It should be handling only UI components in the class. Think of both files as a complete view. One cannot be without the other. Thus I consider them one.

Related

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!

Is it better to have a viewDidLoad in all view controllers or just in the main view controller have multiple UIViews?

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

How should one cope with multiple delegates in a paged UIScrollView

I have a UIScrollView, contains 3 pages.
The first two are UITableView, the third one is a UICollectionView
So in one View Controller I will have to write delegate methods for all of them.
I googled a bit and found a solution like this (not tested yet),
Place each page in a separate UIViewController, implement the
corresponding delegate methods, and use UIViewController.view
attribute to build the scroll view
The UIViewController.view approach seems wrong to me, is that the normal way to do it?
Why are you trying to handle all the delegate calls in one view controller, can't you create separate view controller for each of them? If you are not separating now then it will be tougher for you to manage code later.
Absolutely using controller composition is a standard and respected solution to the Massive View Controller problem. Examine for instance the expositions at the StackViewController project which cleverly uses that concept to create forms in a UIStackView:
Composition over inheritance is a fundamental principle of object-oriented programming.
This principle has always been used in iOS view hierarchies, where more complex views are composed out of simpler ones (e.g. how a UIButton contains a UILabel and a UIImageView that render its content). However, there was no "official" way to compose view controllers until the introduction of view controller containment in iOS 5. It was possible to mimic behaviour like this prior to iOS 5, but handling the propagation of events between parent and child view controllers and transitions between child view controllers was difficult to get right, which are all problems that the view controller containment API solves.
In the same way that you can create complex layouts by composing multiple UIStackView instances, you can use the view controller containment API to compose multiple instances of StackViewController to create a hierarchy of view controllers where each content view is backed by a corresponding view controller that cleanly separates the responsibilities, instead of handling all of that at the view level (an anti-pattern, as mentioned earlier).
Also review 8 Patterns to Help You Destroy Massive View Controller, particularly
Standard Composition
View controllers can be composed using the View Controller Containment APIs introduced in iOS 5. If your view controller is composed of several logical units that could each be their own view controller, consider using Composition to break them apart. A practical application of this litmus test is a screen with multiple table views or collection views.
Which is, in fact, the exact situation that you have to practically apply it to!

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

I would like a custom, resuable subview that can know about the model and lifecycle events

I come from an ASP.NET background so I'm not sure if there is a way to do this in iOS. Essentially, we have a design paradigm in our app where you can either have a single item in your model or multiple items. Depending on which one, different subviews are hidden/shown.
I have already created a custom subview that inherits from UIView which handles this with the help of a delegate to get some information from the ViewController. I have implemented it on multiple screens which works fine. However, the separate view controllers are duplicating a ton of code such as when to update the model, what to do when the model is updated, etc. Essentially, stuff that the view controller should do. It would be great to keep this code in one place as opposed to the different ViewControllers.
I know I can have my custom subview's class inherit from a UIViewController, but I also need the ability to have additional views above or below the reusable one. What are my options for this? In ASP.NET you can just create a user control which knows about the page lifecycle and can know about the model.
"I know I can have my custom subview's class inherit from a UIViewController" -- no, you can't do this. A view can't inherit from UIViewController, and in Apple's MVC paradigm, a view shouldn't know anything about the model. Without knowing more about what you're doing, I would say one thing you can do is to make a base view controller class that your other controllers inherit from to cut down on the amount of duplicated code. Since the controller mediates between the model and the view, you should have the controller tell the view which of its subviews to show or hide, based on the model.

Resources