Swift: Как настроить табличное представление с несколькими разделами динамически, используя данные JSON - PullRequest
0 голосов
/ 06 февраля 2019

Я пытаюсь заполнить динамический UITableView несколькими разделами, используя данные JSON, полученные из конечной точки на сервере.

В табличном представлении должен отображаться список проектов пользователя, организованных командой, с помощьюдо 5 последних проектов от любой команды наверху.

Однако у меня возникают проблемы с заполнением команд (секций) их проектами из-за сложного возвращения JSON.Я знаю, что должен сравнить идентификатор команды проекта с идентификатором команды, чтобы определить, принадлежит ли этот проект этой команде.Но я застрял на следующем шаге: как я могу сохранить все проекты, принадлежащие команде, а затем проиндексировать эту структуру данных, чтобы отобразить имя команды для заголовка раздела, а затем проекты для данной команды.

То, что я пытался сделать до сих пор:

  1. Цикл каждого проекта, выбранного из конечной точки.
  2. Проверьте, соответствует ли идентификатор команды текущего проекта текущей командеID команды.
  3. Если они совпадают, добавьте этот проект в эту команду

    // Loop through each project
    for project in projects {
        // If the current project belongs to the current team
        if project.relationships.team.id == teams[section - 1].id {
            // Add the project to that team
    
        }
    
    }
    

Последний раздел (первый раздел вверху) зарезервирован длясписок ячеек табличного представления, которые включают заголовок (название проекта) и подзаголовок (команда, в которой содержится проект).

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

Ниже приведен пример ответа JSON конечной точки.

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

included - это массив команд.data - это массив проектов.

{
  "included": [
    {
      "type": "teams",
      "id": "1",
      "attributes": {
        "name": "Team1"
      }
    },
    {
      "type": "teams",
      "id": "2",
      "attributes": {
        "name": "Team2"
      }
    },
    {
      "type": "teams",
      "id": "3",
      "attributes": {
        "name": "Team3"
      }
    }
  ],
  "data": [
    {
      "type": "projects",
      "id": "1",
      "relationships": {
        "team": {
          "id": "1",
          "type": "teams"
        }
      },
      "attributes": {
        "name": "House of Cards",
      }
    },
    {
      "type": "projects",
      "id": "2",
      "relationships": {
        "team": {
          "id": "1",
          "type": "teams"
        }
      },
      "attributes": {
        "name": "Arrested Development",
      }
    },
    {
      "type": "projects",
      "id": "3",
      "relationships": {
        "team": {
          "id": "1",
          "type": "teams"
        }
      },
      "attributes": {
        "name": "Orange Is The New Black",
      }
    },
    ...
  ]
}

Я создал модель (и связанные с ней модели) на основе JSON:

struct JSON: Codable {
    let included: [Included]
    let data: [Datum]
}

Вот соответствующие фрагменты моего кода:

// This should belong in the fetchData() function to be called in viewDidLoad but I believe I need access to the `section`

    var arrProjects = [Datum]()
    // Loop through each project
    for project in projects {
        // If the current project belongs to the current team
        if project.relationships.team.id == teams[section - 1].id {
            // Add the project to that team
            arrProjects.append(project)

//                let teamName = teams[section - 1].attributes.name
//                projectsByTeam.append([teamName: arrProjects])
            //projectsByTeam[section-1] = [teamName: arrProjects]

            let teamName = teams[section - 1].attributes.name
            let team = [teamName: arrProjects]
            projectsByTeam.append(team)
        }

    }


let decoder = JSONDecoder()
self?.json = try decoder.decode(JSON.self, from: data)

guard let json = self?.json else { return }

self?.teams = json.included
self?.projects = json.data

DispatchQueue.main.async { [weak self] in
    self?.tableView.reloadData()
}

...

func numberOfSections(in tableView: UITableView) -> Int {

    if let numberOfTeams = teams?.count {
        return 1 + numberOfTeams
    }

    return 1

}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    guard let projects = projects else { return 0 }
    guard let teams = teams else { return 0 }

    let numberOfProjects = projects.count

    if section == 0 {
        // Recent section
        if numberOfProjects <= 5 {
            return 0
        } else if numberOfProjects > 5 && numberOfProjects < 10 {
            return numberOfProjects - 5
        } else if numberOfProjects >= 10 {
            return 5
        }
    }

    // *NEED TO FIND THE NUMBER OF PROJECTS FOR EACH REMAINING SECTION (WHICH IS A TEAM)*
    // How to index the data structure that holds the projects for each team?

    return 0

}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    guard let project = projects?[indexPath.row] else { return UITableViewCell() }

    if indexPath.section == 0 {
        let cell = tableView.dequeueReusableCell(withIdentifier: Constants.RecentCellReuseIdentifier, for: indexPath) as! RecentTableViewCell
        cell.textLabel?.text = project.attributes.name
        cell.detailTextLabel?.text = project.relationships.team.id

        return cell
    }

    let cell = tableView.dequeueReusableCell(withIdentifier: Constants.ProjectCellReuseIdentifier, for: indexPath) as! ProjectTableViewCell
    // How to index the data structure that holds the projects for each team?
    //cell.textLabel?.text = projectsByTeam?[indexPath.section][indexPath.row]

    return cell
}

Вот как примерно должна выглядеть структура представления таблицы:

Раздел 0 - Недавние

  • ProjectA (Team 1)
  • ProjectD (команда 2)
  • ProjectE (команда 3)

Раздел 1 - Команда 1

  • ProjectA
  • ProjectB

Раздел 2 - Команда 2

  • ProjectC
  • ProjectD

Раздел 3 - Команда 3

  • ProjectE
  • ProjectF

1 Ответ

0 голосов
/ 06 февраля 2019

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

var teams = [[String: [Datum]]]()
for team in teams {
let teamProjects = projects.filter {$0.relationships.team.id == team.id}
let teamData = [team: [teamProjects]]
teams.append(teamData)
}

и в методе numberOfRows:

 let team = teamsWithProjects[section-1]
 let teamProject = Array(team.values)[0]
 return teamProject.count

и в методе cellForRow:

  let team = teamsWithProjects[indexPath.section-1]
  let teamProject = Array(team.values)[0]
  projectCell.textLabel?.text = teamProject[indexPath.row].attributes.name

Hopeэто поможет вам!

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