从特定单元格获取切换状态 [英] Get Switch State from specific cell

查看:35
本文介绍了从特定单元格获取切换状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发具有两个 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 并将 UILabelUISwitch 拖到画布中.将单元格的类设置为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屋!

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