2010-11-04 98 views
19

這聽起來很平凡,但我注意到一些奇怪。我已經爲UISwitch的Value Changed事件連接了一個處理程序。我會期望是,每次處理程序被稱爲開關的值會改變。但實際上並非總是的情況。如果你按下開關快速開/關,處理程序可以連續調用交換機的SAME狀態(在我的具體應用中,這是一個問題)。所以我想知道是否有其他人注意到這種行爲,並找到了一個很好的解決方案。檢測到UISwitch的變化

回答

0

記錄最後一個狀態,以便可以確定其狀態是否已更改或是否已使用相同狀態觸發。

8

獲取處理程序開關的狀態:

- (void)valueChanged:(UISwitch *)theSwitch { 
    BOOL flag = theSwitch.on; 
} 
7

每按一次,你做不立即切換上/開關關閉。如果開關處於關閉位置,您可以在啓動到開啓位置之前進行幾次按壓。這些印刷機中的每一個被解釋爲「打開開關」,因爲在動畫完成之前它不被視爲「開」。儘管事實上這個數值還沒有真正改變,你仍然可以爲每個媒體獲得一個「valueChanged」回調。

0

當您關閉/打開開關時,已調用「值更改」。因此您可以通過調用valueChanged方法檢測開關中的更改。

15
-(void) createSwitch 
    { 
     self.searchExistSearchNewSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(0,0,0,0)]; 
     [self.searchExistSearchNewSwitch addTarget:self action:@selector(switchValueChanged:) forControlEvents:UIControlEventValueChanged]; 
     [self.view addSubview:self.searchExistSearchNewSwitch]; 
    } 
    - (void)switchValueChanged:(UISwitch *)theSwitch 
    { 
     BOOL flag = theSwitch.isOn; 
    } 
+0

不是一個學究,但對於其'on'屬性'UISwitch' getter函數是'isOn',所以這行應爲'BOOL標誌= theSwitch.isOn'。 – 2016-12-01 22:06:45

+0

測試並編譯。 – user1105951 2016-12-02 14:20:02

+0

我沒有說它不會工作(我知道它會);我說過你沒有使用這個屬性的getter函數。 – 2016-12-02 17:35:49

1

下面是對我工作的解決方案。 當交換機改變時,它也發送一個屬性「will/did change」通知。 事件也正確運行,因爲前後值保持正確。

@interface MySwitch : UISwitch 

@end 

@implementation MySwitch 
{ 
    BOOL _previousValue; 
    BOOL _returnPreviousValue; 
} 

- (instancetype) initWithCoder:(NSCoder *)aDecoder 
{ 
    self = [super initWithCoder: aDecoder]; 
    if (!self) return nil; 

    _previousValue = self.isOn; 
    [self addTarget: self action: @selector(_didChange) 
       forControlEvents: UIControlEventValueChanged]; 

    return self; 
} 

- (instancetype) initWithFrame: (CGRect) frame 
{ 
    self = [super initWithFrame: frame]; 
    if (!self) return nil; 

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

    return self; 
} 

- (BOOL) isOn 
{ 
    return (_returnPreviousValue) 
         ? _previousValue 
         : [super isOn]; 
} 

- (void) setOn:(BOOL) on animated: (BOOL) animated 
{ 
    [super setOn: on animated: animated]; 

    _previousValue = on; 
} 

- (void) _didChange 
{ 
    BOOL isOn = self.isOn; 

    if (isOn == _previousValue) return; 

    _returnPreviousValue = true; 
    [self willChangeValueForKey: @"on"]; 
    _returnPreviousValue = false; 

    _previousValue = isOn; 
    [self didChangeValueForKey: @"on"]; 
} 

@end 
0

我的問題是一個愚蠢的一個......我期待enabled值改變,但顯然不是在開關的切換,以檢查正確的值時,onisOn是正確的要使用的東西。

1

在iOS 11中引入了new UISwitch bug,所以我不建議訂閱改變值的事件。否則,每次UISwitchisOn屬性以編程方式更改時,都會觸發您的回調。

相反:

1)訂閱觸摸了內部事件:

let switch = UISwitch() 
switch.addTarget(self, action: #selector(onSwitchValueChanged), for: .touchUpInside) 

2)實現回調方法:

func onSwitchValueChanged(_ switch: UISwitch) { 

} 

3)現在當編程更改isOn值,它不會觸發onSwitchValueChanged方法。

switch.isOn = !switch.isOn // 'onSwitchValueChanged' is not triggered