Ios 如何根据swift 3中的数组选择复选标记?

Ios 如何根据swift 3中的数组选择复选标记?,ios,uitableview,swift3,Ios,Uitableview,Swift3,我有一个数组,其中所选的名称将被存储并传递到视图控制器之前,当我需要转到上一个视图控制器时,则需要选择上一个选中的复选标记,但这里启用的是最后一个选中的元素。唯一的问题是,如果我选择了三个,则它没有选择三个,而是选中了三个只有最后一个元素,但我需要选择的三个元素。有人能帮助我如何为这三个元素选择复选标记吗 protocol ArrayToPass: class { func selectedArrayToPass(selectedStrings: [String]) } class Fi

我有一个数组,其中所选的名称将被存储并传递到视图控制器之前,当我需要转到上一个视图控制器时,则需要选择上一个选中的复选标记,但这里启用的是最后一个选中的元素。唯一的问题是,如果我选择了三个,则它没有选择三个,而是选中了三个只有最后一个元素,但我需要选择的三个元素。有人能帮助我如何为这三个元素选择复选标记吗

protocol ArrayToPass: class {
    func selectedArrayToPass(selectedStrings: [String])
}
class FilterSelectionViewController: UIViewController,UITableViewDataSource,UITableViewDelegate {

    var productName = [String]()
    var productprice = [String]()
    var imageArray = [String]()
    var idArray = [Int]()
    let urlString = "http://www.json-generator.com/api/json/get/bOYOrkIOSq?indent=2"
    var values = [String]()
    var selected: Bool?
    var delegate: ArrayToPass?
    var nameSelection: Bool?
    var namesArray = [String]()

    override func viewDidLoad() {
        super.viewDidLoad()
        self.downloadJsonWithURL()
        tableDetails.separatorInset = UIEdgeInsets.zero
        activityIndicator.startAnimating()
        tableDetails.isHidden = true
        tableDetails.dataSource = self
        tableDetails.delegate = self
        let rightBarButton = UIBarButtonItem(title: "Apply", style: UIBarButtonItemStyle.plain, target: self, action: #selector(applyBarButtonActionTapped(_:)))
        self.navigationItem.rightBarButtonItem = rightBarButton
        tableDetails.estimatedRowHeight = UITableViewAutomaticDimension
        tableDetails.rowHeight = 60
        // Do any additional setup after loading the view.
    }
    func applyBarButtonActionTapped(_ sender:UIBarButtonItem!){
        self.delegate?.selectedArrayToPass(selectedStrings: values)
        navigationController?.popViewController(animated: true)
    }
    func downloadJsonWithURL() {
        let url = NSURL(string: urlString)
        URLSession.shared.dataTask(with: (url as URL?)!, completionHandler: {(data, response, error) -> Void in
            if let jsonObj = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? NSArray {
                for item in jsonObj! {
                    if let itemDict = item as? NSDictionary{
                        if let name = itemDict.value(forKey: "name") {
                            self.productName.append(name as! String)
                        }
                        if let price = itemDict.value(forKey: "value") {
                            self.productprice.append(price as! String)
                        }
                        if let image = itemDict.value(forKey: "img") {
                            self.imageArray.append(image as! String)
                        }
                        if let id = itemDict.value(forKey: "id") {
                            self.idArray.append(id as! Int)
                        }
                    }
                }
                OperationQueue.main.addOperation({
                    self.tableDetails.reloadData()
                })
            }
        }).resume()
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return productName.count
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "filterSelectionCell", for: indexPath) as! FilterSelectionCell
        activityIndicator.stopAnimating()
        activityIndicator.hidesWhenStopped = true
        tableDetails.isHidden = false
        cell.brandProductName.text = productName[indexPath.row]
        if nameSelection == true{
            if namesArray.count != 0 {
                print(namesArray)
                for name in namesArray{
                    if productName[indexPath.row].contains(name){
                        print(productName[indexPath.row])
                        cell.accessoryType = .checkmark
                    }
                    else {
                        cell.accessoryType = .none
                    }
                }
            }
        }
        return cell
    }
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){
        selected = false
        if let cell = tableView.cellForRow(at: indexPath as IndexPath) {
            if cell.accessoryType == .checkmark{
                cell.accessoryType = .none
                print("\(productName[indexPath.row])")
                values = values.filter{$0 != "\(productName[indexPath.row])"}
                selected = true
            }
            else{
                cell.accessoryType = .checkmark
            }
        }
        if selected == true{
            print(values)
        }
        else{
            getAllTextFromTableView()
        }
        print(values)
    }
    func getAllTextFromTableView() {
    guard let indexPaths = self.tableDetails.indexPathsForSelectedRows else { // if no selected cells just return
    return
    }

    for indexPath in indexPaths {
        values.append(productName[indexPath.row])
    }
    }

基本上不操纵视图(单元格)。使用数据模型

struct Product {
    let name : String
    let value : String
    let img : String
    let id : Int

    var selected = false

    init(dict : [String:Any]) {
        self.name = dict["name"] as? String ?? ""
        self.value = dict["value"] as? String ?? ""
        self.img = dict["img"] as? String ?? ""
        self.id = dict["id"] as? Int ?? 0
    }
}
切勿将多个数组用作数据源。那是一个非常坏的习惯

将数据源数组声明为

var products = [Product]()
解析JSON数据并进行(更好的)错误处理

