如何在嵌套Decodable模型数组中获取numberOfRowsInSection的计数
numberOfRowsInSection Hey there! Let's fix up your code to correctly get the row count from those nested Decodable arrays, and also patch a critical issue in your current implementation.
First, a quick Swift style tip: struct names should use UpperCamelCase (e.g., MyOrdersItems instead of myOrdesItems) to follow standard conventions—this makes your code way easier to read for other developers (and future you!).
The Problem with Your Current Code
Right now, every time tableView(_:numberOfRowsInSection:) gets called (and UITableView calls this a lot—on scrolls, refreshes, layout changes), you loop through myorderArray and append values to arrayOfElement. This means arrayOfElement will keep growing indefinitely, returning wrong row counts over time. We need a way to calculate the row count on-the-fly without modifying a persistent array.
Solution 1: Return Total Number of All Nested listUserOrderShipmentVM Items
If you want the second table view to show all listUserOrderShipmentVM entries from every order in myorderArray (total count across all orders), use Swift's reduce method to calculate the sum in one line:
// First, fix struct names (optional but highly recommended) struct MyOrdersItems: Decodable { let userFName: String? let userLName: String? let userOrderPreSerial: String? let userOrderSerial: Int? let userOrderProductsValue: Int? let userOrderOrderedDate: String? let payTypeDescEN: String? let listUserOrderStatus: [ListUserOrderStatus] let listUserOrderShipmentVM: [ListUserOrderShipmentVM] } struct ListUserOrderStatus: Decodable { let userOrderStatusTitleEN: String? let userOrderStatusID: Int? } struct ListUserOrderShipmentVM: Decodable { let userOrderStatusTimeLine: [UserOrderStatusTimeLine] } struct UserOrderStatusTimeLine: Decodable { let userOrderStatusID: Int? } var myorderArray: [MyOrdersItems] = [] public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { if tableView.tag == 10 { // Return count of orders for the first table view return myorderArray.count } else { // Calculate total number of shipment items across all orders return myorderArray.reduce(0) { total, order in total + order.listUserOrderShipmentVM.count } } }
Solution 2: One Section Per Order, Rows = Shipment Items in That Order
If you want the second table view to have one section per order, with rows equal to the number of listUserOrderShipmentVM items in that specific order, you'll also need to implement numberOfSections(in:):
public func numberOfSections(in tableView: UITableView) -> Int { if tableView.tag == 10 { return 1 // Single section for the order list table view } else { return myorderArray.count // One section per order } } public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { if tableView.tag == 10 { return myorderArray.count } else { // Guard against out-of-bounds index errors guard section < myorderArray.count else { return 0 } // Return shipment count for the order at this section return myorderArray[section].listUserOrderShipmentVM.count } }
Key Takeaways
- Never modify persistent arrays inside
numberOfRowsInSection—UITableView calls this method frequently, so side effects will cause hard-to-track bugs. - Use
reduceto quickly sum nested array counts, or map sections directly to your top-level array elements for per-order row counts. - Following Swift naming conventions will keep your code clean and maintainable.
内容的提问来源于stack exchange,提问作者mohamed gamal

