UIControlEvents and subclassing UIControl - iphone

I have a UIControl subclass for a custom slider type control (one that behaves differently from UISlider). At the moment I use my own target and action variables to send a message to the target whenever the slider value changes. But this doesn't play nice with Apple's UIControlEvent constants. I wasn't sure if I should use these, and if so, where can I put my custom "value changed" detection?
I overrode beginTrackingWithTouch: and continueTrackingWithTouch: to return YES but the action is never dispatched.

Every time the value changes you call [self sendActionsForControlEvents:UIControlEventValueChanged] and the control will handle the rest.

Make sure that you are passing touchesBegan and other inherited methods to super class.

Related

What does obj.delegate=self mean?

What does it actually mean to set the delegate of a textfield?
For example: txtField.delegate = self
"In short, that you are receiving calls from the txtField. You are setting the object 'self' as the delegate for txtField."
"That means that your 'txtField' will receive events from itself
These two answers essentially mean the same thing. But seemingly contradictory. But the first makes more sense to me. I can see why a beginner gets confused, I've been there!
Basically one is the caller one is the receiver Think of it as a chef in a kitchen call his assistant to cut up some onions. In this particular case, txtField is the chef, "self" is the assistant. txtField orders self "Do this, this and this!" Like it or not the assistant has to oblige cuz he has wife and kids to feed. :)
It means that self will be the recipient of certain method calls that are made in response to actions on the text field.
In short, that you are receiving calls from the txtField. You are setting the object 'self' as the delegate for txtField.
Delegating is a programming pattern that is widely used in Objective-C.
The basic idea is let an object delegate some tasks to another object. For example, your UITextField object delegate some tasks to your view controller. In this case, your UITextField object becomes a delegating object, and the view controller the delegate of the UITextField object. The delegating object sends certain messages to its delegate in order to get necessary information, or to notify certain events, etc.
That means that your 'txtField' will receive events from itself (kind of a weird example, maybe a larger source code section could be provided?)
For some of its methods, the textfield (any object in a class using the delegation pattern) is going to try to call some other object to so that that object can customize some of the textfield's behaviors. The object that the textfield will try call is called it's delegate. The delegate is initially set to nil, so, by default, no customization happens.
If a class has a line of code like: textfield.delegate = self; then it says that this object in this class wants to get called to handle the textfield's customization for certain of the textfield's defined delegate methods.
It means the actual class where 'txtField.delegate =self' is called will receive callsbacks from events. This is often a convenient way to do things.

General advice on tracking an object's changes

I have an option menu where a user can change the application's settings. I need to track the changes. There is a DONE button, I want to make changes to the data model only when the button is pressed.
My question is, I am not sure the best way to track the changes. I don't want to introduce a giant if blocks in the doneButtonPressed button. Any general advice?
Well, the generic answer is: add callback to your controls in your options screen.
For example if you are using UISlider, then you have to customize it slightly. Probably create a subclass, that would receive touch events and then you redirect them to the delegate. OR you can use this one: RCSwitch
If you are using UIButton's then it's even easier: just add action to it.
After that you can create method like:
-(void) controlDidChange:(UIView*) control {
//mark changed items here
}

Does Value Changed event work for Text Fields at all in Interface Builder?

I'm trying to set up methods to be executed when value of certain text field is changed and saved. I tried to hook up this method with Value Changed event in Iterface Builder. It doesn't respond and I use this same event with some other control/classes and it works.
There is also no delegate method usable for that purpose.
Last resort could be only UITextFieldTextDidEndEditingNotification notification or UITextFieldTextDidChangeNotification notification, but I would certainly like to avoid writing observers if simple event in interface builder serves the purpose.
Any idea?
The valueChanged event is for buttons and sliders. For TextFields you'll want to use the Editing Changed, Editing Did Begin and Editing Did End events.
If that doesn't help become a UITextFieldDelegate instead.

Using an IBAction method when it is not called from an action?

Are there any issues when using IBAction when it is not actually called from a user's action?
If you have an action like
-(IBAction)sayHello:(id)sender;
You can call it from within your class like:
[self sayHello:#"x"]
The #"x" doesn't do anything, it just fills in for the sender.
You can actually create an IBAction method without (id)sender
-(IBAction)sayHello;
and call it from both user's actions and from within the code, but then you won't get any useful sender info from the interface. What's the 'correct' way of filling in for the sender, when calling from the code? And can you create sender info to send when it's called from within the code?
Just trying to figure it out.
I think a good practice for OOP is to refractor the method
-(IBAction)sayHello:(id)sender;
to another method called: -(void)sayHello;
and inside the method
-(IBAction)sayHello:(id)sender {
[self sayHello];
}
If other methods want to call the sayHello:(id)sender action to do some job, it can call the sayHello. The method name should make sense for the client to call it without a problem or work around. It will help you when you have to test or debug
The sender should be a UI component. So if in your class you have, say, a UIButton...
UIButton *button;
Then you can just send it as parameter to the action:
[self sayHello:button];
Insider the method, no matter if it is called from the UI or in some simulated way, you can have some logic to detect who the sender is, and behave differently based on that. This way, multiple buttons or other components can reuse the same action method.
Unless you're actually making use of the sender parameter (see Jaanus's answer for more on that), you're fine with passing nil for it when calling the method from code.

iPhone Dev - Delegate or event?

In many situations, such as making the keyboard go away when the use clicks done, there are two options: set the text field's delegate to self, and adopt the UITextFieldDelegate protocol, and then use the method
- (BOOL)textFieldShouldReturn:(UITextField *)textField;
to resignFirstResponder and return YES. But you can also
addTarget:self
action:#selector(myMethod:)
forControlEvent:UIControlEventDidEndOnExit];
or something like that, using the did end on exit event, and then in the method, [sender resignFirstResponder]. So what is the best option in situations like these: the delegate, or the event?
The quick rule of thumb is that delegates are supposed to answer the question of "should I?" on behalf of the object they are a delegate for. Events, on the other hand, are broadcast afterward to let listeners know that something has happened.
In your case, while you could call [sender resignFirstResponder] in response to the event, you're mixing metaphors by doing this. Your delegate should have already made the decision to hide the keyboard (or not) and the event being broadcast is merely to let all the other components know that they keyboard hid.
If you are going to be paired with one other class, where the real type of that class may vary, then it makes a lot of sense to formalize that pairing into a protocol and a delegate arrangement.
If the information you want to send is targeted at a broader set of objects, then it starts to make more sense to use notifications - though now you have somewhat obscured what information is being passed by the notification as there's no central definition for what to expect.
Both are about an equal load to work with - with a delegate you have to set yourself and then remember to unset yourself before you are deallocated. You have to do the same thing with notifications, remember to start listening and then unsubscribe before you are deallocated.
Also, you should try as much as possible to make sure you send notifications out on the main thread as the notices get sent on the same thread they started from. Same goes for delegate methods, it's not very kind to call a delegate method from some other mystery thread!
The delegate makes your objects more reusable they are an adapter that lets any object interact with the defined behaviors of that object and use the object. I would say delegates should be adopted by the object responsible for keeping the state of and defining behavior to actions that will occur in the object that it is using. Events should be used for any other objects that are intersted in particular action that the object that has the protocol does (so objects not responsible for keeping the state of the object that defines the protocol).
For example: A view controller using a textfield will adopt its protocol to dismiss the keyboard and any other behaviors that can occur for a textfield, maybe another controller will do some animation when the keyboard is dismissed, so it will register to the textfield as an event in order to receieve the event of the keyboard being dismissed.