UISegmentedControl calls action method on changing selectedSegmentIndex programmatically
Solution 1
.h file
BOOL isProgramaticallyChanged;
.m file
- (IBAction)segmentAction:(id)sender { // valuechanged connected function
UISegmentedControl *segControll = (UISegmentedControl *)sender;
if (segControll.tag == 55) { // while create segment specify tag value to 55 (to set use via IB or Code)
if (isProgramaticallyChanged == NO) {
// your valuechanged code here
}
else {
isProgramaticallyChanged = NO; //important
}
}
else if (segControll.tag == 66) { // for many segments
}
//...like this do for all segments
}
in .m file
wherever you put this code to change programmatically do before that like this
if (mysegmentedcontrol.selectedSegmentIndex != index) {
isProgramaticallyChanged = YES;
mysegmentedcontrol.selectedSegmentIndex = index;
}
Solution 2
The solution is probably to link an IBAction
method to a touchUpInside
event and propagate the value change there if you plan to also change the selected index programmatically.
From what we can read even in Cocoa Fundamentals Guide, events coming from the UI controls should be only sent when the event is triggered in response to the user acting on the control, not from a programmatic change. It's either my misunderstanding, or it's some kind of a UISegmentedControl
bug.
My solution in more detail
Connect an IBAction
method to UISegmentedControl
's Touch Up Inside
event and forward the sender
parameter to the action method handling Value Changed
. That way if there's a programmatic change of the value, the control won't call the value change handler. Only when it's by immediate user action on the control.
The only thing to solve here is to detect whether the selected index actually changed.
Solution 3
I'll add something more to the answers which may feel a little more controllable. Simply call removeTarget, do your programmatic update to the selected segment, re-add the target (for UIControlEventValueChanged)
I came here looking for an answer, the one provided seemed to work, but then it came to me that doing the remove/add target felt more appropriate and works.
AmaltasCoder
Updated on June 04, 2022Comments
-
AmaltasCoder almost 2 years
I have a a UISegmentedControl in my xib file. It is linked to an action method on value changed event in the xib file.
When I programmatically set the value of selectedSegmentIndex the action method gets called
mysegmentedcontrol.selectedSegmentIndex = index
I was expecting that the action method would only be called when the user changes the control by touching it?
This happens only for UISegmentedControl.