对象数组中的 UITableView 部分
Posted
技术标签:
【中文标题】对象数组中的 UITableView 部分【英文标题】:UITableViewSections from Array of Objects 【发布时间】:2021-01-11 17:55:23 【问题描述】:我正在努力实现以下目标。我正在将一个 xml 字符串映射到一个 tableview 中。这部分工作正常,但是我也想在 tableview 中制作部分。我需要 LINENAME 作为 SectionName 并且 NODENAMES 应该在这些部分的下面作为行。下面是它的外观示例。
标题 (LINE1)
单元格 (NODE1) 单元格 (NODE2)标题 (LINE2)
单元(节点 1)等等……
有人能给我更多关于如何实现这一目标的信息吗?
提前致谢。
var LineRows: [LineRow] = []
override func viewDidLoad()
super.viewDidLoad()
let xmlString = """
<?xml version="1.0" encoding="utf-8"?>
<RESULT>
<ROWSET>
<ROW>
<LINENAME>LINE1</LINENAME>
<NODENAME>NODE1</NODENAME>
<LINEID>1</LINEID>
</ROW>
<ROW>
<LINENAME>LINE1</LINENAME>
<NODENAME>NODE2</NODENAME>
<LINEID>1</LINEID>
</ROW>
<ROW>
<LINENAME>LINE2</LINENAME>
<NODENAME>NODE1</NODENAME>
<LINEID>2</LINEID>
</ROW>
</ROWSET>
</RESULT>
"""
let data = Data(xmlString.utf8) // Data for deserialization (from XML to object)
do
let xml = try XMLSerialization.xmlObject(with: data, options: [.default, .cdataAsString])
let food = XMLMapper<LineResult>().map(XMLObject: xml)
print(food?.Linerowset?.Linerows?.first?.Linename ?? "nil")
self.LineRows = food!.Linerowset?.Linerows ?? []
self.tableView.reloadData()
// debugPrint(LineRows)
catch
print(error)
将 XML 字符串映射到对象数组
// MAP NODE DETAILS //
class LineResult: XMLMappable
var nodeName: String!
var error: String?
var Linerowset: LineRowset?
required init?(map: XMLMap)
func mapping(map: XMLMap)
error <- map.attributes["error"]
Linerowset <- map["ROWSET"]
class LineRowset: XMLMappable
var nodeName: String!
var Linerows: [LineRow]?
required init?(map: XMLMap)
func mapping(map: XMLMap)
Linerows <- map["ROW"]
class LineRow: XMLMappable
var nodeName: String!
var Linename: String?
var Nodename: String?
var LineLineID: String?
required init?(map: XMLMap)
func mapping(map: XMLMap)
Linename <- map["LINENAME"]
Nodename <- map["NODENAME"]
LineLineID <- map["LINEID"]
表格视图:
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
//return LineRows.count
return LineRows.count
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let Cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let person = LineRows[indexPath.row]
Cell.textLabel?.text = person.Nodename
return Cell
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
guard
let indexPath = tableView.indexPathForSelectedRow,
let vc = segue.destination as? LineDetails
else
return
let person = LineRows[indexPath.row]
vc.lineID = person.LineLineID!
调试打印(LineRows)响应:
[ApiApp.LineController.LineRow, ApiApp.LineController.LineRow, ApiApp.LineController.LineRow]
转储(LineRows)响应:
LINE1
▿ 3 elements
▿ ApiApp.LineController.LineRow #0
▿ nodeName: Optional("ROW")
- some: "ROW"
▿ Linename: Optional("LINE1")
- some: "LINE1"
▿ Nodename: Optional("NODE1")
- some: "NODE1"
▿ LineLineID: Optional("1")
- some: "1"
▿ ApiApp.LineController.LineRow #1
▿ nodeName: Optional("ROW")
- some: "ROW"
▿ Linename: Optional("LINE1")
- some: "LINE1"
▿ Nodename: Optional("NODE2")
- some: "NODE2"
▿ LineLineID: Optional("1")
- some: "1"
▿ ApiApp.LineController.LineRow #2
▿ nodeName: Optional("ROW")
- some: "ROW"
▿ Linename: Optional("LINE2")
- some: "LINE2"
▿ Nodename: Optional("NODE1")
- some: "NODE1"
▿ LineLineID: Optional("2")
- some: "2"
【问题讨论】:
不相关,但不要以大写开头命名您的 var。let Cell =
=> let cell =
,结构/类的属性相同。
能否取消注释 debugPrint(LineRows)
并将输出(即您的数据源结构)添加到问题中?
@LucaSfragara 我添加了来自 Debugprint(LineRows) 和 Dump(LineRows) 的响应。提前致谢!
LineRows
的每个元素都需要一个部分,对吗?
我会重新组合这些行。我会使用struct LineSection let lineId: String?; let lineName: String?; let nodes: [LineRow]
而不是将当前模型直接放入 tableView VC 中,如果您以后有 var sections: [LineSection];
:NumberOfSection:sections.count
,NumberOfRowsInSection:sections[section].nodes.count
,IndexPath 处的元素,那会更容易: let person = sections[indexPath.section].nodes[indexPath.row]
【参考方案1】:
我会制作一个更适合您的表格视图的 ViewModel。
struct LineSections
let lineId: String?
let lineName: String?
let nodes: [LineRow]
我猜你在某处有var LineRows: [LineRows] = []
,作为你的 ViewController 的一个属性。我会用var lineSections: [LineSections] = []
更改它。
那么,
self.LineRows = food!.Linerowset?.Linerows ?? []
let rows = food?.Linerowset?.Linerows ?? []
self.lineSections = Dictionary(grouping: rows, by: $0.lineId ).values.compactMap LineSections(lineId: $0.first?.lineId, lineName: $0.first?.lineName, nodes: $0) .sorted(by: $0.lineId ?? "" < $1.lineId ?? ""
在您的表格视图中填充:
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return lineSections[section].node.count
override func numberOfSections(in tableView: UITableView) -> Int
return lineSections.count
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let person = lineSections[indexPath.section].node[indexPath.row]
cell.textLabel?.text = person.Nodename
return cell
不相关:以小写开头命名您的 var:let Cell
=> let cell
等。
【讨论】:
感谢您构建示例。显然,这段代码给了我一个错误,它在下一行的范围内找不到“Sections”:self.lineSections = Dictionary(grouping: rows. 应该修复,在我的 Playground 中,我将其命名为Sections
而不是 LineSections
。
你能放一份你的游乐场吗?它一直给我一些非常奇怪的错误
非常感谢!现在一切正常!以上是关于对象数组中的 UITableView 部分的主要内容,如果未能解决你的问题,请参考以下文章
如何根据 Core Data 中的关系对象创建 UITableView 部分
如何从属于 UITableView 中的模型数组对象的数组中向 tableView 显示数据?
如何在 UITableView 中显示数组中的 x 个对象,然后在向下滚动时显示更多?