I have a problem, I explain.
I want to activate a Switch and it is possible to open the application in a tableView.
For this I save the label in an NSUserDefault and if a the opening of the application the label is in the NSUserDefailt it activates the switch.
The problem is that on the following pictures I just switch on switch A and B but when I scrool other switch activates as q, s, c but never the same.
Do you have an idea to suggest me? I but my code below with the console.
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)
}
}
}
Console :
["A", "B"] A On B ["A", "B"] A B On ["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"] A B ["A", "B"] A B ["A", "B"] A B ["A", "B"] A B ["A", "B"] A B
Cells get reused. You must always set a cell's properties for every condition to fully setup the cell for each index path. Your code only deals with turning a cell's switch on, but not off.
There are two solutions.
configCell
method to turn the switch off under any conditions it should not be turned on.prepareForReuse
method. In this method you should reset all state of the cell. This would include setting the switch to off and clearing the label's text.On a side note, your code has several other minor issues that should be cleaned up.
UserDefaults
unless you have a clearly understood need to do so. Use the proper methods to save and read values from UserDefaults
.cellForRowAt
you should force-cast the cell to the desired type. This makes the rest of the code in that method easier to write and you want the app to crash quickly if the cast is wrong because it means you have a programming error that needs to be fixed.configCell
method is called labels
but it only repents a single label. Giving it a plural name makes it confusing.contains
method of Array
.UserDefaults
is all more complicated than it needs to be.item
property of IndexPath
. This is meant to be used with UICollectionView
. For UITableView
, use row
.Below is how I would write your code after fixing all of the above issues.
Table controller:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! TableViewCell
cell.configCell(station[indexPath.row])
return cell
}
Cell code:
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")
}
}