从特定单元格获取切换状态 [英] Get Switch State from specific cell
问题描述
我正在开发具有两个 ViewController
的 iOS 应用.第一个是 TableView
,它为数组中的每个索引创建一行.这个TableView
的每个单元格都显示了索引对应的数组中的内容,并有一个开关.第二个 ViewController
有一个图像和一个标签,它们应该根据开关状态而改变.那么,如何从特定单元格获取开关状态?
I am working on a iOS app that has two ViewControllers
. The first is a TableView
which creates a row for each index in a array. Each cell of this TableView
shows the content in the array corresponding to the index and has a switch. The second ViewController
has an image and a label and they are supposed to change depending the switch state. So, how can I get the switch state from a specific cell?
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet weak var state_label: UILabel!
@IBOutlet weak var descr_label: UILabel!
@IBOutlet weak var myimg: UIImageView!
let arr: [String] = ["Text1","Text2", "Text3", "Text4"]
var switch_isOn = false
override func viewDidLoad() {
super.viewDidLoad()
if(switch_isOn == false){
myimg?.image = UIImage(named: "img1")
}else{
myimg?.image = UIImage(named: "img2")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arr.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "cell")
cell.textLabel?.text = arr[indexPath.row]
let mySwitch = UISwitch()
cell.accessoryView = mySwitch
mySwitch.tag = 1001
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let segueIdentifier: String
segueIdentifier = "segue"
// Get the selected Cell and Iterate through it's subviews to find the switch using the tag
let cell = tableView.cellForRow(at: indexPath)
//Get the Cell Text
print("\(cell?.textLabel?.text ?? "")")
// Iterate through subviews of Cell
for v in cell?.subviews ?? [] {
// If a view found with tag == 1001 then it's the switch view because we had assigned 1001 to the switch view
if v.tag == 1001 {
// One last check we cast the view to UISwitch if it succeed then it's the switch view
if let mySwitch = v as? UISwitch {
if(mySwitch.isOn == true){
descr_label?.text = "\(cell?.textLabel?.text ?? "")"
print("The cell has the Switch On")
switch_isOn = true
}else{
descr_label?.text = "\(cell?.textLabel?.text ?? "")"
switch_isOn = false
print("The cell has the Switch Off")
}
}
}
}
self.performSegue(withIdentifier: segueIdentifier, sender: self)
}
}
推荐答案
使用开关的附件视图似乎是一个简单的解决方案,但访问视图非常麻烦.类似于 for v in cell?.subviews ??[]
和处理标签是可怕的.
Using the accessory view for the switch seems to be an easy solution but it's very cumbersome to access the view. Something like for v in cell?.subviews ?? []
and dealing with tags is horrible.
更好 更有效的解决方案是自定义单元格类.
A better more efficient solution is a custom cell class.
在 Interface Builder 中,将单元格的样式设置为 custom
并将 UILabel
和 UISwitch
拖到画布中.将单元格的类设置为TableViewCell
.
In Interface Builder set the style of the cell to custom
and drag an UILabel
and an UISwitch
into the canvas. Set the class of the cell to TableViewCell
.
添加一个新的 CocoaTouch 类 TableViewCell
作为 UITableViewCell
的子类.您需要两个 IBOutlets、一个 IBAction 和一个 callback
变量.回调对于保持模型中的开关状态很重要.连接插座和 IB 中的动作.
Add a new CocoaTouch class TableViewCell
as subclass of UITableViewCell
. You need two IBOutlets, one IBAction and a callback
variable. The callback is important to keep the state of the switch in the model. Connect the outlets and the action in IB.
class TableViewCell: UITableViewCell {
@IBOutlet weak var switcher : UISwitch!
@IBOutlet weak var label : UILabel!
var callback : ((Bool)->())?
@IBAction func switchChanged(_ sender : UISwitch) {
callback?(sender.isOn)
}
}
创建一个包含文本和开关状态的数据源模型
Create a data source model containing the text and the state of the switch
struct Item {
var text : String
var isSelected : Bool
init(text : String, isSelected : Bool = false {
self.text = text
self.isSelected = isSelected
}
}
声明数据源数组
var arr : [Item] = [Item(text: "Text1"), Item(text: "Text2"), Item(text: "Text3"), Item(text: "Text4")]
用
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell
let item = arr[indexPath.row]
cell.label.text = item.text
cell.switcher.isOn = item.isSelected
// the callback updates the model and is called when the value of the switch changes
cell.callback = { newValue in
item.isSelected = newValue
}
return cell
}
将 didSelectRow
替换为(是的,它只有一行,它将索引路径作为 sender
参数传递)
Replace didSelectRow
with (yes, it's only one line, it passes the index path as sender
parameter)
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.performSegue(withIdentifier: "segue", sender: indexPath)
}
最终实现prepare(for segue
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "segue" {
let viewController = segue.destination as! ViewController // the class of the second view controller
// get the current index path
let indexPath = sender as! IndexPath
let item = arr[indexPath.row]
// get the state of the switch from the model, not from the view
let isSelected = item.isSelected
// do something with `isSelected`
}
}
}
这篇关于从特定单元格获取切换状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!