func downloadJsonWithURL() {
    let url = URL(string: urlString)!
    let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
        if error != nil { print(error!); return }
        do {
            if let jsonObj = try JSONSerialization.jsonObject(with: data!) as? [[String:Any]] {
                self.products = jsonObj.map{ Product(dict: $0) }                
                DispatchQueue.main.async {
                    self.tableDetails.reloadData()
                }
            }
        } catch {
            print(error)
        }
    }
    task.resume()
}
cellForRow…
中,根据所选
为标签指定名称并设置复选标记

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "filterSelectionCell", for: indexPath)

    let product = products[indexPath.row]
    cell.textLabel!.text = product.name
    cell.accessoryType = product.selected ? .checkmark : .none
    return cell
}
didSelect…
中切换
selected
并重新加载行

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let selected = products[indexPath.row].selected
    products[indexPath.row].selected = !selected
    tableView.reloadRows(at: [indexPath], with: .none)
}

获取所有选定项目也非常容易

let selectedItems = products.filter{ $0.selected }
或者只知道名字

let selectedNames = products.filter{ $0.selected }.map{ $0.name }
根本不需要从视图中获取任何信息。控制器始终从模型获取信息,并使用tableview数据源和委托更新视图


如果要将数据传递给另一个视图控制器,请传递
Product
实例。它们包含所有相关信息。

基本上不操纵视图(单元格)。使用数据模型

struct Product {
    let name : String
    let value : String
    let img : String
    let id : Int

    var selected = false

    init(dict : [String:Any]) {
        self.name = dict["name"] as? String ?? ""
        self.value = dict["value"] as? String ?? ""
        self.img = dict["img"] as? String ?? ""
        self.id = dict["id"] as? Int ?? 0
    }
}
切勿将多个数组用作数据源。那是一个非常坏的习惯

将数据源数组声明为

var products = [Product]()
解析JSON数据并进行(更好的)错误处理

func downloadJsonWithURL() {
    let url = URL(string: urlString)!
    let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
        if error != nil { print(error!); return }
        do {
            if let jsonObj = try JSONSerialization.jsonObject(with: data!) as? [[String:Any]] {
                self.products = jsonObj.map{ Product(dict: $0) }                
                DispatchQueue.main.async {
                    self.tableDetails.reloadData()
                }
            }
        } catch {
            print(error)
        }
    }
    task.resume()
}
cellForRow…
中,根据所选
为标签指定名称并设置复选标记

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "filterSelectionCell", for: indexPath)

    let product = products[indexPath.row]
    cell.textLabel!.text = product.name
    cell.accessoryType = product.selected ? .checkmark : .none
    return cell
}
didSelect…
中切换
selected
并重新加载行

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let selected = products[indexPath.row].selected
    products[indexPath.row].selected = !selected
    tableView.reloadRows(at: [indexPath], with: .none)
}

获取所有选定项目也非常容易

let selectedItems = products.filter{ $0.selected }
或者只知道名字

let selectedNames = products.filter{ $0.selected }.map{ $0.name }
根本不需要从视图中获取任何信息。控制器始终从模型获取信息,并使用tableview数据源和委托更新视图



如果要将数据传递给另一个视图控制器,请传递
Product
实例。它们包含所有相关信息。

您如何将阵列发送回first view controller?我正在使用协议将数据传递给另一个view controller@Aravindar。当我从first view controller返回到previous时,我需要勾选先前选择的,以便选择其他更多品牌@Aravindar。您呢在发送回数据后重新加载表?这里重新加载表视图的需要是什么@TJ3您如何将阵列发送回第一视图控制器?我正在使用协议将数据传递给另一个视图控制器@Aravindar当我从第一视图控制器返回到上一视图控制器时,我需要选中先前选中的,为了选择其他更多品牌@Aravindar,在发送数据后是否重新加载表返回?这里需要重新加载表视图吗@TJ3从模型u r获得数据很好,但首先我需要将整个数据发送到表视图,在表视图中我将选择一些数据,但这里的数组在选择后是空的,然后数据将在数组中,因为u表示对象数组。您的设计非常麻烦。不要使用像
namesArray
这样的临时数组。你可以用这个模型做任何事情
cellForRow
仅用于更新用户界面,没别的。不管你说什么都可以,但作为一名实习生,我无法完全理解,但我明白,永远不要不使用视图管理一切,尝试使用模型类u r进行管理,并说@vadian如果可能,请提供一个示例项目,该项目使用视图@vadian以外的模型进行管理答案中的代码包含所有组件。这很简单。使用模型而不是
productName
[String]
)创建数据源数组,模型的初始值设定项传递字符串。用您的标识符替换单元格标识符。从模型u r获得数据很好,但首先我需要将整个数据发送到表视图,在表视图中我将选择一些数据,但这里的数组是空的,如选择后所述,然后数据将在数组中,因为u表示对象数组。您的设计非常麻烦。不要使用像
namesArray
这样的临时数组。你可以用这个模型做任何事情
cellForRow
仅用于更新用户界面,没别的。不管你说什么都可以,但作为一名实习生,我无法完全理解,但我明白,永远不要不使用视图管理一切,尝试使用模型类u r进行管理,并说@vadian如果可能,请提供一个示例项目,该项目使用视图@vadian以外的模型进行管理答案中的代码包含所有组件。这很简单。使用模型而不是
productName
[String]
)创建数据源数组,模型的初始值设定项传递字符串。将单元格标识符替换为您的标识符。