如何将 tableview header 和 cellForRowAt 与 swift 中的相同 json 分开

How to separate tableview header and cellForRowAt from same json in swift

我想将国家/地区代码显示为 table 视图的 header,点击 header 场地后应该会显示。我试过了,但我无法达到预期的输出。

这是我的 json :

{
  "meetings": [
    {
      "meetingId": 31389393,
      "name": "Ludlow 20th Apr",
      "openDate": "2022-04-20T12:00:00+00:00",
      "venue": "Ludlow",
      "eventTypeId": 7,
      "countryCode": "GB",
      "meetingGoing": "Good"
    },
    {
      "meetingId": 31389469,
      "name": "Catterick 20th Apr",
      "openDate": "2022-04-20T12:40:00+00:00",
      "venue": "Catterick",
      "eventTypeId": 7,
      "countryCode": "GB",
      "meetingGoing": "Good (Good to Soft in places)"
    },
    {
      "meetingId": 31389416,
      "name": "Perth 20th Apr",
      "openDate": "2022-04-20T12:50:00+00:00",
      "venue": "Perth",
      "eventTypeId": 7,
      "countryCode": "GB",
      "meetingGoing": "Good to Soft (Good in places)"
    },
    {
      "meetingId": 31389532,
      "name": "Lingfield 20th Apr",
      "openDate": "2022-04-20T15:15:00+00:00",
      "venue": "Lingfield",
      "eventTypeId": 7,
      "countryCode": "GB",
      "meetingGoing": "Standard"
    },
    {
      "meetingId": 31389447,
      "name": "Salisbury 20th Apr",
      "openDate": "2022-04-20T15:25:00+00:00",
      "venue": "Salisbury",
      "eventTypeId": 7,
      "countryCode": "GB",
      "meetingGoing": "Good to Firm (Good in places)"
    }
  ]
}

这是我用来获取数据的代码:

    struct Racing{
        var countryCode:String
        var venue: [String]
        var races: [Races]?
    }
    
    var todayRacingArray = [Racing]()
    APIClient2<RacingListBaseClass>().API_GET(Url: url, Params: noParams, Authentication: false, Progress: false, Alert: true, Offline: false, SuperVC: self, completionSuccess: { (response) in
    for item in response.meetings ?? []
    {
       let cc = item.countryCode
       var venue = [String]()
       ven.append(item.venue ?? "")
       let obj = Racing(countryCode: cc ?? "", venue: venue)
       self.todayRacingArray.append(obj)
    }
    self.otherSportsTableView.reloadData()
 }) { (failed) in
            
        }

表格视图:

func numberOfSections(in tableView: UITableView) -> Int {
    return self.todayRacingArray.count
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int     {
    return self.todayRacingArray[section].venue.count
}

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let cell =  tableView.dequeueReusableCell(withIdentifier: String(describing: HeaderTableViewCell.self)) as! HeaderTableViewCell
    let obj = todayRacingArray[section]
    cell.titleLbl.text = obj.countryCode
    return cell
  }

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell =  tableView.dequeueReusableCell(withIdentifier: String(describing: BodyTableViewCell.self)) as! BodyTableViewCell
    cell.frame = tableView.bounds
    cell.layoutIfNeeded()
    let obj = self.todayRacingArray[indexPath.section].venue[indexPath.row]
    cell.horseTitleLabel.text = obj
    return cell
}

我的输出 My table Header After Clicking on header 我想要这样的输出: enter image description here After clicking on header

请有人帮我解决这个问题。

更新答案

添加一个新模型RaceVenue。然后像下面这样修改 Racing 结构。

struct RaceVanue {
    var venue: String
    var races: [Race]?
}

struct Racing {
    var countryCode:String
    var raceVenues: [RaceVanue]
}

修改countryVenueDict字典的声明。

var countryVenueDict: [String: [RaceVanue]] = [:]

然后在添加到countryVenueDict字典时修改代码。然后在添加到 todayRacingArray

时也修改 Racing 模型
for item in response.meetings ?? []
{
    if let _ = countryVenueDict[item.countryCode ?? ""] {
        countryVenueDict[item.countryCode ?? ""]?.append(RaceVanue(venue: item.venue ?? "", races: item.races))
    } else {
        countryVenueDict[item.countryCode ?? ""] = [RaceVanue(venue: item.venue ?? "", races: item.races)]
    }
}

todayRacingArray += countryVenueDict.map { Racing(countryCode: [=12=].key, raceVenues: [=12=].value) }

上一个答案

todayRacingArray

的声明之前添加字典以将 venue 映射到 countrycode
var countryVenueDict: [String: [String]] = [:]
var todayRacingArray = [Racing]()

修改for循环中的代码如下。

for item in response.meetings ?? []
{
    if let _ = countryVenueDict[item.countryCode ?? ""] {
        countryVenueDict[item.countryCode ?? ""]?.append(item.venue ?? "")
    } else {
        countryVenueDict[item.countryCode ?? ""] = [item.venue ?? ""]
    }
}

然后通过使用 map 函数映射转换 countryVenueDict,将 [Racing] 数组附加到 todayRacingArray

todayRacingArray += countryVenueDict.map { Racing(countryCode: [=15=].key, venue: [=15=].value) }

这是完整的代码

var countryVenueDict: [String: [String]] = [:]
var todayRacingArray = [Racing]()
APIClient2<RacingListBaseClass>().API_GET(Url: url, Params: noParams, Authentication: false, Progress: false, Alert: true, Offline: false, SuperVC: self, completionSuccess: { (response) in
    for item in response.meetings ?? []
    {
        if let _ = countryVenueDict[item.countryCode ?? ""] {
            countryVenueDict[item.countryCode ?? ""]?.append(item.venue ?? "")
        } else {
            countryVenueDict[item.countryCode ?? ""] = [item.venue ?? ""]
        }
    }
    todayRacingArray += countryVenueDict.map { Racing(countryCode: [=16=].key, venue: [=16=].value) }
    self.otherSportsTableView.reloadData()
}) { (failed) in
    
}