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

Time:04-20

I want to display countrycode as header of table view and after click on header venue should display. I had tried but I'm unable to achieve output as expected.

This is my 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)"
    }
  ]
}

Here is my code which is I'm using for getting data:

    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
            
        }

TableView:

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 Output My table Header After Clicking on header I want Output like this: enter image description here After clicking on header

Please someone helpme out with this.

CodePudding user response:

Add a dictionary to map the venue with countrycode before the declaration of todayRacingArray

var countryVenueDict: [String: [String]] = [:]
var todayRacingArray = [Racing]()

Modify the code in for loop like below.

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

Then append [Racing] array to todayRacingArray by mapping the transforming the countryVenueDict by using map function.

todayRacingArray  = countryVenueDict.map { Racing(countryCode: $0.key, venue: $0.value) }

Here is the full code

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: $0.key, venue: $0.value) }
    self.otherSportsTableView.reloadData()
}) { (failed) in
    
}
  • Related