In iOS, should every UIView have a UIViewController?

Many views have a subspecies that need not have their own controller associated with them. In Apple’s own tutorial on creating custom views, they don’t actually create a sub UIViewController for each view.

However, I often encounter situations where I will have a hierarchy of views, where some subview has a button that sends a network request. In this case, I could make the goal:

myView.addTarget(self, action: "networkRequest:", forControlEvents: UIControlEvents.TouchDown) 

And then in the same myView class, I could handle this network request, but that seems to break the MVC pattern. Viewing should not do logic, they should just display material, right?


Another option we could do is to have access to each view for this parent or grandparents controller, which is necessary for logic. In case my goal might look something like this:

 func networkRequest(view : MyView) { self.controller.doNetworkRequest() } 

But this is also not the right decision. Again, it looks like we're just breaking MVC and digging it out.


So, we left one of two options, as far as I saw:

First, we could add goals and all the logic from the parent controller itself. But doing this gives us nasty chains like this:

 self.grandParentView.parentView.childView.addTarget(self, action: "networkRequest:", forControlEvents: UIControlEvents.TouchDown) 

This long access list gives me chills and just looks bad. But apparently this is similar to MVC. Technically, we do the logic in the controller, right?


But there may be another option. We could just give each kind of controller and each UIViewController have a sub-controller for each new subview.

But some views are static. They really have no logic, so they do not necessarily need a controller. But we essentially need one for each view if we follow this convention, otherwise we have inconsistencies when the controller has a grandson controller but no child controller.

So, we have left the creation of empty boxes for our controllers. This creates a lot of dead code that is never used, which can lead to a software crash.


So, who is smarter and wiser than me , what is the right decision here?

+8
ios uiviewcontroller uiview
source share
3 answers

Probably the MVC guru there is wiser than me, but I will give him a crack:

Option 1 - Failure

If you handle network requests in a subclass of UIView, you will ultimately violate the MVC pattern. According to Apple MVC link:

A view object is an object in an application that users can see. The view object knows how to draw itself and can respond to user actions.

It seems that the view should simply handle what users can see and interact with. Do not miss this route.

Option 2 - Success

Back to the Apple MVC link for view controllers:

A controller object acts as an intermediary between one or more application presentation objects and one or more model objects. Thus, controller objects are a channel through which view objects learn about changes in model objects and vice versa. Controller objects can also configure and coordinate tasks for the application and manage the life cycles of other objects.

Pay attention to the way the document says “one or more”, since it is perfectly acceptable for a view controller to process several types of logic. Personally, I would say that if there is only one button in your view that needs delegation for network requests, go ahead and set the view controller of the parent view as a delegate.

You must allow the view to have its own view controller as soon as the processing of the view data becomes "complex", which for brevity I will define as "multiple actions that will have the obvious purpose of the view controller of the parent view."

We can say that in the view controller you can clearly indicate #pragma mark why exactly the code is, so use your opinion here.

Option 3 - Ehhh ...

Providing each kind of its own view controller is definitely viable, but do you really think this is necessary? Creating an entire new view controller every time you need to handle one click of a button certainly seems redundant if the application is expansive.

To summarize

Go with option number 2 and use your best solution. You cannot be punished for violating the MVC pattern. The worst part is that you will rework your code into a new view controller if your presentation logic becomes complex.

Additional link:

Model-View-Controller - iOS Developer Library

Hope this helps!

+4
source share

First of all, I asked the question very well!

To answer your question - there is no need for every UIView have a view controller to manage them, but its best practice is to turn off the UIView control itself - the MVC design pattern.

I would recommend using delegates. It works great with saving the MVC pattern and makes the custom UIView re-accessible.

I have many custom UIViews that I use for multiple view controllers. The way I process them:

  • Create a protocol and add the necessary methods to it.
  • The view controller complies with this protocol.
  • Introduce the necessary protocol methods.
  • Handle the UI action in a UIView and pass the processing to whoever has ever been a delegate.
+3
source share

Let's start with the basics ... views must be dumb.

If you ever write a view that has application logic, business logic, or references to a model object, then you are doing it wrong.

NOTE. This includes table view cells and collection view cells!

You have the correct answer to the problem.

At first, we could add goals and all the logic from the parent controller itself.

But you have a problem.

But it gives us nasty chains

In practice, this should not be a problem. Keep individual views. You should always maintain a maximum of 1 level of directivity (while the properties of the presentation are the second level of indirection).

 myView.mySubview myView.mySubview.myProperty 

To accomplish this, I try to follow some basic rules.

  • Simple view views.
  • Thank you for inheriting the composition to add new functionality.
  • When all else fails, use container views (this is how you should think of sub-view controllers).
+1
source share

All Articles