0

What is the proper way to accept user input in a view and then transfer it to that view's controller? I know the NotificationCenter is one option, but surely there is a more elegant way to transfer data from a view to its controller?

All help is greatly appreciated and I always accept an answer!

danielmhanover
  • 3,094
  • 4
  • 35
  • 51

5 Answers5

2

Use the delegate protocol design pattern, or target-action by subclassing UIControl. Think about how a UIButton tells a view controller that it's been pressed. In interface builder, you connect an action - a selector something like touchUpInside: to a target - the view controller that owns it. In non-IB, you directly tell the UIButton what selector and what target to use.

Both methods make sense in different cases. For a UITextField, for example, it makes more sense to use delegation because it's possible for the text field to send you any number of events, such as an event when the user begins editing, ends editing, or types a character.

For a button, it makes more sense to use target-action because there's really only one event expressed in different forms.

For swipes and drags and other gestures, use UIGestureRecognizers.

Jack Lawrence
  • 10,664
  • 1
  • 47
  • 61
1

You are looking for delegation, where the controller set itselfs as the delegate of the view. You know it from UITableViewDelegate.

vikingosegundo
  • 52,040
  • 14
  • 137
  • 178
1

You're looking for Delegation or a Data Source. You can see more information about this here, Delegation and Data Sources

A brief example of this would be, something along the lines of this:

  //MyViewSubclass.h

  @protocol MyViewSubclassDelegate
  //Implement your delegate methods here.
  -(void)didTouchView; 
  @end

  @interface MyViewSubclass {

     id<MyViewSubclassDelegate>delegate;
  }
  @property(nonatomic,assign)id<MyViewSubclassDelegate>delegate;

Of course, @synthesize your delegate in MyViewSubclass.m

Now in the class's header, that you want the delegate of MyViewSubclass to be, you need to conform to the `MyViewSubclassDelegate Protocol.

 #import "MyViewSubclass.h"
 @interface MyViewController : UIViewController <MyViewSubclassDelegate>

In your @implementation of MyViewController., implement the MyViewSubclassDelegate method of -(void)didTouchView.

When you initialize and create your MyViewSubclass object, you set MyViewController as the delegate:

myViewSubclass.delegate = self // Self being MyViewController.

In your MyViewSubclass, when you're ready to forward any information, or simply want to fire a method you would do [self.delegate didTouchView]

Hope this helps !

Infinite Possibilities
  • 7,415
  • 13
  • 55
  • 118
skram
  • 5,314
  • 1
  • 22
  • 26
  • Yes, this does seem to be what I am looking for. What are the benefits of using the @protocol instead of just referencing self.delegate? – danielmhanover Jun 07 '12 at 23:38
  • Great! Glad I can help, if this suffices as the solution to your question please check it off as such :) – skram Jun 07 '12 at 23:39
  • Benefits of using @protocol instead of referencing just a delegate gives you finer control of your delegation behavior. i,e: Adding @required in the protocol tells your delegate that method is required and gives you a warning that it's not present. Amongst other things such as, `-conformsToProtocol:` to check if a class `IS` indeed a `delegate` to your object. – skram Jun 07 '12 at 23:44
  • @skram, is this really the way to do this? Maybe I'm misunderstanding the op's question, but shouldn't any action methods for buttons, text fields, etc. be in the controller class? You don't have to do anything to transfer it to the view controller, it should already be there. – rdelmar Jun 07 '12 at 23:49
  • `@rdelmar` Yes, this is an example of `Delegation`. Which is what Apple implements already in numerous controls `(UITableViewDelegate,UITextFieldDelegate,UIPickerViewDelegate..)` – skram Jun 07 '12 at 23:52
  • @skram, Sorry, I hit send before I finished, see my complete comment – rdelmar Jun 07 '12 at 23:53
  • 1
    `@rdelmar` I believe you're misunderstanding his question. He doesn't want to use `buttons`, he wants to detect the touch of a view. If he wanted to use buttons he can surely use `UIButton`'s `-addTarget:action:forControlEvents:` method. But, I don't think this is the case. – skram Jun 07 '12 at 23:59
0

Make your view a subclass of UIControl and implement the target/action design pattern - use the sendActionsForControlEvents: method to message the controller.

Ashley Mills
  • 50,474
  • 16
  • 129
  • 160
0

Often the UIKit objects like UITextField have delegate methods that you can implement to perform your business logic. E.g UITextField has a delegate method called - textFieldDidEndEditing: that gets called after the user has dismissed the keyboard.

Peter Warbo
  • 11,136
  • 14
  • 98
  • 193