2017-08-21 38 views
1

我有一個問題,我解釋。切換到UserDefaults的桌面視圖,幾個被自己激活

我想激活一個開關,並且可以在tableView中打開應用程序。

爲此,我將標籤保存在NSUserDefault中,如果應用程序打開時標籤位於NSUserDefailt中,它將激活開關。

問題是,在下面的圖片中,我只是打開開關A和B,但當我scrool其他開關激活爲q,s,c但從來不相同。

你有想法建議我嗎? 我但我的代碼與控制檯下面。

Screen 1

Screen 2

的ViewController:

@IBOutlet weak var tableView_t: UITableView! 

let station = ["A","B","C","D","E","F","G","H","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","&","é","("] 

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
{ 
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as? TableViewCell 

    cell?.configCell(station[indexPath.item]) 

    return cell! 
} 

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
{ 
    return station.count 
} 

TableViewCell:

@IBOutlet weak var switch_t: UISwitch! 
@IBOutlet weak var label_t: UILabel! 

func configCell(_ labels : String) 
{ 
    label_t.text = labels 

    if let sav = UserDefaults.standard.value(forKey: "switch") as? [String] 
    { 
     print(sav) 
     for switchs in sav 
     { 
      print(switchs) 
      if switchs == labels 
      { 
       switch_t.setOn(true, animated: false) 
       print("On") 
      } 
     } 
    } 
} 

@IBAction func actionSwitch(_ sender: Any) 
{ 
    var sav : [String] = [] 

    if let saving = UserDefaults.standard.value(forKey: "switch") as? [String] 
    { 
     sav = saving 
    } 

    if switch_t.isOn 
    { 
     sav.append(label_t.text!) 
     UserDefaults.standard.set(sav, forKey: "switch") 
     print(sav) 
    } 
    else 
    { 
     var number = 0 

     for s in sav 
     { 
      if s == label_t.text 
      { 
       sav.remove(at: number) 
       UserDefaults.standard.set(sav, forKey: "switch") 
      } 
      number += 1 
      print(sav) 
     } 
    } 

} 

控制檯:

[ 「A」, 「B」] 甲 在 乙 [ 「A」, 「B」] 甲 乙 論 [ 「A」,「B 「] 甲 乙 [」 A」, 「B」] 甲 乙 [ 「A」, 「B」] 甲 乙 [ 「A」, 「B」] 甲 乙 [ 「 A」, 「B」] 甲 乙 [ 「A」, 「B」] 甲 乙 [ 「A」, 「B」] 甲 乙 [ 「A」, 「B」] 甲 乙 [ 「A」, 「B」] 甲 乙 [ 「A」, 「B」] 甲 乙 [ 「A」, 「B」] 甲 乙 [ 「A」 ,「B」] A B [「A」,「B」] A B [「A 「,」B「] A B

+0

因爲細胞被重用,你可以嘗試添加其他'{switch_t.setOff(真,動畫:假)}'。基本上他們記得重用時的狀態。 – JuicyFruit

回答

0

單元格被重用。您必須始終爲每個條件設置單元格的屬性,以便爲每個索引路徑完全設置單元格。您的代碼只處理打開單元格的開關,但不關閉。

有兩種解決方案。

  1. 更新您的configCell方法在任何不應打開的情況下關閉開關。
  2. 覆蓋單元的prepareForReuse方法。在這種方法中,您應該重置單元格的所有狀態。這將包括將開關設置爲關閉並清除標籤的文字。

在附註中,您的代碼有幾個其他小問題需要清理。

  1. 不要使用鍵值編碼與UserDefaults,除非您有明確的理解需要這樣做。使用適當的方法保存並讀取UserDefaults的值。
  2. 在你cellForRowAt應該將電池強制轉換爲所需的類型。這使得該方法中的其餘代碼更易於編寫,並且如果轉換錯誤,您希望應用程序迅速崩潰,因爲這意味着您需要修正編程錯誤。
  3. 輕微 - 參數你configCell方法被稱爲labels但它只是悔改的單個標籤。給它一個複數名稱會讓人困惑。
  4. 你的邏輯檢查一個單元的開關是否應該打開比它需要的複雜得多。使用Arraycontains方法。
  5. 您的更新UserDefaults代碼是所有複雜得多,它需要的。
  6. 你引用的IndexPathitem財產。這是爲了與UICollectionView一起使用。對於UITableView,請使用row

下面是如何將我固定所有上述問題後,編寫代碼。

表控制器:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! TableViewCell 

    cell.configCell(station[indexPath.row]) 

    return cell 
} 

細胞代碼:

func configCell(_ label: String) { 
    label_t.text = label 

    if let sav = UserDefaults.standard.array(forKey: "switch") as? [String] { 
     switch_t.isOn = sav.contains(label) 
    } else { 
     switch_t.isOn = false 
    } 
} 

@IBAction func actionSwitch(_ sender: UISlider) { 
    var labels = (UserDefaults.standard.array(forKey: "switch") as? [String]) ?? [] 

    if let text = label_t.text { 
     if switch_t.isOn { 
      labels.append(text) 
     } else { 
      if let index = labels.indexOf(text) { 
       labels.remove(at: index) 
      } 
     } 
     UserDefaults.standard.set(labels, forKey: "switch") 
    } 
} 
+0

你好,你的評論幫助我很多。我會糾正你帶給我的任何問題。謝謝 – Jules

0

因爲你從未開關設置爲關時,標籤不是在UserDefault。請嘗試

switch_t.setOn(false, animated: false) 

在適當的地方。

0

你需要做出明確的iOS犯規的每一行創建新小區,它只是一次又一次的重複使用1個單元格,請確保您的開關是打開還是關閉顯示將應用於其他下一單元其他明智的相同狀態之前。 。在你的情況,你千萬不要關閉開關,當電池即將顯示

switch_t.setOn(false, animated: true)