Аксессуары исчезают при прокрутке таблицы |Swift 5 - PullRequest
1 голос
/ 19 сентября 2019

Чего я хотел бы достичь:

У меня есть таблица, которая заполняется с помощью JSON, который получает свои данные из базы данных MySQL.Для декодирования этого JSON я использую следующую структуру:

import UIKit

struct Section {
    let name : String
    var items : [Portfolios]
}

struct Portfolios: Decodable {

    let person: String
    let code: String
    let tick: Int
    var isSelected = false

    enum CodingKeys : String, CodingKey {
        case person, code, tick
    }

}

При каждом выборе и отмене выбора строки должны происходить две вещи:

Selected

1.) В выбранную строку добавлен флажок.

2.) Выполнена функция выбора ().

Отменено

1.) Флажок снят с выбранной строки.

2.) Функция отмены выбора () выполнена.

ex: Из чего выглядят функции selectRow () и unselectRow ():

func selectRow() {
    let url = "https://example.com/example/"
    let parameters: Parameters = ["code": codeSelected]

    Alamofire.request(url, method: .post, parameters: parameters).responseString { response in
        print(response)
    }
}

ПРИМЕЧАНИЕ: Эта функция отправляет параметр в скрипт сценария и изменяет "галочка "значение столбца для этого кода от 1 до 2.

Когда строка не выбрана, функция Unselect () выглядит так же, но служит для обновления записи путем изменения отметки с 2 на 1.

Функция unselectRow () выглядит следующим образом:

func unselectRow() {
    let url = "https://example.com/example/"
    let parameters: Parameters = ["code": codeUnselected]

    Alamofire.request(url, method: .post, parameters: parameters).responseString { response in
        print(response)
    }
}

Чтобы указать значение codeSelected, я изначально использовал didDeselectRowAtи didSelectRowAt

ex:

    structure = sections[indexPath.section].code
    let theStructure = structure[indexPath.row]
    rmaUnselected = theStructure.code

Использование didDeselectRowAt и didSelectRowAt не вызывало никаких проблем, пока я не понял, что аксессуары для галочек исчезали при прокрутке далекодостаточно.

Еще одно предостережение: если выбрана строка, кодовое значение изменяется для этой записи, вспомогательный элемент галочки должен отображаться для этой строки в табличном представлении, как только загружается табличное представление и строка должнабыть уже выбранным.

Я использовал следующее в ячейке willDisplay

if (theStructure.tick == 2) {
    tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)
    cell.accessoryType = .checkmark
} else {
    tableView.deselectRow(at: indexPath, animated: false)
    cell.accessoryType = .none
}

Что я пробовал:

Я попытался изменить то, что происходит, когда ячейки выделены и отменены, но мне все еще нужен код в функциях select () и unselect () для работы.

В cellForRowAt я установил галочку в соответствии сto isSelected

let item = sections[indexPath.section].items[indexPath.row]
cell.accessoryType = item.isSelected ? .checkmark : .none

И я следующее в didSelectRowAt:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    sections[indexPath.section].items[indexPath.row].isSelected.toggle()
    tableView.reloadRows(at: [indexPath], with: .none)
}

1 Ответ

0 голосов
/ 19 сентября 2019

Последняя попытка:

Поскольку выбор обозначен tick, свойство isSelected фактически избыточно, но вы можете использовать его для преобразования значения Int в более подходящее Bool.Чтобы иметь возможность изменить tick сделать его изменяемым.

И, пожалуйста, назовите Portfolio в единственном числе

struct Portfolio: Decodable {

    let person: String
    let code: String
    var tick: Int

    var isSelected : Bool {
        get { return tick == 2 }
        set { tick = newValue ? 2 : 1 }
    }

    enum CodingKeys : String, CodingKey {
        case person, code, tick
    }
}

Замените selectRow на updateSelection(of:at:), что занимает Portfolioпараметр и indexPath.Табличное представление перезагружается, только если сетевой запрос был успешным.Я не знаю, какую строку возвращает запрос Alamofire.Было бы еще безопаснее сначала обновить базу данных, а затем обновить Portfolio.

func updateSelection(of portfolio: Portfolio, at indexPath: IndexPath) {
    let url = portfolio.isSelected ? "https://example.com/example/selected" : "https://example.com/example/unselected"
    let parameters: Parameters = [portfolio.code: portfolio.tick]

    Alamofire.request(url, method: .post, parameters: parameters).responseString { response in
        switch response.result {
        case .success(let string): self.tableView.reloadRows(at: [indexPath], with: .none)
        case .failure(let error): print(error)
        }        

    }
}

In didSelectRowAt, переключить isSelected (который обновляет tick неявно) и обновить базу данных.

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    sections[indexPath.section].items[indexPath.row].isSelected.toggle()
    let portfolio = sections[indexPath.section].items[indexPath.row]
    updateSelection(of: portfolio, at: indexPath)
}

Вы можете оставить код в cellForRow

let item = sections[indexPath.section].items[indexPath.row]
cell.accessoryType = item.isSelected ? .checkmark : .none

, но удалить метод willDisplayCell

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...