@fakin_kiska
Telegram Bots and iOS

Как отредактировать ячейку в TableView по ID?

У меня есть таблица в первом ViewController'е, в которую можно через второй VC либо добавлять новые ячейки, либо редактировать существующие

По скриншотам будет нагляднее, это добавление новой ячейки
6389d32ee83e8072419870.png
6389d350555f9693686542.png

Это редактирование
6389d359f0276656408189.png
6389d3a16580d167059390.png
6389d3ac47380350947703.png

Структура для ячейки и массив:
struct Record {
    var amount: Float
    var descriptionText: String = ""
    var categoryText: String = ""
    var categoryImage: String = ""
    var date: Date
    var id: Int
}
var cellArr = [Record]()


Я присваиваю всем созданным ячейкам уникальный ID на этапе получения данных со второго VC. Мне нужно достать ID при редактировании ячейки, либо создать новую

func sendNewOperation(amount: Float, description: String, category: String,
                          image: String, date: Date, switcher: String) {
        
        let operationID = Int.random(in: 0...10000)
                
        if (self.cellArr.count > 0) { // Добавление или редактирование ячейки
            for i in 0..<(self.cellArr.count) {
                print("id: \(cellArr[i].id)")
                if cellArr.filter({ $0.id == cellArr[i].id && $0.id != cellArr[i].id }).isEmpty { // ???
                    self.cellArr[i] = Record(amount: amount, descriptionText: description, categoryText: category, categoryImage: image, date: date, id: cellArr[i].id)
                    self.tableView.reloadData()
                } else {
                    self.cellArr.append(Record(amount: amount, descriptionText: description, categoryText: category, categoryImage: image, date: date, id: operationID))
                    self.tableView.insertRows(at: [IndexPath(row: self.cellArr.count - 1, section: 0)], with: .automatic) // + 1 ячейка
                }
            }
        }
        if (self.cellArr.isEmpty == true) { // Добавить первую ячейку, записывается рандомный ID
            self.cellArr.append(Record(amount: amount, descriptionText: description, categoryText: category, categoryImage: image, date: date, id: operationID))
            self.tableView.insertRows(at: [IndexPath(row: self.cellArr.count - 1, section: 0)], with: .automatic) // + 1 ячейка
        }
    }


У меня возникает сложность с тем, что я не могу создать больше 1 ячейки, так как все последующие вне зависимости от действия только редактируются, то есть в else код не заходит. Но если я уберу в условии $0.id != cellArr[i].id, то существующая ячейка будет дублироваться
  • Вопрос задан
  • 51 просмотр
Решения вопроса 1
@fakin_kiska Автор вопроса
Telegram Bots and iOS
Переделал функцию sendNewOperation, теперь она выглядит таким образом:

func sendNewOperation(id: Int?, amount: Float, description: String, category: String,
                          image: String, date: Date, switcher: String) {
        if let oldCellId = id {
            if let ix = self.cellArr.firstIndex(where: { searchedRecord in
                searchedRecord.id == oldCellId
            }) { 
                self.cellArr[ix] = Record(amount: amount, descriptionText: description, categoryText: category, categoryImage: image, date: date, id: oldCellId)
                self.tableView.reloadRows(at: [IndexPath(row: ix, section: 0)], with: .automatic)
            } else {
                fatalError("couldn't edit old cell #\(oldCellId)")
            } // Создается новая ячейка
        } else {
            let operationID = Int.random(in: 0...10000)
            print("id: \(operationID)")
            self.cellArr.append(Record(amount: amount, descriptionText: description, categoryText: category, categoryImage: image, date: date, id: operationID)) // Добавление в массив нового элемента
            self.tableView.insertRows(at: [IndexPath(row: self.cellArr.count - 1, section: 0)], with: .automatic)
        }
    }


Так у меня происходит передача данных со второго контроллера при нажатии на кнопку "Сохранить":
var operationID: Int?
    let homeViewController: HomeViewController
    init(homeViewController: HomeViewController, operationID: Int?) {
        self.homeViewController = homeViewController
        self.operationID = operationID
        super.init(nibName: nil, bundle: nil)
    }         
            
    @objc func saveButtonAction(sender: AnyObject) {

        addNewOpDelegate?.sendNewOperation(id: operationID, amount: abs(amount), description: descriptionTextField.text!, category: categoryButton.titleLabel!.text!, image: categoryImage, date: datePicker.date, switcher: segment)
            
        self.navigationController?.popToRootViewController(animated: true) // Закрыть AddNewOperationVC
    }

    // Протокол отправки всех введенных значений операции
    protocol AddNewOpSendData: AnyObject {
    func sendNewOperation(id: Int?, amount: Float, description: String, category: String, image: String, date: Date, switcher: String)
}


Первый контроллер:

@objc func AddNewOperation() {
        let vc = AddNewOperationVC(homeViewController: self, operationID: nil)
        vc.addNewOpDelegate = self
        navigationController?.pushViewController(vc, animated: true)
    }
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы