这很奇怪:我只是建立了一个新的单视图iOS项目并将一个TableView放入Main.storyboard。在这个TableView中,我把一个TableViewCell放到这个Cell中,我放了一个UILabel和一个UISwitch。 对于这个TableViewCell,我创建了一个CocoaTouchClass MyTableViewCell,并在Interfacebuilder中为TableViewCell的Class设置了它。 我将UILabel和UISwitch的Outlets连接到MyTableViewCell,以及切换操作。 我还将TableView的dataSource和委托连接到ViewController。
因此,正如我所想,设置表格的基本内容。
我的ViewController看起来像这样:
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切换为开启。
MyTableViewCell-Class也没什么特别之处:
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表线不适合一个屏幕,因此TableView使其自身可滚动。
现在:当我更改一个UISwitch的状态,然后拖动TableView以使更改的UISwitch离开视图然后拖动TableView以便更改的UISwitch再次可见,它将更改回其初始状态。 Switch-event会像它应该被触发一样。
那么,我做错了什么?我错过了什么吗?
我录制了一个4秒的截屏视频来演示,发生了什么: http://b-bereich.de/download/swiftSwitch.mov
答案 0 :(得分:2)
TableViewCells 重用 。
这意味着您需要跟踪用于填充单元格内容的数据。如果单元格内容发生更改(例如,当您在单元格中点击Switch时),则需要更新数据源。滚动时,再次显示该行,您的数据将知道如何设置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
}
}
答案 1 :(得分:0)
我认为每次翻开开关时都需要让IBAction更改Bool。目前,交换机会更改UI但不会更改底层Bool,因此当单元格在屏幕上滚动时,cellForRowAt
方法会使用当前保存的值。
答案 2 :(得分:0)
在自定义单元类中添加函数prepareForReuse(),默认情况下将开关状态设置为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
}