如何在swift 3中根据数组做选中勾选?
我有一个数组,其中选定的名称将被存储并传递到视图控制器之前,当我需要去以前的视图控制器,然后以前选定的复选标记需要被选中,但在这里是启用最后选定的元素只有问题是如果我select三,那么它不是select三它是检查标记只有最后一个元素,但我需要三个选定任何人都可以帮助我如何使复选标记被选中的三个要素?
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]()
parsingJSON数据并做一个(更好的)error handling
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...
将名称分配给标签并根据selected
设置复selected
标记
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) }
获取所有select的项目也非常容易。
let selectedItems = products.filter{ $0.selected }
或者只有名字
let selectedNames = products.filter{ $0.selected }.map{ $0.name }
从这个angular度来看,根本不需要任何信息。 控制器始终从模型中获取信息,并使用tableview数据源和委托来更新视图 。
如果要将数据传递给另一个视图控制器传递Product
实例。 它们包含所有相关信息。