Сортировка ввода ячейки из настроенной ячейки в ViewController

#ios #arrays #swift #sorting #tableviewcell

#iOS #массивы #swift #сортировка #tableviewcell

Вопрос:

У меня есть ViewController, в который интегрированы TableView и кнопка «сортировать». Ячейки этого TableView настраиваются в другом классе, который называется «customizedCell».

Когда ViewController загружен, метка (riskTitle: UITextView! в ячейке (CellCustomized) в TableView заполняется элементами, хранящимися в массиве (RiskTitles_Plan = Строка в ViewController). В моем приведенном ниже коде некоторые значения жестко запрограммированы для этого массива.

Сейчас я пытаюсь сохранить числа, сгенерированные двумя pickerViews, в метке «riskFactor: UILabel!» в массиве (RiskFactor_Plan -> RiskFactor_Int). Когда пользователь нажимает на кнопку сортировки, значения в моем массиве должны быть отсортированы, а строки в TableView будут загружены в новом порядке (от наименьшего к наибольшему числу или наоборот).

Это мой код (ненужный код удален).

Swift 3 — ViewController:

 import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    var RiskTitles_Plan = [String]()
    var RiskFactor_Plan = [String]()
    var RiskFactor_Plan_Int = [Int]()

    var sortBtn = UIButton()

    override func viewDidLoad() {
        super.viewDidLoad()

        RiskTitles_Plan = ["my cat","my dog","my sheep","my cow","my fish"]

        sortBtn.setImage(UIImage(named: "Sort"), for: UIControlState.normal)
        sortBtn.addTarget(self, action: #selector(RiskPlan.sortAction(_:)), for: .touchUpInside)
        self.view.addSubview(sortBtn)
    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return RiskTitles_Plan.count
    }

 /////// Here comes the interesting part ///////

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = self.tableView!.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CellCustomized

        RiskFactor_Plan.append(cell.riskFactor.text!)
        cell.riskTitle?.text = RiskTitles_Plan[indexPath.row]
        cell.backgroundColor = myColorsClass.darkCyan()

        for i in RiskFactor_Plan_Int {
            let stringItem: String = String(i)
            RiskFactor_Plan.append(stringItem)
        }

        cell.riskFactor.text! = RiskFactor_Plan[indexPath.row]

        return cell
    }

    func sortAction(_ sender:UIButton!) {

        for i in RiskFactor_Plan {
            let intItem: Int = Int(i)!
            RiskFactor_Plan_Int.append(intItem)
        }

        RiskFactor_Plan_Int = RiskFactor_Plan_Int.sorted{ $0 < $1 }
        tableView.reloadData()
    }
}
  

Swift 3 — Настраиваемая ячейка:

 import UIKit

class CellCustomized: UITableViewCell {

    var myColorsClass = myColors()
    var myStylesClass = myStyles()

    @IBOutlet weak var riskTitle: UITextView!
    @IBOutlet weak var riskFactor: UILabel!

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier) // the common code is executed in this super call

    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func awakeFromNib() {
        super.awakeFromNib()

    } // nib end

}
  

Приведенный выше код приводит к ошибке fatal error: unexpectedly found nil while unwrapping an Optional value для строки кода: let intItem: Int = Int(i)! в ViewController при нажатии кнопки сортировки.

Моя проблема заключается в том, чтобы выяснить

  • как сохранить сгенерированные значения в riskFactor: UILabel! в массиве (-> RiskTitles_Plan = String) во время выполнения. Я предполагаю, что массив необходимо добавлять всякий раз, когда метка в таблице обновляется с сгенерированным значением

  • как преобразовать массив строк (-> RiskTitles_Plan = String) в массив целых чисел (-> RiskTitles_Plan_Int = Int)

Ответ №1:

Исходя из контекста вашей проблемы, я попытался воспроизвести ее в проекте, так что вот как я это делаю, надеюсь, это поможет вам.

Результат:

Код:

 class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource{
  @IBOutlet weak var tableView: UITableView!
  
  var risks = Array<(title: String, factor: Int)>()

  override func viewDidLoad() {
    super.viewDidLoad()
    
    tableView.delegate = self
    tableView.dataSource = self
    
    risks.append(("my cat", 0))
    risks.append(("my dog", 0))
    risks.append(("my sheep", 0))
    risks.append(("my cow", 0))
    risks.append(("my fish", 0))
  }
  
  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return risks.count
  }
  
  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell
    
    let riskTitle = risks[indexPath.row].title
    let riskFactor = risks[indexPath.row].factor
    
    cell.titleLabel.text = riskTitle
    cell.factorLabel.text = String(riskFactor)
    cell.index = indexPath.row
    
    
    cell.onFactorValueChanged = { [unowned self] newFactorValue, atIndex in
      self.risks[atIndex].factor = newFactorValue
    }
    
    return cell
  }
  
  @IBAction func sortRisksBasedOnFactor(_ sender: AnyObject) {
    risks.sort { (riskA, riskB) -> Bool in
      return riskA.factor > riskB.factor
    }
    
    tableView.reloadData()
  }
}
  

 class TableViewCell: UITableViewCell {
  
  @IBOutlet weak var titleLabel: UILabel!
  @IBOutlet weak var factorLabel: UILabel!
  var index = 0
 
  var onFactorValueChanged: (Int, Int) -> Void = { _ in }
 
  @IBAction func generateFactor(_ sender: AnyObject) {
    factorLabel.text = String(random(min: 1, max: 10))
    onFactorValueChanged(Int(factorLabel.text!)!, index)
  }
  
  func random(min: Int, max: Int) -> Int {
    guard min < max else {return min}
    return Int(arc4random_uniform(UInt32(1   max - min)))   min
  }
  
}
  

Комментарии:

1. Это решение работает до тех пор, пока таблица состоит только из двух полей. Это связано с тем, что сортируется не строка, а значения. Это приводит к проблеме, заключающейся в том, что, когда у меня есть еще несколько полей (например, у меня также есть pickerView в моем классе CustomizedCell), поля не являются частью процедуры сортировки, и все значения таблицы смешиваются после нажатия кнопки сортировки. Я расширил ваш пример в отношении других полей в моем классе CustomizedCell, но затем у меня возникли проблемы с вычисляемым значением метки. Возможно, мне нужна совершенно другая попытка.