How to I respond to a user pressing a UISegment? Is there a delegate, or must I programmatically (or Interface Builder), attach the selectors?
If you prefer to do it in code you can use:
[segmentedControl addTarget:self action:#selector(didSelectIndex:) forControlEvents:UIControlEventValueChanged];
And this is then the method that would be called
- (void) didSelectIndex: (id) sender
{
NSLog(#"%#",[(UISegmentedControl *)sender titleForSegmentAtIndex:[(UISegmentedControl *)sender selectedSegmentIndex]]); //replace this with your code
}
If you prefer to use IB, right click on your UISegmentedControl select Value Changedand then attach it to the desired method in your first responder.
UISegmentedControl subclasses UIControl and sends out the control event UIControlEventValueChanged whenever the selected segment changes. You can add a target/action pair for this event in code, or you can do it with the normal control-click-and-drag in IB.
Related
I need several UIButtons to all connect to the same IBAction so the buttons can all do the same thing without having to copy and paste the code. Please tell me if there is a way to do this! It might be right under my nose, but I can't find it. Thanks!
Simply add the same target and selector to each button:
[button1 addTarget:self
action:#selector(buttonClicked:)
forControlEvents:UIControlEventTouchUpInside];
[button2 addTarget:self
action:#selector(buttonClicked:)
forControlEvents:UIControlEventTouchUpInside];
// etc.
For this You need to use set IBOutlet for Each Button or Set tag for each button if you are using Outlet then used this code .h
#interface RootViewController_Phone : UIViewController
{
IBOutlet UIButton *btn1;
IBOutlet UIButton *btn2;
}
- (IBAction)buttonPressed:(id)sender;
-(void)CallButtonsMethod;
#end
Now in .m file
- (IBAction)buttonPressed:(id)sender{
if([sender isEqual:btn1])
{
[self CallButtonsMethod];
}
if([sender isEqual:btn2])
{
[self CallButtonsMethod];
}
}
-(void)CallButtonsMethod
{
//your Code
}
Use IBOutletCollections.
Here is tutorial for that:
http://useyourloaf.com/blog/2011/03/28/interface-builder-outlet-collections.html
I've found that I'm usually not able to hook up multiple buttons (or even a single button, for that matter) in IB to an already existing IBAction in code, by Ctrl-dragging from the button to the IBAction in the m file. Xcode tries to create a new action in the dragged-to file, but won't connect to an existing action. [This is true for Xcode 4.6.1 and several previous (maybe all) versions.]
The approach in the accepted answer in the following link works if the IBAction is in the view controller which is the "File Owner" for the view containing the button:
Connect object in .xib to existing IBAction
However if you want your IBAction to be in the view's own class, rather than the view controller's class, then the following approach works:
Drag only one button onto the canvas in IB first. Control-drag from
the button to the view's .m file.
Drop the dragged line in any vacant space in the implementation section of the code.
Define a new IBAction in the little popup dialogue box. So now you have one
button hooked up to an IBAction.
Now instead of dragging more buttons from the object library, hold
down the Option key and drag out a new button from the original one.
This new button will come hooked up to the same IBActions as the
original one. (If you need to create lots and lots of buttons and
this seems tedious, you can select a bunch of already created ones simultaneously and
Option-drag to create as many more in a single go.)
I have a Button1 which has IBAction. Also I set target and action for my button
- (void)setTarget:(id)target action:(SEL)action {
[self.Button1 addTarget:target action:action
forControlEvents:UIControlEventTouchUpInside];
}
So when I pressed the button firstly IBAction did what he should, and than action that I set to button. Is that order always be like that ?
If you are loading you view or view controller from a nib file then yes the pattern will always be the IBAction even first followed by the target you have added to the button.
In effect adding an IBAction in Interface Builder is really just telling IB to call ["UIControl" addTarget:"id" forControlEvents:"UIControlEvent"], and you can add multiple targets to a UIButton.
In effect your code will load everything from the NIB file first (if you are using initWithNib:named:), so this will call the addTarget function on the button first with the action you have specified in Interface Builder, then at some later point the setTarget function you have above will get called, which will add another target action to the button. A UIControls targets are stored in an array which is accessed in order and will trigger if control events are met in the order they were created in.
If you look in the header file for UIControl (the super class for UIButton) you will see that NSMutableArray* _targetActions is an array. So the order is guaranteed to fire like this unless you reorder this array after it is created at some point.
When I create UITextField inside Interface Builder, I can access Events tab for it, which has events like Value changed, Touch cancel, Touch drag, etc. I can assign my own methods to every of those events. How can I do the same, when I create UITextField programmatically with alloc?
Refer to Apple documentation for UIControl. After initializing your textField, call addTarget:action:forControlEvents:
example for the touch event ending an edit session
[textField addTarget:self action:#selector(handleTouchValueChanged:) forControlEvents: UIControlEventEditingDidEnd]
Instead of UIControlEventValueChanged, you should use UIControlEventEditingChanged:
[_titleTextField addTarget:self action:#selector(handleTitleValueChanged:) forControlEvents:UIControlEventEditingChanged];
UIControlEventEditingChanged fires whenever user changes value [synchronous with typing or keyup]
which could cause extra hits to your data handler routine, if you're saving values based on that event, expecting it to be some kind of final value from user input...
How can I determine whether my button's event is Touch Down?
I want to do a function like this:
if(users click on touchdown event)
{
NSLog(#"a");
}
else if(users click on touchupinside event)
{
NSLog(#"b");
}
Eather you set two different IBAction methods in the InterfaceBuilder or you set two different targets via:
- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents
in your code while creating the button.
You "find out" by letting the button tell you when the event happens.
Add a method (or methods) like this:
- (IBAction)myButtonClick:(id)sender;
In Interface Builder, attach the method(s) to the events you're interested in.
You create a separate method for each type of event if you want different behavior for a TouchDown as opposed to TouchUpInside.
you attach each unique event to its own IBAction
I have a small iPhone app which I've created a button with some functionality in. My question is, how can I call this button without actually pressing it?
Any help would be appreciated!
Thanks
If you want to activate whatever target a button is wired to, you can call:
[button sendActionsForControlEvents:UIControlEventTouchUpInside];
(TouchUpInside is the event you'd normally wire a button action to). This way if other targets are added or changed for any button (say for debugging) you don't have to alter your code.
This method is on UIControl which UIButton inherits from, which is why you might have overlooked it at first glance...
Have your button event call a function. You can also manually call the function yourself.
Example:
- (void) btnFunction {
NSLog (#"test");
}
...
UIButton *btn1 = [UIButton buttonWithType:UIButtonRoundedRect];
// other code to set up button goes here
[btn1 addTarget:self action:#selector(btnFunction) forControlEvents:UIControlEventTouchUpInside];
You can also call the function yourself:
[self btnFunction];
Your button shouldn't have functionality, it should just send a message to its target (or call a method, or call a function...).
You're free to send that message to that target yourself.
e.g. Your button's target outlet is connected to an IBAction on your controller. That IBAction is just a method of the form:
- (void) doSomething:(id)sender
In your own code do:
[controller doSomething:self];
It's exactly the same as having your button do it.