如何将 JSON 获取到 Swift 到 tableView 作为节和行?

问题描述 投票:0回答:2

我想问如何实现文件作为部分取决于

userId
然后在表格视图中再次显示全部。

我开始构建简单的项目,我获取 JSON 文件作为解码器并在表视图中显示所有内容:

func fetchUsers(using url: String){
    let url = URL(string: url)!
    let _ = URLSession.shared.dataTask(with: url){ (data,response,error)
        in
        guard let data = data else {return}
        do{
            let objects = try JSONDecoder().decode([User].self, from: data)  // decode * ( Codable )
            self.users = objects
        } catch{
            print("error loading data cause: \(error)")
            }
        }.resume()
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if let cell = tableView.dequeueReusableCell(withIdentifier: "users",for: indexPath) as? customeCellTableViewCell{
        let indexRow = users[indexPath.row]
        cell.dataModel(forModel: indexRow)
     return cell
    }
    return UITableViewCell()
}

private func numberOfUsers(in users: [User]) -> Int {
         
            return 1
        }
    
        func numberOfSections(in tableView: UITableView) -> Int {

            return numberOfUsers(in: self.users)
            
        }
ios json swift tableview
2个回答
2
投票

就像 @vadian 提到的那样,应该避免使用元组,所以这里有一个改进的解决方案。

我们可以使用结构体来代替元组来保存分组数据

struct UsersByID {
    let id: Int
    var users : [User]
}

然后将

load
函数更改为

func load(withUsers users: [User]) {
    let dict = Dictionary(grouping: users) { return $0.userID }
    usersByID = dict.map { (key, values) in
        return UsersByID(id: key, users: values)
    }.sorted(by: { $0.id < $1.id })
}

其余代码相同,但将

key
替换为
id
,将
value
替换为
users


旧解决方案

首先创建一个字典来保存部分(键)和行(值)作为视图控制器中的属性

var usersByID = [(key: Int, value: [User])]()

然后使用 json

 中的数组使用 
grouping:by:

填充该字典
func load(withUsers users: [User]) {
    usersByID = Dictionary(grouping: users, by: { user in
        user.userID }).sorted(by: { $0.0 < $1.0})
}

然后表视图函数使用这个字典


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

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return usersByID[section].value.count
}

override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return String(usersByID[section].key)
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "LabelCell", for: indexPath)

    let user = usersByID[indexPath.section].value[indexPath.row]
    cell.textLabel?.text = user.title
    //...

    return cell
}

0
投票
    func numberOfSections(in collectionView: UICollectionView) -> Int {
            return datesArr.count
        }

        func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

            if (contractsDict.keys.contains(datesArr[section])) {
                return contractsDict[datesArr[section]]!.count
            }

            return 0
        }

        func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! ContractsCollectionViewCell

            DispatchQueue.main.async {
                if (self.contractsDict.keys.contains(self.datesArr[indexPath.section])) {
                    for _ in 0..<(self.contractsDict[self.datesArr[indexPath.section]]!.count) {
                        cell.contract = self.contractsDict[self.datesArr[indexPath.section]]![indexPath.row]
                        cell.delegate = self
                    }
                }
            }

            return cell
        }
    }
}

    ContractServices.shared.fetchAllContracts(completion: { (contracts, err) in
                    DispatchQueue.main.async {
                        if (err != nil) {
                            print(err!, "1323")
                            return
                        }

                        for contract in (contracts?.data)! {
                            self.allContractsArr.append(contract)
                            if let callDate = contract.revdat {
                                let formatterGet = DateFormatter()
                                formatterGet.dateFormat = "yyyy-MM-dd HH:mm:ss"
                                let newFormat = DateFormatter()
                                newFormat.dateFormat = "dd MMM yyyy"

                                if let date = formatterGet.date(from: callDate) {
                                    self.datesArr.append(newFormat.string(from: date))
                                }
                            }
                        }

                        for i in 0..<self.allContractsArr.count {
                            if let callDate = self.allContractsArr[i].revdat {
                                let formatterGet = DateFormatter()
                                formatterGet.dateFormat = "yyyy-MM-dd HH:mm:ss"
                                let newFormat = DateFormatter()
                                newFormat.dateFormat = "dd MMM yyyy"

                                if let date = formatterGet.date(from: callDate) {
                                    self.allContractsArr[i].revdat = newFormat.string(from: date)
                                }
                            }
                        }

                        self.allContractsArr = self.allContractsArr.sorted(by: { ($0.revdat)! > ($1.revdat)! })
                        self.contractsDict = Dictionary(grouping: self.allContractsArr, by: { ($0.revdat)! })
                        let newFormat = DateFormatter()
                        newFormat.dateFormat = "dd MMM yyyy"
                        self.datesArr = Array(Set(self.datesArr))
                        self.datesArr = self.datesArr.sorted(by: { newFormat.date(from: $0)! > newFormat.date(from: $1)! })

                        self.contractListCV.reloadData()

                        DispatchQueue.main.async {
                            self.activityBackView.isHidden = true
                            self.activity.isHidden = true
                            self.activity.stopAnimating()
                            self.design()
                        }

                    }
                })

我就是这么做的。 获取数组格式的数据,通过 grouping(by:) 方法将其转换为字典,然后对这些字典数据进行与 CollectionView 相关的所有操作。

© www.soinside.com 2019 - 2024. All rights reserved.