35408

iOS: handling of UIGestureRecognisers in UI(Sub)Views

I would like to know how to best possible address the following issue:

I have a single ViewController. Its view contains a great number of complex subviews (subclass of UIView). Due to the complexity some of these UIViews initialise their own UIGestureRecognisers and implement the according target actions. As I want to coordinate the gestures of various subviews I have to set the single once ViewController as the gesture's delegate. There are various possibilities for that.

1) Initialize ALL gestures in the the viewController (this will lead to a massive viewController)

2) defining a protocol in the UIVIews (getViewController), implemented by the ViewController

@protocol CustomViewDelegate <NSObject> @required - (UIViewController *)getViewController; @end

3) customise the init method of the UIViews and using the ViewController as an option.

- (id)initWithFrame:(CGRect)frame andViewController:(UIViewController *)vc;

What is the most elegant possibility to solve this issue? Is it OK to implement target actions inside a UIView object?

Thanks for your thoughts...

Answer1:

If you're defining custom UIView subclasses, you can invest them with as much logic as it makes sense to store local to them, give them delegate protocols to pass anything else up and, as long as you expose the delegate as an IBOutlet, you can wire up your view controller as the relevant delegate directly in Interface Builder or the UI designer part of Xcode 4. I personally think that would be the most natural way forward, since it consolidates any view-specific logic directly in the view and lets you do the wiring up where you would normally do the wiring up.

In terms of overall design, such a scheme conforms to model-view-controller provided your views are doing only view-related logic. So, for example, if you had a custom rectangular view that can take a swipe anywhere on it to reposition a pin, and the 2d position of the pin affects some other system setting, you'd be correct to catch the gesture in the view, reposition the pin and then send updates on its position down to the delegate, which would fulfil the role of controller and push the value to any other views that are affected and out to the model.

Commenting on your suggested solutions directly:

(1) this would focus all logic into the one controller; whether it's correct from a design point-of-view depends on the extent to which you're having to interrogate your custom views (in that you don't want to end up treating them as mostly data that external actors have to know how to manipulate) and the extent to which you want to reuse logic.

(2) I'm not sure I entirely understand the suggestion — what is getViewController defined on and how does it know how to respond? If it's the UIViews themselves and the view controller has to identify itself first then I'd suggest just adopting the delegate pattern wholesale rather than specialising to views and view controllers, e.g. as you may want to build compound views that tie together logic from several subviews.

(3) as a rule of thumb, the sort of things to pass to init are those that the class actually needs to know to be able to initialise; it would probably be better to use a normal property to set the controller after the fact. Or make it an IBOutlet and wire it up so that it happens automatically via the NIB.

Recommend

  • Opengl Iphone SDK: How to tell if you're touching an object on screen?
  • Dynamically change cell's height while typing text, and reload the containing tableview for res
  • Trying to use CGContextAddArc… nothing is drawn?
  • Varnish VCL: how can I switch on req.backend_hint?
  • UITableView gives empty table, does not load data
  • how can i generate ssis packages from biml using commandline and deploy ssis on server
  • How to load image asynchronously using UIImageView+AFNetworking in ios
  • Finding a MongoDB document through a word in a field description in each product with Mongoskin
  • Convert base64 image to a file in Node Js
  • How to send data along with file in http POST (angularjs + expressjs)?
  • Aspect ratio behaviour of - internal dimensions and element size
  • windowScriptObject method not found on Objective-C code
  • Read files from URL
  • Using bitbake is it possible to have a different do_install for a package based on the target image?
  • express.static handling root url request
  • Renewing Cookie-session for express.js
  • Global session variable in express.js route?
  • Level-order tree traversal
  • parsing xml and html page with lxml and requests package in python
  • x-axis labels in coreplot not displayed
  • What is the Linux Equivalent of Kernel32.dll?
  • not able to create VC++ project, with VS11
  • iOS 9 errors and correct conversion to swift 2
  • Express JS Display Data By ID
  • Counting Treaps
  • How do I check if System::Collections:ArrayList is empty / nullptr / null?
  • CORS with socket.io
  • Alamofire and Reachability.swift not working on xCode8-beta5
  • How can we prepend rows to a react native list-view?
  • How does this usort cmp function actually work?
  • wxPython: displaying multiple widgets in same frame
  • R - Combining Columns to String Based on Logical Match
  • ORA-29908: missing primary invocation for ancillary operator
  • How to delete a row from a dynamic generate table using jquery?
  • json Serialization in asp
  • Rails 2: use form_for to build a form covering multiple objects of the same class
  • embed rChart in Markdown
  • How to stop GridView from loading again when I press back button?
  • Unable to use reactive element in my shiny app
  • How to load view controller without button in storyboard?