问题
I have two arrays Data1 and Data2 and I want to populate the data within each of these (they contain strings) into a tableview in two different sections. The first section should have a heading "Some Data 1" and the second section should be titled "KickAss".
I have both sections populating with data from the first array (but with no headings either).
Here is my code so far:
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 2
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
var rowCount = 0
if section == 0 {
rowCount = Data1.count
}
if section == 1 {
rowCount = Data2.count
}
return rowCount
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
let ip = indexPath
cell.textLabel?.text = Data1[ip.row] as String
return cell
}
in the cellForRowAtIndexPath method, is it possible for me to identify the section somehow like I did in the numberOfRowsInSection method? Also, how do I give titles to each section? Thanks
回答1:
TableView Cells
You could use a multidimensional array. For example:
let data = [["0,0", "0,1", "0,2"], ["1,0", "1,1", "1,2"]]
For the number of sections use:
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return data.count
}
Then, to specify the number of rows in each section use:
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data[section].count
}
Finally, you need to setup your cells:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellText = data[indexPath.section][indexPath.row]
// Now do whatever you were going to do with the title.
}
TableView Headers
You could again use an array, but with just one dimension this time:
let headerTitles = ["Some Data 1", "KickAss"]
Now to set the titles for the sections:
override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if section < headerTitles.count {
return headerTitles[section]
}
return nil
}
The code above checks to see there's a title for that section and returns it, otherwise nil
is returned. There won't be a title if the number of titles in headerTitles
is smaller than the number of arrays in data
.
The Result

回答2:
You could create a Struct
to hold the data that belongs to a section, as an alternative to my previous answer. For example:
struct SectionData {
let title: String
let data : [String]
var numberOfItems: Int {
return data.count
}
subscript(index: Int) -> String {
return data[index]
}
}
extension SectionData {
// Putting a new init method here means we can
// keep the original, memberwise initaliser.
init(title: String, data: String...) {
self.title = title
self.data = data
}
}
Now in your view controller you could setup your section data like so:
lazy var mySections: [SectionData] = {
let section1 = SectionData(title: "Some Data 1", data: "0, 1", "0, 2", "0, 3")
let section2 = SectionData(title: "KickAss", data: "1, 0", "1, 1", "1, 2")
return [section1, section2]
}()
Section Headers
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return mySections.count
}
override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return mySections[section].title
}
Compared to my previous answer, you now don't have to worry about matching the number of headerTitles
to the number of arrays in data
.
TableView Cells
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return mySections[section].numberOfItems
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellTitle = mySections[indexPath.section][indexPath.row]
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! UITableViewCell
cell.textLabel?.text = cellTitle
return cell
}
回答3:
You can determine which section you are in by looking at indexPath.section
.
To specify the titles, override the function
func tableView(tableView: UITableView!, titleForHeaderInSection section: Int) -> String!
回答4:
In swit 4 or swift 5, You can use like.Here Custom header section wit filter is shown Image is look like bellow
- create a project
- Add table view
- create UITableView Cell
- Connect label to uitable view & table with view controller
Add bellow code
import UIKit struct Category { let name : String var items : [[String:Any]] } class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource,UITextFieldDelegate { @IBOutlet weak var txtName: UITextField! @IBOutlet weak var tableView: UITableView! var originalArr = [[String:Any]](); var recentArr = [[String:Any]](); var searchArrRes = [[String:Any]]() var searching:Bool = false // var sections = [Category]() override func viewDidLoad() { super.viewDidLoad() //Assign delegate don't forget txtName.delegate = self tableView.delegate = self tableView.dataSource = self recentArr = [ ["name": "Enamul", "number": "+8800000003"], ["name": "Enam", "number": "+8800000004"] ] originalArr = [ ["name": "abdul", "number": "+8800000001"], ["name": "abdin", "number": "+8800000002"], ["name": "Enamul", "number": "+8800000003"], ["name": "enam", "number": "+8800000004"], ["name": "Rafi", "number": "+8800000005"], ["name": "Ehaque", "number": "+8800000006"] ] //my array sections = [ Category(name:"Recent", items:recentArr), Category(name:"ALL", items:originalArr) ] } func textFieldShouldReturn(_ textField: UITextField) -> Bool { textField.resignFirstResponder() return true } func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) { guard let tableView = view as? UITableViewHeaderFooterView else { return } tableView.textLabel?.textColor = UIColor.red } public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool{ //input text let searchText = textField.text! + string searchArrRes = self.originalArr.filter({(($0["name"] as! String).localizedCaseInsensitiveContains(searchText))}) if(searchArrRes.count == 0){ searching = false }else{ searching = true } self.tableView.reloadData(); return true } func numberOfSections(in tableView: UITableView) -> Int { if( searching == true){ return 1 } return self.sections.count } func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { if( searching == true){ return "" } return self.sections[section].name } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { if( searching == true){ return searchArrRes.count }else{ let items = self.sections[section].items return items.count } } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! Custom_cell // var dict = itemsA[indexPath.section] if( searching == true){ var dict = searchArrRes[indexPath.row] cell.name.text = dict["name"] as? String cell.number.text = dict["number"] as? String }else{ let items = self.sections[indexPath.section].items let item = items[indexPath.row] cell.name.text = item["name"] as? String cell.number.text = item["number"] as? String } return cell } }
You can download full source from GitHub.GitHub Like: https://github.com/enamul95/Custom_table_view_section.git
来源:https://stackoverflow.com/questions/29578965/how-do-i-populate-two-sections-in-a-tableview-with-two-different-arrays-using-sw