iOS Swift:如何为TableView表头与分区填充数据并按StatusId分组
Alright, let's fix this step by step. The core issue here is that you're using the same MyArray for both sections, but we need to split your data into two groups based on StatusId first. Here's how to implement the grouping and adjust your table view code accordingly:
1. Split Your Data into Section-Specific Arrays
First, add class-level variables to hold the grouped inspections, then split the raw data once you receive it from the server:
// Add these alongside your existing variables var currentInspections: [[String: Any]] = [] var pastInspections: [[String: Any]] = [] var sectionData: [[[String: Any]]] = [] // Holds both groups for easy section access var hidden: [Bool] = [] // Keep your existing fold/unfold tracking array
Then create a function to split the data:
// Call this right after you get MyArray from the server func splitInspectionData() { guard let myArray = MyArray as? [[String: Any]] else { return } currentInspections.removeAll() pastInspections.removeAll() for inspection in myArray { guard let statusId = inspection["StatusId"] as? Int else { continue } // Group StatusId 2 & 3 into Past Inspection, others into Current if statusId == 2 || statusId == 3 { pastInspections.append(inspection) } else { currentInspections.append(inspection) } } // Map groups to sections: index 0 = Current, index 1 = Past sectionData = [currentInspections, pastInspections] scheduleInspectionTableView.reloadData() }
2. Update Table View Data Source Methods
Adjust your table view logic to use the grouped data instead of the raw MyArray:
Number of Sections
Fix the hidden array initialization to avoid re-setting it every time the method runs:
func numberOfSections(in tableView: UITableView) -> Int { // Initialize hidden array only if it doesn't match the section count if hidden.count != HeaderArray.count { hidden = Array(repeating: true, count: HeaderArray.count) } return HeaderArray.count }
Number of Rows per Section
Now return the count of the corresponding section's array instead of MyArray.count:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { if hidden[section] { return 0 } else { return sectionData[section].count } }
Header View Fixes
Your original header had two critical issues: it didn't return the view, and it was missing a tap gesture to trigger folding/unfolding. Also fix the key used to fetch the header text:
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { let headerView = UIView() headerView.backgroundColor = Colors().appColor headerView.tag = section // Add tap gesture to enable fold/unfold functionality let tapGesture = UITapGestureRecognizer(target: self, action: #selector(tapFunction(sender:))) headerView.addGestureRecognizer(tapGesture) let label = UILabel() // Use the correct key "inspection_Header" from your HeaderArray label.text = (HeaderArray[section] as AnyObject).value(forKey: "inspection_Header") as? String label.frame = CGRect(x: 10, y: 5, width: 150, height: 35) label.font = UIFont.boldSystemFont(ofSize: 15) label.textColor = .white // Ensure text is visible against the header background headerView.addSubview(label) label.tag = section return headerView // Don't forget to return the configured header view! }
Cell Configuration
Load data from the correct section array instead of the raw MyArray:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { // Dequeue cell safely (ensure you've registered the cell in storyboard/code) let cell = tableView.dequeueReusableCell(withIdentifier: "PropertyInspectionTableViewCell", for: indexPath) as! PropertyInspectionTableViewCell // Fetch the inspection for this row from the section's grouped array let inspection = sectionData[indexPath.section][indexPath.row] // Extract and use data to configure the cell if let statusId = inspection["StatusId"] as? Int { print(statusId) } // Add more cell setup here (e.g., template name, status, scheduled date) cell.templateNameLabel.text = inspection["TemplateName"] as? String cell.statusLabel.text = inspection["Status"] as? String cell.scheduledDateLabel.text = inspection["ScheduledDate"] as? String return cell }
3. Fix the Fold/Unfold Tap Handler
Update the tap function to use the correct row count for each section:
@objc func tapFunction(sender:UITapGestureRecognizer) { guard let section = sender.view?.tag else { return } let rowCount = sectionData[section].count // Generate index paths for the section's rows let indexPaths = (0..<rowCount).map { IndexPath(item: $0, section: section) } hidden[section] = !hidden[section] scheduleInspectionTableView.beginUpdates() if hidden[section] { scheduleInspectionTableView.deleteRows(at: indexPaths, with: .fade) } else { scheduleInspectionTableView.insertRows(at: indexPaths, with: .fade) } scheduleInspectionTableView.endUpdates() }
Quick Notes:
- Ensure you've registered your
PropertyInspectionTableViewCellwith the table view (either in storyboard or viatableView.register(_:forCellReuseIdentifier:)) to avoid nil cell issues. - Use optional binding (
if let) instead of force unwraps (as!) where possible to make your code more crash-resistant. - Call
splitInspectionData()immediately after receivingMyArrayfrom the server to populate the grouped data.
内容的提问来源于stack exchange,提问作者B.Saravana Kumar

