Swift 3 UISwitch in TableViewCell loses State when scrolling

后端 未结 3 1550
感情败类
感情败类 2020-12-12 07:38

That\'s weird: I just set up a new Single-View iOS Project and put a TableView into the Main.storyboard. In this TableView I put a TableViewCell and into this Cell, I put an

相关标签:
3条回答
  • 2020-12-12 08:18

    Add function prepareForReuse() in your custom cell class and set switch state to off by default. -:

     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
        }
    
    0 讨论(0)
  • 2020-12-12 08:20

    TableViewCells are reused.

    That means you need to keep track of the data you are using to fill the content of the cells. If the cell content changes - such as when you tap a Switch in the cell - you need to update your datasource. When you scroll, and that row is displayed again, your data will know how to set the state of the Switch.

    Here is a simple example:

    //
    //  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
        }
    
    
    }
    
    0 讨论(0)
  • 2020-12-12 08:30

    I think you need to have your IBAction change the Bool each time you flip the switch. Currently the switch changes the UI but not the underlying Bool so the cellForRowAt method uses the currently saved value when the cell scrolls back on screen.

    0 讨论(0)
提交回复
热议问题