UISegmentedControl更改事件未在iOS5中触发

Cla*_*fou 36 iphone uisegmentedcontrol ios ios5

我有一个UISegmentedControl,它的"Value changed"事件在Interface Builder中连接起来调用我的控制器 -(IBAction)segmentChangeAction:(id)sender;

当用户点击控件以更改所选的段时,segmentChangeAction无论是在iOS4还是iOS5中,都会调用所需的段.

当我以编程方式更改所选的段时segmentedControl.selectedSegmentIndex = newIndex;,在iOS4 segmentChangeAction上调用并且该段反映新的选择.但是在iOS5 segmentChangeAction没有被调用,但该段确实反映了新的选择.

这是iOS5的变化吗?segmentChangeAction当我以编程方式更改选择时,有什么办法可以在iOS5上调用吗?

Dav*_*ong 70

这是iOS 5中的更改,以便UISegmentedControl与所有其他控件保持一致.

我们的想法是,操作只应在用户交互时自动触发.在iOS 5之前,UISegmentedControl由于用户交互程序化交互,将触发操作.但是,以编程方式启动更改意味着您也可以[myControl sendActionsForControlEvents:UIControlEventValueChanged]自己完成.

但是,你必须小心这一点.说你做:

[segmentedControl setSelectedSegmentIndex:newIndex];
[segmentedControl sendActionsForControlEvents:UIControlEventValueChanged];
Run Code Online (Sandbox Code Playgroud)

如果您在iOS 5上构建并运行它,它可以按预期工作.如果你在iOS 4上构建并运行它,你将会触发两次你的行为(一次当你setSelectedSegmentIndex和你的时候再次sendActions...).

解决这个问题的方法是做一些防守.这可能是运行时检查,表明您在iOS 5+设备上运行,或者甚至可能是更平凡的事情,如下所示:

// changingIndex is a BOOL ivar
changingIndex = YES;
[segmentedControl setSelectedSegmentIndex:newIndex];
changingIndex = NO;
[segmentedControl sendActionsForControlEvents:UIControlEventValueChanged];
Run Code Online (Sandbox Code Playgroud)

然后在你的行动方法......

- (void)segmentedControlSelectedIndexChanged:(id)sender {
  if (!changingIndex) {
    // your action code here, guaranteed to only run as a result of the sendActions... msg
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 感谢您的深入解释!我做了最简单的事情(在更改索引后直接调用`segmentChangeAction`),验证了在iOS <5上调用此代码两次没有问题.但是我知道为什么要这样做感到高兴,谢谢. (2认同)

Cha*_*ndo 5

我找到了另一种方法,可能更容易理解你可以扩展UISegmentedControl并在init方法中添加目标操作并调用委托方法来触发值更改

这是示例代码

头文件看起来像这样

#import <UIKit/UIKit.h>
@class CGUISegmentedControl;

@protocol CGUISegmentedControlDelegate <NSObject>

@optional
- (void) segmentedControl:(CGUISegmentedControl *) control valueChangedTo:(NSInteger) nValue;

@end

@interface CGUISegmentedControl : UISegmentedControl

@property (nonatomic,unsafe_unretained) id <CGUISegmentedControlDelegate> delegate;

@end
Run Code Online (Sandbox Code Playgroud)

.m文件

    #import "CGUISegmentedControl.h"

@implementation CGUISegmentedControl

@synthesize delegate                = _delegateAction;

- (void) addTargetAction {

    [self addTarget:self action:@selector(indexChanged:) forControlEvents:UIControlEventValueChanged];

}

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self addTargetAction];
    }
    return self;
}

- (id) initWithCoder:(NSCoder *)aDecoder {

    self = [super initWithCoder:aDecoder];
    if (self) {
        [self addTargetAction];
    }
    return self;

}

- (id) initWithItems:(NSArray *)items {

    self = [super initWithItems:items];
   if (self) {
        [self addTargetAction];
    }
    return self;
}

- (id) init {

    self = [super init];
    if (self) {
        [self addTargetAction];
    }
    return self;

}

- (void) indexChanged:(id) sender {

    if (_delegateAction && [_delegateAction respondsToSelector:@selector(segmentedControl:valueChangedTo:)])
        [_delegateAction segmentedControl:self valueChangedTo:self.selectedSegmentIndex];


}

@end
Run Code Online (Sandbox Code Playgroud)

您可以在调用类中设置委托