отображение тегов внутри tableviewcell из данных JSON

#ios #json #swift #uitableview #taglist

#iOS #json #swift #uitableview #список тегов

Вопрос:

Я создаю приложение, используя Swift , и я хочу показать некоторые теги внутри UITableViewCell с помощью синтаксического анализа JSON вот скриншот, который я хочу сделать в своем приложении

Вот снимок экрана, который я хочу сделать следующим образом

как вы видите на скриншоте Flat1, Flat2 — это теги, которые я хочу показать внутри UITableVieCell и для отображения тегов, которые я использовал ниже

Это TagListView, который я использовал

Вот мои данные JSON, которые поступают из веб-сервиса

 {
  "success": "1",
  "data": [
    {
      "fk_project_surveyors_id": "1",
      "number": 1,
      "created_date": "2020-04-17 10:09:57",
      "sub_cores": [
        {
          "sub_cores_title": "Flat 1"
        }
      ],
      "signature": "img_sFZuFpUd011587136197.png",
      "name": "Sean Clancy",
      "inspections_id": "4",
      "fk_user_id": "1",
      "fk_cores_id": "12",
      "survey_date": "2020-04-12"
    },
    {
      "fk_project_surveyors_id": "1",
      "number": 2,
      "created_date": "2020-04-29 12:55:45",
      "sub_cores": [
        {
          "sub_cores_title": "Flat 1"
        },
        {
          "sub_cores_title": "Flat 2"
        }
      ],
      "signature": "img_Ptw0bvSGfR1588182945.png",
      "name": "Sean Clancy",
      "inspections_id": "6",
      "fk_user_id": "1",
      "fk_cores_id": "12",
      "survey_date": "2020-04-12"
    },
    {
      "fk_project_surveyors_id": "1",
      "number": 3,
      "created_date": "2020-05-06 06:08:11",
      "sub_cores": [
        {
          "sub_cores_title": "Flat 1"
        }
      ],
      "signature": "img_FSUTzxT4221588763291.png",
      "name": "Sean Clancy",
      "inspections_id": "7",
      "fk_user_id": "1",
      "fk_cores_id": "12",
      "survey_date": "2020-04-12"
    },
    {
      "fk_project_surveyors_id": "1",
      "number": 4,
      "created_date": "2020-06-15 04:25:16",
      "sub_cores": [
        {
          "sub_cores_title": "Flat 1"
        }
      ],
      "signature": "img_EVqcz58zN11592213116.png",
      "name": "Sean Clancy",
      "inspections_id": "8",
      "fk_user_id": "1",
      "fk_cores_id": "12",
      "survey_date": "2020-04-12"
    },
    {
      "fk_project_surveyors_id": "1",
      "number": 5,
      "created_date": "2020-06-21 11:04:56",
      "sub_cores": [
        {
          "sub_cores_title": "Flat 1"
        }
      ],
      "signature": "img_3ySNyhAjYd1592755496.png",
      "name": "ron",
      "inspections_id": "10",
      "fk_user_id": "1",
      "fk_cores_id": "12",
      "survey_date": "2020-04-12"
    },
    {
      "fk_project_surveyors_id": "1",
      "number": 6,
      "created_date": "2020-06-21 11:05:44",
      "sub_cores": [
        {
          "sub_cores_title": "Flat 1"
        }
      ],
      "signature": "img_ILSykgAIW71592755544.png",
      "name": "ron2",
      "inspections_id": "11",
      "fk_user_id": "1",
      "fk_cores_id": "12",
      "survey_date": "2020-04-12"
    }
  ],
  "message": ""
}
  

как вы видите в данных JSON, каждый элемент имеет массив sub_cores, и из этого sub_cores_title я хочу показать, что внутри TagListView находится внутри UITableViewCell

Вот моя структура модели, которую я использовал для анализа выше JSON

 public struct HistoryModel{
    var fk_user_id: String?
    var signature: String?
    var fk_cores_id: String?
    var name: String?
    var inspections_id: String?
    var fk_project_surveyors_id: String?
    var created_date: String?
    var number: String?
    var survey_date: String?
    var sub_cores: [SubCoreModelData]
    
    public init(fk_user_id: String,signature: String,fk_cores_id: String,name: String,inspections_id: String,fk_project_surveyors_id: String,created_date: String,number: String,survey_date: String,sub_cores:[SubCoreModelData]) {
        self.fk_user_id = fk_user_id
        self.signature = signature
        self.fk_cores_id = fk_cores_id
        self.name = name
        self.inspections_id = inspections_id
        self.fk_project_surveyors_id = fk_project_surveyors_id
        self.created_date = created_date
        self.number = number
        self.survey_date = survey_date
        self.sub_cores = sub_cores
    }
}

public struct SubCoreModelData{
    var sub_core_title: String?
    
