Why UIViewController is a subclass of UIResponder?
Asked Answered
J

4

8

What's the purpose for making UIViewController a subclass of UIResponder? Was it done solely to pass the rotation events?

I could not find any definitive info on that in the docs.

Update

I understand that if something is made a UIResponder, this something is suppose to be included in the responder chain and process events. But I have two gnawing doubts.

  1. As far as I know, UIViewController is put into the responder chain right after its view. Why do we need a view controller in the responder chain at all? Its view is already there, so why don't we let the view process the events that were not handled by its subviews?
  2. OK, I'm ready to agree that we might need this. But I would like to see some real life examples, when processing events in a view controller is really needed and is the best/easiest/most appropriate way to do something.
Johathan answered 14/5, 2011 at 21:57 Comment(0)
M
14

I think your problem may simply be a failure of object oriented thinking.

Per the docs:

The responder chain is a linked series of responder objects to which an event or action message is applied.

In UIKit the view controller sits in the responder chain between its view and the view to which the controller was pushed. So it is offered any event or action that its views don't handle.

The topmost view controller's next responder is the window, the window's next responder is the application, the application's next responder is the application delegate and the application delegate is where the buck stops.

Your question "Was it done solely to pass the rotation events?" applies the incorrect test; it implies that at some point the responder chain had otherwise been fully engineered and somebody thought 'oh, wait, what about rotation? Better chuck the view controllers into the chain'.

The original question will have been: is it helpful if events or actions can be handled by the view controller if none of the views handle them? The answer should obviously be 'yes' as — even on a touch-screen device — there will be events or actions that aren't inherently related to a view.

The most obvious examples are those related to physical inputs other than the screen. So device rotation is one. Key presses on a bluetooth keyboard are another. Remote controls are a third. The accelerometer is a fourth.

The next most obvious example is any system-generated events or actions that should go to the single most local actor rather than to everyone. In iOS that's generally requests for a more specific actor, like the most local undo manager or the identity of the input view to show if focus comes to you.

A slightly less obvious example is that exemplified by UIMenuController — a pop-up view that posts a user-input event that may need to traverse several view controllers to get to the one that should act on it. iOS 5's child view controllers increase the number of possibilities here enormously; quite often you're going to have one parent view controller with the logic to do a bunch of things and children that want to pass messages up to whomever knows how to handle them, without hard coding the hierarchy.

So, no, view controllers weren't added to to the responder chain just to handle rotation events. They were added because logically they belong to be there based on the initial definition of the responder chain.

Mooned answered 15/8, 2012 at 21:28 Comment(0)
M
4

This is going to sound like a glib answer, but it really isn't. UIViewController is a subclass of UIResponder so that is can respond to user actions (e.g. touches, motion, etc.).

If a view does not respond to an event it is passed up the responder chain giving higher level objects a chance to handle it. Hence, view controllers and the application class are all subclasses of UIResponder

You can find more detailed information about the responder chain in Cocoa Application Competencies for iOS: Responder Object on Apple's developer site.

Macias answered 14/5, 2011 at 22:18 Comment(6)
That's fine. But could you give some concrete examples when UIViewController actually responses to actions, touches for example?Johathan
OK, a totally contrived example: Suppose you have a number of UIImageViews, each one displaying an animal. When the user touches one you want to play the sound the animal makes. Rather than having each view play the sound you could have the view controller respond to the events and play the appropriate sound. This would allow it to stop the sound that is playing before starting a new one.Macias
Better example: if you wanted to implement drag and drop between two subviews.Macias
With the animal case I would suggest different design, when all info on an animal (the appearance and the sound) is encapsulated inside one model object and presented in one view object, with a controller object just passing the data. (However the animalView might have a method like shutUpTheAnimalNow). As for drag and drop, please see updated question. Why can't UIViewController's view handle this?Johathan
More on animals: may be a subview animalSoundPlayer would be even better :)Johathan
@Johathan true but then it would be a very bad example of why you might want a view controller to process events which was the whole idea of the example now, wasn't it?Macias
T
1

UIViewController is in the responder chain to allow for it to process any event. There are more then just the events you think of (touches) that pass through this chain. Motion events get passed through the chain, touch events that a specific view doesn't handle, you can also force things through the responder chain using [UIApplication sendEvent:...] with a nil target.

The other thing you may notice is UIApplication is also a subclass of UIResponder. All events that aren't handled will end up there.

Tail answered 14/5, 2011 at 22:38 Comment(1)
I'm thinking not of the touches but of rotations -- is this the only reason? As for UIAppliction -- it's the main controlling object of the app, so I have no questions on it being a responder. Please check the updated question.Johathan
I
0

In MVC conception handling of event occurred in view should perform controller.

There is a feature, to set "nil" to "target" parameter of -[UIControl addTarget:action:forControlEvents:] in with case the responder chain is searched for an object willing to respond to the action.

That is, because of search option, UIViewController is subclass of UIResponder.

So, you can send your custom control events in same manner to get benefits of "search" option.

Inefficiency answered 2/7, 2012 at 13:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.