UISegmentedControl register taps on selected segment

后端 未结 20 2878
渐次进展
渐次进展 2020-12-04 15:28

I have a segmented control where the user can select how to order a list. Works fine.

However, I would like that when an already selected segment is tapped, the orde

相关标签:
20条回答
  • 2020-12-04 15:59

    You can subclass UISegmentedControl, and then override setSelectedSegmentIndex:

    - (void) setSelectedSegmentIndex:(NSInteger)toValue {
        if (self.selectedSegmentIndex == toValue) {
            [super setSelectedSegmentIndex:UISegmentedControlNoSegment];
        } else {
            [super setSelectedSegmentIndex:toValue];        
        }
    }
    

    If using IB, make sure you set the class of your UISegmentedControl to your subclass.

    Now you can listen for the same UIControlEventValueChanged as you would normally, except if the user deselected the segment, you will see a selectedSegmentIndex equal to UISegmentedControlNoSegment:

    -(IBAction) valueChanged: (id) sender {
        UISegmentedControl *segmentedControl = (UISegmentedControl*) sender;
        switch ([segmentedControl selectedSegmentIndex]) {
            case 0:
                // do something
                break;
            case 1:
                // do something
                break;
            case UISegmentedControlNoSegment:
                // do something
                break;
            default:
                NSLog(@"No option for: %d", [segmentedControl selectedSegmentIndex]);
        }
    }
    
    0 讨论(0)
  • 2020-12-04 16:01

    On iOS8 every answer here seem to either not work or trigger change twice. I came up with very simple solution - so I'd like to share it.

    In subclass I only have:

    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
        [super touchesBegan:touches withEvent:event];
        [self setSelectedSegmentIndex:UISegmentedControlNoSegment];
    }
    

    What it does is to reset selected segment to -1 before changing segmented control segment. It will happen in touchesEnded method.

    0 讨论(0)
  • 2020-12-04 16:03

    This was a pretty old question so I thought I'd add the rather simple solution I used when I ran into this in an iOS 5+ app.

    All I did was drag a Tap Gesture Recognizer onto the UISegmentedControl in my .xib file. Check the connections for your new gesture recognizer to make sure the segmented control is the only gestureRecognizer outlet and then just wire up it's action to the method you want to fire in your controller.

    This method should fire any time you touch the segmented control, so just check the selected index with perhaps an instance variable to see if the user touched the already selected segment.

    @implementation MyViewController
    
    @synthesize selectedSegment;
    @synthesize segmentedControl;
    
    // connected to Tap Gesture Recognizer's action
    - (IBAction)segmentedControlTouched:(id)sender
    {
        NSLog(@"Segmented Control Touched");
        if (selectedSegment == [segmentedControl selectedSegmentIndex]) {
            // Do some cool stuff
        }
    
        selectedSegment = [segmentedControl selectedSegmentIndex];
    
    }
    
    @end
    
    0 讨论(0)
  • 2020-12-04 16:03

    The first idea I had was wire up the Touch Up Inside or Touch Down actions to your sort method, but this doesn't seem to work.

    The second idea is more of a work around, set the Momentary property on the segmented control. This will then fire a Value Did Change action every time it is tapped.

    0 讨论(0)
  • 2020-12-04 16:04

    Wanted this myself. Took Julian's solution (thanks!) and modified slightly.

    The following UISegmentedControl subclass simply triggers the UIControlEventValueChanged event even when the value didn't change, which obviously reads a bit weird, but works fine in my case and keeps things simple.

    AKSegmentedControl.h

    #import <UIKit/UIKit.h>
    
    @interface AKSegmentedControl : UISegmentedControl {
    }
    
    @end
    

    AKSegmentedControl.m

    #import "AKSegmentedControl.h"
    
    @implementation AKSegmentedControl
    
    - (void)setSelectedSegmentIndex:(NSInteger)toValue {
      // Trigger UIControlEventValueChanged even when re-tapping the selected segment.
      if (toValue==self.selectedSegmentIndex) {
        [self sendActionsForControlEvents:UIControlEventValueChanged];
      }
      [super setSelectedSegmentIndex:toValue];        
    }
    
    @end
    
    0 讨论(0)
  • 2020-12-04 16:06

    I think it is even a little better if you use -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event---as this is the behaviour of UISegmentedControl. Further, it seems you don't need to overload the -(void)setSelectedSegmentIndex:(NSInteger)toValue

    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {    
        NSInteger current = self.selectedSegmentIndex;
        [super touchesBegan:touches withEvent:event];
        if (current == self.selectedSegmentIndex) 
            [self sendActionsForControlEvents:UIControlEventValueChanged];
    }
    
    0 讨论(0)
提交回复
热议问题