我想问如何实现文件作为部分取决于
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)
}
就像 @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
}
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 相关的所有操作。