Swift 3 UISwitch in TableViewCell verliert der Staat beim scrollen

Das ist seltsam: ich habe gerade eine neue Single-Ansicht der iOS-Projekt und fügen Sie eine TableView in die Main.storyboard. In diesem TableView ich eine TableViewCell und in dieser Zelle, ich habe ein UILabel und ein UISwitch.
Für diese TableViewCell ich erstellte eine CocoaTouchClass MyTableViewCell und setzen Sie diese für die TableViewCell s-Klasse im Interfacebuilder.
Ich mit Steckdosen für das UILabel und UISwitch zu MyTableViewCell, sowie eine Aktion für den Schalter.
Auch ich angeschlossen TableView dataSource und delegate zu der ViewController.

So, wie ich glaube, grundlegende Dinge für den Aufbau einer Tabelle.

Meiner ViewController sieht wie folgt aus:

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

var tableData = [[String: Bool]]()

override func viewDidLoad() {
    super.viewDidLoad()
    //Do any additional setup after loading the view, typically from a nib.

    for index in 1...40 {
        self.tableData.append([String(index): index%2 == 0])
    }
}

func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

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


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "mycell", for: indexPath) as! MyTableViewCell
    let object = tableData[indexPath.row].first!

    cell.myLabel.text = object.key
    cell.mySwitch.setOn(object.value, animated: false)

    return cell
}

}

So, ich füllen Sie die Tabelle mit einigen Zeilen von Daten und wechseln jede Sekunde UISwitch auf.

Den MyTableViewCell-Klasse ist nichts besonderes:

class MyTableViewCell: UITableViewCell {
@IBOutlet weak var myLabel: UILabel!
@IBOutlet weak var mySwitch: UISwitch!

override func awakeFromNib() {
    super.awakeFromNib()
    //Initialization code
}

override func setSelected(_ selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

    //Configure the view for the selected state
}

@IBAction func switched(_ sender: UISwitch) {
    print("Switched: \(sender.isOn)")
}

}

Ok, starten Sie den iOS-Simulator, und ich sehe in der Tabelle wie erwartet. 40 Tabelle-Zeilen nicht auf einen Bildschirm passen, so dass der TableView lässt sich scrollable.

Nun: wenn ich den Zustand von einem UISwitch, und ziehen Sie den TableView, so dass die geänderten UISwitch wird aus der Ansicht und ziehen Sie dann die TableView, so dass die geänderten UISwitch wird wieder sichtbar, Sie wieder in Ihren ursprünglichen Zustand.
Die Switch-event gefeuert wird, wie es sein sollte.

So, was mache ich falsch? Bin ich etwas fehlt?

Ich nahm einen 4-Sekunden-Screencast zu zeigen, was Los ist:
http://b-bereich.de/download/swiftSwitch.mov

  • Sebastian de Vries Tabellenansicht Zellen wiederverwendet werden, wenn Sie scrollen Sie nach unten.was Sie sehen, ist eine wiederverwendbare Zelle erneut mit dem Schalter eingeschaltet.



3 Replies
  1. 2

    TableViewCells sind wiederverwendet.

    Das bedeutet, dass Sie brauchen, um zu verfolgen die Daten, die Sie verwenden, um füllen Sie den Inhalt der Zellen. Wenn der Inhalt der Zelle ändert – wie wenn du auf einen Schalter in der Zelle – Sie müssen aktualisieren Sie Ihre datasource. Wenn Sie Blättern, und die Zeile wird erneut angezeigt wird, werden Ihre Daten wissen, wie der Zustand des Schalters.

    Hier ist ein einfaches Beispiel:

    //
    // TableWithSwitchTableViewController.swift
    // SWTemp2
    //
    // Created by Don Mag on 6/5/17.
    // Copyright © 2017 DonMag. All rights reserved.
    //
    
    import UIKit
    
    class MyTableViewCell: UITableViewCell {
        @IBOutlet weak var myLabel: UILabel!
        @IBOutlet weak var mySwitch: UISwitch!
    
        var switchTapAction : ((Bool)->Void)?
    
        @IBAction func switched(_ sender: UISwitch) {
            print("Switched: \(sender.isOn)")
    
            //send the Switch state in a "call back" to the view controller
            switchTapAction?(sender.isOn)
        }
    }
    
    //simple data object
    class MyObject: NSObject {
        var theTitle = ""
        var theSwitchState = false
    
        init(_ title: String) {
            theTitle = title
        }
    }
    
    class TableWithSwitchTableViewController: UITableViewController {
    
        //array of MyObjects
        var myData = [MyObject]()
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            //just to make it a little easier to see the rows scroll
            tableView.rowHeight = 60
    
            //create 40 data objects for the table
            for i in 1...40 {
                let d = MyObject("Data Item: \(i)")
                myData.append(d)
            }
    
            tableView.reloadData()
    
        }
    
        //MARK: - Table view data source
        override func numberOfSections(in tableView: UITableView) -> Int {
            return 1
        }
    
        override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return myData.count
        }
    
        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "SwitchCell", for: indexPath) as! MyTableViewCell
    
            //Configure the cell...
            let d = myData[indexPath.row]
            cell.myLabel.text = d.theTitle
            cell.mySwitch.isOn = d.theSwitchState
    
            //set a "Callback Closure" in the cell
            cell.switchTapAction = {
                (isOn) in
                //update our Data Array to the new state of the switch in the cell
                self.myData[indexPath.row].theSwitchState = isOn
            }
    
            return cell
        }
    
    
    }
    • Toll, dieser Rückruf ist die Lösung des Problems. Danke!!!
  2. 0

    Ich denke, Sie müssen Ihre IBAction ändern Sie die Bool jedes mal, wenn Sie einen Schalter umlegen. Derzeit wechseln, ändert sich die Benutzeroberfläche, aber nicht die zugrunde liegenden Bool, so dass die cellForRowAt Methode verwendet den aktuell gespeicherten Wert, wenn die Zelle Schriftrollen zurück auf dem Bildschirm.

  3. 0

    Add-Funktion prepareForReuse() in Ihrer benutzerdefinierten Zelle Klasse und switch Status standardmäßig auf off. -:

     class MyTableViewCell: UITableViewCell {
        @IBOutlet weak var myLabel: UILabel!
        @IBOutlet weak var mySwitch: UISwitch!
    
        override func awakeFromNib() {
            super.awakeFromNib()
            //Initialization code
        }
    
        override func setSelected(_ selected: Bool, animated: Bool) {
            super.setSelected(selected, animated: animated)
    
            //Configure the view for the selected state
        }
    
        @IBAction func switched(_ sender: UISwitch) {
            print("Switched: \(sender.isOn)")
        }
    
        override func prepareForReuse(){
        //SET SWITCH STATE OFF HERE
        }

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.