如何在uitableview的cellForRowAt函数中按标题日期对响应进行排序
Posted
技术标签:
【中文标题】如何在uitableview的cellForRowAt函数中按标题日期对响应进行排序【英文标题】:How to sort response by header date in cellForRowAt function in uitableview 【发布时间】:2018-07-26 13:12:46 【问题描述】:我目前有一个来自json 的 json 响应,它是一个 [NSDictionary]。这显示在表格视图中,我能够将排序的日期设置为标题,但是在 cellForRowAt 函数中设置 uilabel 时遇到了困难。我要显示的表格视图有一个已排序日期的标题标题(我已经有),并且在该部分下是与标题具有相同日期的名称。我在下面提供了代码。感谢您的帮助和建议。
import UIKit
import Alamofire
class JSONTableViewController: UITableViewController
var responseValue:[NSDictionary] = []
var sortedResponsevalue:[NSDictionary] = []
var sectionHeaderArray:[String] = []
var rowTitle:[String] = []
override func viewDidLoad()
super.viewDidLoad()
override func viewWillAppear(_ animated: Bool)
super.viewWillAppear(animated)
for response in self.responseValue
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
let responseDate = response.object(forKey: "date") as! String
let date = dateFormatter.date(from: responseDate)
print(date!.toString(dateFormat: "MMM d, yyyy"))
self.sectionHeaderArray.append(date!.toString(dateFormat: "MMM d, yyyy"))
self.rowTitle.append(response.object(forKey: "name") as! String)
print(self.sectionHeaderArray.count)
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?
return self.sectionHeaderArray[section]
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int
// #warning Incomplete implementation, return the number of sections
return self.sectionHeaderArray.count
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return self.sectionHeaderArray[section].count
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
return 80
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "jsonCell", for: indexPath) as! JSONTableViewCell
if let nameString = self.responseValue[indexPath.row].object(forKey: "name") as? String
cell.jsonLabel.text = nameString
return cell
【问题讨论】:
【参考方案1】:我从您的问题中了解到:您在 cellForRow 方法中获得了“nameString”的相同标题。
问题是
if let nameString = self.responseValue[indexPath.row].object(forKey: "name") as? String
cell.jsonLabel.text = nameString
您传递的部分数量 self.sectionHeaderArray.count。因为总部分 = 100,并且每个部分只有 1 行,所以标题将始终保持不变。
试试这个:使用 indexPath.section 而不是 indexPath.row 来获得不同的标题
if let nameString = self.responseValue[indexPath.section].object(forKey: "name") as? String
cell.jsonLabel.text = nameString
编辑
class JSONTableViewController: UITableViewController
var responseValue:[NSDictionary] = []
var sortedResponsevalue:[NSDictionary] = []
var sectionHeaderArray = [[String: Any]]()
override func viewDidLoad()
super.viewDidLoad()
override func viewWillAppear(_ animated: Bool)
super.viewWillAppear(animated)
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
var currentDate: String? = nil
var nameArray = [String]()
for (index,response) in self.responseValue.enumerated()
let responseDate = response.object(forKey: "date") as! String
let date = dateFormatter.date(from: responseDate)
let dateString = date!.toString(dateFormat: "MMM d, yyyy")
let nameString = response.object(forKey: "name") as! String
if currentDate == nil
// FIRST TIME
currentDate = dateString
nameArray.append(nameString)
else
// CHECK IF DATES EQUAL, THEN KEEP ADDING
if currentDate == dateString
nameArray.append(nameString)
if index == self.responseValue.count - 1
let dictToAppend: [String : Any] = ["date": currentDate!, "names": nameArray]
self.sectionHeaderArray.append(dictToAppend)
else
let dictToAppend: [String : Any] = ["date": currentDate!, "names": nameArray]
self.sectionHeaderArray.append(dictToAppend)
currentDate = dateString
nameArray.removeAll()
nameArray.append(nameString)
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?
let dictInfo = self.sectionHeaderArray[section]
let dateString = dictInfo["date"]
return dateString as? String
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int
// #warning Incomplete implementation, return the number of sections
return self.sectionHeaderArray.count
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
let dictInfo = self.sectionHeaderArray[section]
let namesArray = dictInfo["names"] as! [String]
return namesArray.count
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
return 80
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "jsonCell", for: indexPath) as! JSONTableViewCell
let dictInfo = self.sectionHeaderArray[indexPath.section]
let namesArray = dictInfo["names"] as! [String]
let nameString = namesArray[indexPath.row]
cell.jsonLabel.text = nameString
return cell
尝试并分享结果。
【讨论】:
我会试试这个。我不确定如何定义override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int return self.sectionHeaderArray[section].count
的返回值
if let nameString = self.responseValue[indexPath.section].object(forKey: "name") as? String cell.jsonLabel.text = nameString
已经为 cellForRowAt 设置了正确的值,但是现在的问题是每个结果的正确行数。感谢您的帮助
numberOfRowsInSection 应该返回 1,因为日期和名称是一对一的映射。
有没有办法根据 json 响应使其动态化?我有 2 件商品,日期为 2018 年 6 月 20 日、2018 年 4 月 26 日、2018 年 4 月 16 日、2018 年 2 月 23 日等。是否可以在同一部分中返回具有相同日期的名称数量?谢谢
你真的救了我。这做得恰到好处。我不能感谢你足够的 Bhavin。感谢您的耐心等待。【参考方案2】:
这是一种不同的方法,使用 Decodable
协议将 JSON 解码为结构,并使用优化的初始化程序 Dictionary(grouping:by:)
按日期对项目进行分组。
创建一个结构体(可以在视图控制器之外)
struct Response : Decodable
let id : Int
let date : Date
let name : String
在视图控制器内部为标题标题创建一个日期格式化程序
let dateFormatter : DateFormatter =
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "MMM d, yyyy"
return formatter
()
和一个 native 字典(从不NSDictionary
)用于数据源和一个数组用于Date
实例的部分。使用Date
的好处是可以排序(字符串日期格式无法正确排序)
var sections = [Date]()
var dataSource = [Date:[Response]]()
假设data
是viewDidLoad
中的JSON 数据,将data
解码到结构中并填充数据源。 Dictionary(grouping:by:)
方法将Response
的数组分组到一个字典中,以日期为键。
override func viewDidLoad()
super.viewDidLoad()
// put here the code to retrieve the JSON data in the variable `data`
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(dateFormatter)
do
let result = try decoder.decode([Response].self, from: data)
dataSource = Dictionary(grouping: result, by: $0.date)
sections = dataSource.keys.sorted()
self.tableView.reloadData()
catch
print(error)
数据源和委托方法是
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?
return dateFormatter.string(from: sections[section])
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int
// #warning Incomplete implementation, return the number of sections
return sections.count
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
let sectionDate = sections[section]
return dataSource[sectionDate]!.count
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
return 80
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "jsonCell", for: indexPath) as! JSONTableViewCell
let sectionDate = sections[indexPath.section]
let item = dataSource[sectionDate]![indexPath.row]
cell.jsonLabel.text = item.name
return cell
【讨论】:
你能帮我解决这个问题吗@vadian only using nsurlsession ***.com/questions/62084188/… @DilipTiwari 抱歉,*** 不是代码编写服务,如何解析 JSON 是 SO 上最常见的问题之一。请搜索。 您遇到了什么问题?您几乎可以按字面意思使用答案。 没有解码我该怎么办以上是关于如何在uitableview的cellForRowAt函数中按标题日期对响应进行排序的主要内容,如果未能解决你的问题,请参考以下文章
在 tableviewcell 中使用 UITableview 执行 segue