UISegmentedControl寄存器点击选定的段

Pie*_*sma 61 iphone uisegmentedcontrol

我有一个分段控件,用户可以选择如何订购列表.工作良好.

但是,我希望在点击已选择的段时,订单会被反转.我已经准备好了所有代码,但我不知道如何在这些段上注册水龙头.似乎唯一可以使用的控制事件是UIControlEventValueChanged,但这不起作用(因为所选的段实际上没有变化).

这有解决方案吗?如果是这样,它是什么?

提前致谢!

Jul*_*ian 51

你可以继承UISegmentedControl,然后override setSelectedSegmentIndex:

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

如果使用IB,请确保将您的类设置为UISegmentedControl子类.

现在您可以像平常一样收听UIControlEventValueChanged,除非用户取消选择该段,您将看到selectedSegmentIndex等于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]);
    }
}
Run Code Online (Sandbox Code Playgroud)


dav*_*dav 31

我认为如果你使用它会更好一点-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event- 因为这是UISegmentedControl的行为.此外,似乎你不需要超载-(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];
}
Run Code Online (Sandbox Code Playgroud)

  • 有关iOS 7更新版本,请参阅此答案:http://stackoverflow.com/a/17652998/292145 (3认同)

Hen*_*k N 17

我自己想要这个.采取朱利安的解决方案(谢谢!)并略微修改.

下面的UISegmentedControl子类只是触发UIControlEventValueChanged事件,即使值没有改变,这显然有点奇怪,但在我的情况下工作正常并保持简单.

AKSegmentedControl.h

#import <UIKit/UIKit.h>

@interface AKSegmentedControl : UISegmentedControl {
}

@end
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

  • 这在iOS 6.1中对我不起作用.该方法是一次调用,但在响应触摸时,它不是调用.看起来Apple正在绕过自己的安装者和吸气者. (2认同)

Eri*_*icS 12

这适用于iOS 4和5:

-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
  int oldValue = self.selectedSegmentIndex;
  [super touchesBegan:touches withEvent:event];
  if ( oldValue == self.selectedSegmentIndex )
    [self sendActionsForControlEvents:UIControlEventValueChanged];
}
Run Code Online (Sandbox Code Playgroud)


Bob*_*aaf 11

显示的当前解决方案仍然不起作用,因为除非真正触发新段,否则永远不会调用setSelectedSegmentIndex.至少在我的情况下这没用,我确实使用iOS5,也许这个解决方案在iOS4中运行.无论如何,这是我的解决方案.它需要一个额外的子类方法,如下所示:

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{    
    [self setSelectedSegmentIndex:self.selectedSegmentIndex];
    [super touchesEnded:touches withEvent:event];
}
Run Code Online (Sandbox Code Playgroud)

祝好运!


Ste*_*e E 9

这是一个非常古老的问题,所以我想我会添加一个相当简单的解决方案,当我在iOS 5+应用程序中遇到这个时,我会使用它.

我所做的只是将Tap Gesture Recognizer拖到我的.xib文件中的UISegmentedControl上.检查新手势识别器的连接,确保分段控件是唯一的gestureRecognizer插座,然后将其操作连接到您要在控制器中触发的方法.

只要您触摸分段控件,此方法就会触发,因此只需使用实例变量检查所选索引,以查看用户是否触摸了已选择的段.

@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
Run Code Online (Sandbox Code Playgroud)


Iva*_*iuk 8

雨燕5

class ReselectableSegmentedControl: UISegmentedControl {
    // Captures existing selected segment on touchesBegan.
    var oldValue: Int!

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        self.oldValue = self.selectedSegmentIndex
        super.touchesBegan(touches, with: event)
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesEnded(touches, with: event)

        if self.oldValue == self.selectedSegmentIndex {
            self.sendActions(for: .valueChanged)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这里


yer*_*chu 6

在iOS8上,这里的每个答案似乎都不起作用或触发两次更改.我提出了非常简单的解决方案 - 所以我想分享它.

在子类中我只有:

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

它的作用是在更改分段控制段之前将所选段重置为-1.它将在touchesEnded方法中发生.


Jas*_*ane 5

这有效:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    int oldValue = self.selectedSegmentIndex;
    [super touchesBegan:touches withEvent:event];
    if (oldValue == self.selectedSegmentIndex)
    {
        [super setSelectedSegmentIndex:UISegmentedControlNoSegment];
        [self sendActionsForControlEvents:UIControlEventValueChanged];
    }
}
Run Code Online (Sandbox Code Playgroud)