    public init(sub_core_title: String?) {
        self.sub_core_title = sub_core_title
    }
}
  

и вот моя функция вызова code API, из которой я сохраняю данные в массив

var historyData = HistoryModel

 func historyAPI(){
        guard let uid = UserDefaults.standard.string(forKey: "uid") else { return }
        guard let accessToken = UserDefaults.standard.string(forKey: "accToken") else { return }
        guard let projectid = UserDefaults.standard.string(forKey: "propSurID") else { return }
        
        let params = ["user_id": uid, "access_token": accessToken,"project_surveyors_id": projectid,"cores_id": self.coreid]
        print(params)
        showHud(view: self.view, message: "Please Wait")
        AF.request(previousinspectionlist, method: .post, parameters: params).responseJSON(completionHandler: {(response) in
            switch response.result{
            case.success(let value):
                let json  = JSON(value)
                print(json)
                let data = json["data"]
                if data == []{
    
                }else{
                    self.historyData.removeAll()
                    for cat in data{
                        let fk_user_id = cat.1["fk_user_id"].stringValue
                        let name = cat.1["name"].stringValue
                        let signature = cat.1["signature"].stringValue
                        let fk_cores_id = cat.1["fk_cores_id"].stringValue
                        let inspections_id = cat.1["inspections_id"].stringValue
                        let fk_project_surveyors_id = cat.1["fk_project_surveyors_id"].stringValue
                        let created_date = cat.1["created_date"].stringValue
                        let number = cat.1["number"].stringValue
                        let survey_date = cat.1["survey_date"].stringValue


                        var arrOfItems = [SubCoreModelData]()
                        for ser in cat.1["sub_cores"] {
                            let subcore = SubCoreModelData(sub_core_title: ser.1["sub_cores_title"].stringValue)
                            arrOfItems.append(subcore)
                        }
                        self.historyData.append(HistoryModel(fk_user_id: fk_user_id, signature: signature, fk_cores_id: fk_cores_id, name: name, inspections_id: inspections_id, fk_project_surveyors_id: fk_project_surveyors_id, created_date: created_date, number: number, survey_date: survey_date, sub_cores: arrOfItems, collapsed: false))
                    }
                }
                self.tblListView.reloadData()
                dismissHud()
            case.failure(let error):
                basicErrorAlertWith(title: "Error", message: error.localizedDescription, controller: self)
                dismissHud()
            }
        })
    }
  

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

TableviewDelegate и код источника данных

 func numberOfSections(in tableView: UITableView) -> Int {
    return self.historyData.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    let items = self.historyData[section].sub_cores
    return items.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as! InspectionHistoryTableViewCell
    cell.lblName.text = historyData[indexPath.row].name
    if let number = historyData[indexPath.row].number{
        print(number)
        cell.lblNumber.text = "#(number)"
    }
    cell.lblSurveydate.text = historyData[indexPath.row].survey_date
    let items = self.historyData[indexPath.section].sub_cores
    let item = items[indexPath.row]
    if let subcore = item.sub_core_title{
        cell.tagList.addTag(subcore)
    }
    cell.selectionStyle = .none
    return cell
}
  

Комментарии:

1. Не могли бы вы показать код в func cellForRowAtIndexPath ?

2. @goat_herd Пожалуйста, проверьте, что я обновил код

3. @goat_herd проверили код в cellForRoAtIndexPath? чем, пожалуйста, помогите мне

4. Извините за опоздание, но, похоже, у вас есть ответ, счастливого кодирования

5. @goat_herd Да, я получил ответ и спасибо за поддержку

Ответ №1:

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

Но то, что вам действительно нужно, — это всего лишь один раздел со historyData.count строками.

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

Итак, чтобы исправить cellForRowAt: это, вам нужно просто получить доступ к данным истории по индексу строки и clar и заполнить представление тегов всеми sub_cores.

Это должно сработать:

 func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.historyData.count
}

func tableView (_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell    = tableView.dequeueReusableCell(withIdentifier: "Cell") as! InspectionHistoryTableViewCell
    let row     = indexPath.row
    let data    = historyData[row]
    
    cell.lblName.text = data.name

    if let number = data.number{
        print(number)
        cell.lblNumber.text = "#(number)"
    }
    
    cell.lblSurveydate.text = data.survey_date
    let items = data.sub_cores
    cell.tagList.removeAllTags()
    for (item in items) {
        cell.tagList.addTag(item.sub_core_title)
    }
    
    cell.selectionStyle = .none
    return cell
}
  

Комментарии:

1. не могли бы вы сказать мне, что я должен вернуть в numberOfSections amp; numberOfRowsInSection

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

3. Хорошо, но есть еще одна проблема, когда я прокручиваю tableview, тогда он показывает мне дубликаты, есть ли у них какое-либо решение для этого?