Question

Coming from a web development background, doing mainly MVC-based applications, I am used to have the components of my code separated in three groups of files: the controllers, the models and the views.

But in a iOS application, even also using the MVC pattern, does it make sense to follow the same technique?

An UIViewController provides you with a default view where you can add the rest of the subviews (UILabel, UIButton,...) and have immediate access to them. And the language is the same, it's not like having to deal with HTML/CSS and something else.

But I have came across some iOS applications where an UIView is subclassed and maintained in a separate file, even when it's only going to be used in an UIViewController. Thus, you have to code custom accessors to deal with internal subviews.

I do not see the need for doing that, unless of course you are reusing the same UIView in several places or doing custom drawing.

Was it helpful?

Solution

Many of us will admittedly blur the MVC lines a little and will slip a tiny amount of view-related code into our controllers. I personally think that is fine. It does not diminish the fact that we're still largely following the MVC pattern (and that the Cocoa classes are doing the heavy lifting for the view). But, for me, if the view-related code expands beyond the trivial, I find myself electing to subclass the view.

There will be people who religiously subclass UIView, but I think a little pragmatism is warranted. If you're adding a trivial amount of view-related code, is your code legibility improved by abstracting that away into a new UIView subclass? Not always. But I think this situation (where someone subclasses when they probably didn't need to) is far less common than the opposite problem (where someone failed to subclass when they probably should have).

So, you asked:

I do not see the need for doing that [subclassing UIView], unless of course you are reusing the same UIView in several places or doing custom drawing.

I agree that reuse and custom drawing (e.g. drawRect) are two great examples. But I would also add a principle that if subclassing would improve code legibility because a view is sufficiently complicated (admittedly a subjective call), then I will subclass. Two examples:

  1. I had a calendar view in an app and the view controller was getting unwieldy, managing all of the cells for the various days in the month, etc. So by subclassing the UIView, I was able to abstract the ugly details of all of the subviews that composed by calendar view. I subclassed not only the main "month" view, but also the "day" views within the "month" view. No reuse per se. No custom drawing. But it was obviously the right thing to do. The code is infinitely more legible.

  2. I increasingly subclass UITableViewCell for my table views. In my first projects, I'd have the table view controller's cellForRowAtIndexPath do all of the complicated composition and layout of that cell. My code is far easier to follow now that I routinely subclass the UITableViewCell in any situation that I'm not using one of the standard cell types.

In short, while I agree that one shouldn't feel forced to subclass a UIView for every view controller, I personally try to do so when a view reaches a certain level of complexity. I let the code legibility govern my practices. I find that I'm subclassing views more than I used to, but by no means am I doing it all the time.

Bottom line, while you don't need to subclass views all the time, I personally think many developers are guilty of failing to subclass views (or models) when they should have. They shouldn't do so out of some fanatical desire to conform to MVC, but rather they should be asking themselves if their code would be easier to read and maintain if they subclassed the view or model as appropriate.

OTHER TIPS

Normally, I would have a UIViewController <=> SingletonManager <=> Actual Data Source. I do prefer to keep things well separated. If I happen to have a custom UIView, where I do my own custom drawing, I will have a different file for that, because it makes sense. Even if I am only using in one place (you never know what you will need tomorrow, and you might happen to need it somewhere else). Also don't forget that you actually have the MVC well separated in iOS:

  • NIBS/StoryBoard/Custom Drawing
  • UIViewControllers
  • DataSource

It can be a good pattern as you deal with the difference between the same app on iPhone vs iOS. What might be a DetailViewController on an iPad could be a UINavigationController on an iPhone.

Another common pattern is that the controller is coupled to the DataSource while the view is agnostic to the DataSource and can be reused in several controllers.

Views are not in the view controller, these are either in separate classes or nib file loaded by the view controller, the view controller is written for that view so it will have all actions and outlets connected to that view.

Now if you are asking about using a nib or a subclass, it's the same that choose between composition and inheritance.

If you need to have a special view, subclass UIView, but if you want to have a view with controls as subviews, use composition and it's easier to use Interface Builder to compose your view.

The only reason i see to have a subclass of UIView only for subviews is for a better encapsulation but because your controller is written especially for the view, there is no need to have this encapsulation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top