I'm looking for the correct way to write my own interface objects.
Say, I want an image that can be double-tapped.
@interface DoubleTapButtonView : UIView {
UILabel *text;
UIImage *button;
UIImage *button_selected;
BOOL selected;
}
// detect tapCount == 2
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
This works fine - the button receives the events and can detect double taps.
My question is how to cleanly handle actions. The two approaches I've tried are adding references to the parent object and delegation.
Passing a reference to the parent object is quite straightforward...
@interface DoubleTapButtonView : UIView {
UILabel *text;
UIImage *button;
UIImage *button_selected;
BOOL selected;
MainViewController *parentView; // added
}
@property (nonatomic,retain) MainViewController *parentView; // added
// parentView would be assigned during init...
- (id)initWithFrame:(CGRect)frame
ViewController:(MainViewController *)aController;
- (id)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
But, this would prevent my DoubleTapButtonView class from being easily added to other views and view controllers.
Delegation adds some extra abstraction to the code, but it allows me to use the DoubleTapButtonView in any class that fits the delegate interface.
@interface DoubleTapButtonView : UIView {
UILabel *text;
UIImage *button;
UIImage *button_selected;
BOOL selected;
id <DoubleTapViewDelegate> delegate;
}
@property (nonatomic,assign) id <DoubleTapViewDelegate> delegate;
@protocol DoubleTapViewDelegate <NSObject>
@required
- (void)doubleTapReceived:(DoubleTapView *)target;
This seems like the proper way to design the objects. The button only knows if it was doubletapped, and then tells the delegate who decides how to handle this information.
I'm wondering if there are any other ways of thinking about this problem? I noticed that UIButton uses the UIController and addTarget: to manage sending events. Is it desireable to leverage this system when writing my own interface objects?
Update: Another technique is using NSNotificationCenter to create observers for various events, and then create the event in the button.
// listen for the event in the parent object (viewController, etc)
[[NSNotificationCenter defaultCenter]
addObserver:self selector:@selector(DoubleTapped:)
name:@"DoubleTapNotification" object:nil];
// in DoubleTapButton, fire off a notification...
[[NSNotificationCenter defaultCenter]
postNotificationName:@"DoubleTapNotification" object:self];
What are the disadvantages to this approach? Less compile-time checking, and potential spaghetti code with events flying around outside of the object structure? (and even namespace collision if two developers use the same event name?)