TableViewCell 中的 Swift 3 UISwitch 在滚动时丢失状态 [英] Swift 3 UISwitch in TableViewCell loses State when scrolling

查看:14
本文介绍了TableViewCell 中的 Swift 3 UISwitch 在滚动时丢失状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这很奇怪:我刚刚设置了一个新的单视图 iOS 项目,并将一个 TableView 放入 Main.storyboard.在这个 TableView 中,我放了一个 TableViewCell,在这个 Cell 中,我放了一个 UILabel 和一个 UISwitch.对于这个 TableViewCell,我创建了一个 CocoaTouchClass MyTableViewCell 并在 Interfacebuilder 中为 TableViewCell 的类设置它.我将 UILabel 和 UISwitch 的 Outlets 连接到 MyTableViewCell,以及用于切换的操作.我还连接了 TableView 的数据源并委托给了 ViewController.

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 UILabel and an UISwitch. For this TableViewCell I created a CocoaTouchClass MyTableViewCell and set this for the TableViewCell's Class in Interfacebuilder. I connected Outlets for the UILabel and UISwitch to MyTableViewCell, as well as an action for the switch. Also I connected the TableView's dataSource and delegate to the ViewController.

所以,我认为,设置桌子的基本东西.

So, as I think, basic stuff for setting up a table.

我的 ViewController 如下所示:

My ViewController looks like this:

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
}

}

所以,我用一些数据行填充表格,并每隔一秒切换一次 UISwitch.

So, I populate the Table with some Rows of Data and switch every second UISwitch to on.

MyTableViewCell-Class 也没什么特别的:

The MyTableViewCell-Class is nothing special as well:

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)")
}

}

好的,启动 iOS 模拟器,我会按预期看到表格.40 Table-Lines 不能在一个屏幕上显示,所以 TableView 使自己可以滚动.

Ok, fire up the iOS-Simulator and I see the Table as expected. 40 Table-Lines don't fit on one screen, so the TableView makes itself scrollable.

现在:当我更改一个 UISwitch 的状态,并拖动 TableView 使更改后的 UISwitch 离开视图,然后拖动 TableView 使更改后的 UISwitch 再次可见时,它会更改回其初始状态.Switch 事件会像它应该的那样被触发.

Now: when I change the state of one UISwitch, and drag the TableView so the changed UISwitch gets out of view and then drag the TableView so the changed UISwitch gets visible again, it is changed back to its initial state. The Switch-event gets fired like it should.

那么,我做错了什么?我错过了什么吗?

So, what am I doing wrong? Am I missing something?

我录制了一个 4 秒的截屏视频来演示发生了什么:http://b-bereich.de/download/swiftSwitch.mov

I recorded a 4-seconds-Screencast to demonstrate, what's going on: http://b-bereich.de/download/swiftSwitch.mov

推荐答案

TableViewCells 被重用.

TableViewCells are reused.

这意味着您需要跟踪用于填充单元格内容的数据.如果单元格内容发生变化 - 例如当您点击单元格中的开关时 - 您需要更新您的数据源.当您滚动时,该行再次显示,您的数据将知道如何设置 Switch 的状态.

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.

这是一个简单的例子:

//
//  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
    }


}

这篇关于TableViewCell 中的 Swift 3 UISwitch 在滚动时丢失状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