1

我想完成的事情:

我有使用从 mySQL 数据库获取数据的 JSON 填充的 tableview。要解码此 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
    }

}

每次选择和取消选择一行时,必须发生两件事:

已选中

1.)选中的行添加了复选标记附件。

2.)执行 Select() 函数。

取消选择

1.)选中的行已删除复选标记附件。

2.) Unselect() 函数被执行。

例如: 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)
    }
}

注意: 此函数将参数发送到后端脚本并将该代码的“tick”列值从 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 的值,我最初使用didDeselectRowAtanddidSelectRowAt

前任:

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

使用didDeselectRowAtanddidSelectRowAt并没有引起任何问题,直到我意识到滚动足够远时复选标记附件消失了。

另一个需要注意的是,如果选择了一行,则该记录的代码值发生更改,一旦表视图加载并且该行需要已经被选中,复选标记附件需要在表视图中显示该行。

我在 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 我根据 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)
}
4

1 回答 1

0

最后一次尝试:

由于属性指示的选择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
    }
}

替换selectRowupdateSelection(of:at:)which 接受一个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)
        }        

    }
}

didSelectRowAt切换isSelectedtick隐式更新)并更新数据库。

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

于 2019-09-19T14:26:50.727 回答