2017-03-03 111 views
2

我剛剛注意到在其IBAction中設置UISwitch的isOn導致IBAction被再次調用。所以下面的代碼:設置UISwitch isOn以編程方式從IBAction再次調用IBAction

class ViewController: UIViewController { 
    var count = 0 
    @IBOutlet weak var mySwitch: UISwitch! 

    override func viewDidAppear(_ animated: Bool) { 
     super.viewDidAppear(animated) 
     mySwitch.isOn = false 
    } 

    @IBAction func buttonTapped(_ sender: UIButton) { 
     mySwitch.isOn = !mySwitch.isOn 
    } 

    @IBAction func switchChanged(_ sender: UISwitch) { 
     print("\(count) pre: \(mySwitch.isOn)") 
     mySwitch.isOn = !mySwitch.isOn 
     print("\(count) post: \(mySwitch.isOn)") 
     count += 1 
    } 
} 

打印當開關被導通一個時間以下:

0 pre: true 
0 post: false 
1 pre: false 
1 post: true 
  1. 開關在viewDidLoad
  2. 開關關斷是由用戶
  3. 接通
  4. switchChanged(IBAction)被調用時,開關處於開啓狀態
  5. 0 pre: true印刷
  6. 開關被關斷以編程在switchChanged
  7. 0 post: false印刷
  8. switchChanged由系統
  9. 開關關斷現在switchChanged再次調用,並且1 pre: false稱爲
  10. 開關被接通以編程方式
  11. 1 post: true is printed

爲什麼系統第二次調用IBAction?例如,當一個人想要根據內部狀態否定用戶的行爲時,如何解決這個問題?我覺得我錯過了一些令人尷尬的顯而易見的東西,但我非常肯定類似的代碼用於工作。這是一個iOS錯誤?它被在iOS 10.2 iPhone 5S模擬器上運行時,Xcode版本8.2.1(8C1002)

有趣的是,當綁buttonTapped按鈕被竊聽(調用同樣的方法),該交換機的IBAction爲不叫。

+0

您可能已將開關事件處理程序連接到兩個不同的事件。 – gnasher729

+0

我對它進行了測試,並看到了與之相同的行爲。只有通過點擊來改變開關,通過拖動來改變它只會導致被調用一次。 – dan

+0

切換'switchChanged'中的開關沒有任何意義。如果你想讓開關關閉,明確地將其設置爲關閉,那麼再次調用該方法並不重要,因爲第二次它將關閉,並且將它設置爲關閉並且不會被調用再次。 – Paulw11

回答

0

你的IBAction可能與valueChanged相關,它並不表示特定的觸摸事件,正如它所說的那樣,值被改變了。

我建議設置一個叫做var didOverrideSwitchValue = false的變量,在設置新開關值之前將其設置爲true,然後在調用該函數時檢查該變量。如果它設置爲true,則將其設置爲false並返回。

或者,如果您希望僅在打開新設置時否定此設置,那麼您可以執行if (switch.isOn),如果是,則可以通過將其關閉(如果需要)進行響應。

+0

安德魯,這是正確的,它掛鉤了'valueChanged'。我不確定我完全理解了你的第一個建議,我們假設我總是想要切換布爾值。我仍然試圖理解爲什麼set-isOn/IBAction-invocation週期不會無限期地繼續下去,爲什麼拖動開關的行爲與點擊不同,以及爲什麼當'isOn'在' buttonTapped'。 –