UISegmentedControl calls action method on changing selectedSegmentIndex programmatically

13,312

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.

Share:
13,312
AmaltasCoder
Author by

AmaltasCoder

Updated on June 04, 2022

Comments

  • AmaltasCoder
    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.