Подтвердить что ты не робот

Событие изменения UISegmentedControl не срабатывает в iOS5

У меня есть UISegmentedControl, чье событие "Изменено значение" подключено в Interface Builder для вызова моего контроллера -(IBAction)segmentChangeAction:(id)sender;

Когда пользователь нажимает на элемент управления для изменения выбранного сегмента, как ожидается, segmentChangeAction вызывается в iOS4 или iOS5.

Когда я программно меняю выделенный сегмент на segmentedControl.selectedSegmentIndex = newIndex;, на iOS4 segmentChangeAction вызывается, и сегмент отражает новый выбор. Однако на iOS5 segmentChangeAction не вызывается, но сегмент отражает новый выбор.

Является ли это изменением в iOS5? Есть ли что-нибудь, что я могу сделать, чтобы получить segmentChangeAction, вызванный в iOS5, когда я программно меняю выбор?

4b9b3361

Ответ 1

Это изменение в iOS 5 для того, чтобы UISegmentedControl соответствовало всем другим элементам управления.

Идея состоит в том, что действие должно запускаться автоматически только в результате взаимодействия с пользователем. До iOS 5 действия UISegmentedControl были бы уволены из-за взаимодействия с пользователем и программного взаимодействия. Однако, инициирование изменения программно означает, что вы также можете сделать [myControl sendActionsForControlEvents:UIControlEventValueChanged] самостоятельно.

Однако вы должны быть осторожны с этим. Скажем, вы:

[segmentedControl setSelectedSegmentIndex:newIndex];
[segmentedControl sendActionsForControlEvents:UIControlEventValueChanged];

Если вы создаете и запускаете это на iOS 5, он работает так, как вы ожидаете. Если вы построите и запустите это на iOS 4, вы дважды активируете свои действия (один раз, когда вы setSelectedSegmentIndex и снова, когда вы sendActions...).

Путь вокруг этого - сделать какой-то охранник. Это может быть проверка времени выполнения, указывающая, что вы работаете на устройстве iOS 5+, или даже может быть чем-то более обыденным, например:

// changingIndex is a BOOL ivar
changingIndex = YES;
[segmentedControl setSelectedSegmentIndex:newIndex];
changingIndex = NO;
[segmentedControl sendActionsForControlEvents:UIControlEventValueChanged];

а затем в вашем методе действий...

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

Ответ 2

Я нашел другой способ, возможно, немного легче понять вы можете расширить 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

.m file

    #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

И вы можете установить делегат в вызывающем классе