I have multiple sections in a UITableView. I am using the IndexPath of the cells to set some values. What I am asking is if at the start of a new section, the counting of the IndexPaths restarts to zero. Any help is greatly appreciated. Thanks!
it does. If you implement the basic example below, you'll see how the row index restarts from 0 in each section
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet var myTableView: UITableView!
let myDataSource = ["Andrew", "Anthony", "Bill", "Brad", "Charlie", "Craig"]
override func viewDidLoad() {
super.viewDidLoad()
myTableView.delegate = self
myTableView.dataSource = self
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath) as! MyTableViewCell
cell.myCellLabel.text = myDataSource[indexPath.row + indexPath.section*2] + " [Row = \(indexPath.row), Section = \(indexPath.section)]"
return cell
}
func numberOfSections(in tableView: UITableView) -> Int {
return 3
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 2
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
var title = ""
switch section {
case 0:
title = "A"
case 1:
title = "B"
case 2:
title = "C"
default:
break
}
return title
}
}
Related
I want to create 3 headers in the tableview given in the images and 8 students in each row, my code is as follows
Screenshot of the example
class ViewController: UIViewController {
var schoolOfList: [Any] = [
[["school": ["VIP", "Bright International", "Motherland"]],
[["student1": ["Chirag", "Akshay", "Shailesh", "Vishal", "Mehul", "Vinod", "Mukesh", "Darshan"]],
["student2": ["Manjari", "Kairav", "Abhimanyu", "Akshara", "Arohi", "Neel", "Naksh", "Naman"]],
["student3": ["Paritosh", "Anuj", "Kavya", "Samar", "Vanraj", "Kinjal", "Anupama", "Riyan"]]]]]
#IBOutlet weak var mytableview : UITableView!
override func viewDidLoad() {
super.viewDidLoad()
}
}
extension ViewController:UITableViewDelegate,UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> (Int) {
return schoolOfList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for:indexPath)
cell.textLabel?.text = schoolOfList["school"] as! [String]indexPath.row
return cell
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 50
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerview = UIView(frame: CGRect(x:0,y:0,width:self.mytableview.frame.width,height:50))
headerview.backgroundColor = .green
let lable = UILabel(frame: CGRect(x:0,y:0,width:self.mytableview.frame.width,height:50))
lable.textAlignment = .center
lable.text = (schoolOfList["school"]as!String)
headerview.addSubview(lable)
return headerview
}
I'm getting this error message in my table view controller class
value of uitableviewcell has no member delegate
Here is an image of the error.
Is there anything that should be changed in my code?
import UIKit
class TViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
#IBOutlet weak var Tviews: UITableViewCell!
let contacts:[[String]] = [
["Elon Musk", "+1-201-3141-5926"],
["Bill Gates", "+1-202-5358-9793"],
["Tim Cook", "+1-203-2384-6264"],
["Richard Branson", "+1-204-3383-2795"],
["Jeff Bezos", "+1-205-0288-4197"],
["Warren Buffet", "+1-206-1693-9937"],
["The Zuck", "+1-207-5105-8209"],
["Carlos Slim", "+1-208-7494-4592"],
]
override func viewDidLoad() {
super.viewDidLoad()
Tviews.delegate = self
Tviews.datasource = self
// Do any additional setup after loading the view.
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return contacts.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "tableViews", for: indexPath)
print("\(#function) --- section = \(indexPath.section), row = \(indexPath.row)")
cell.textLabel?.text = contacts[indexPath.row][0]
return cell
}
You should assign your delegate and data source to your table view instance, and not your table view cell.
In order to do that, create an outlet link with your table view in the TViewController file and then edit your code like this:
import UIKit
class TViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
let contacts:[[String]] = [
["Elon Musk", "+1-201-3141-5926"],
["Bill Gates", "+1-202-5358-9793"],
["Tim Cook", "+1-203-2384-6264"],
["Richard Branson", "+1-204-3383-2795"],
["Jeff Bezos", "+1-205-0288-4197"],
["Warren Buffet", "+1-206-1693-9937"],
["The Zuck", "+1-207-5105-8209"],
["Carlos Slim", "+1-208-7494-4592"],
]
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.datasource = self
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return contacts.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "<your-table-view-cell-id>", for: indexPath) as! YourTableViewCell
cell.textLabel?.text = contacts[indexPath.row][0]
return cell
}
}
I am trying to get my tableView to show content in its cells, but it doesn't and I don't know why.
Here is the code. I also have connected the table view to the viewcontroller through dataSource and delegate in the storyboard, so that's why there are not typed in the viewDidLoad() method.
class ViewController: UIViewController, MKMapViewDelegate, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
wordsArray = [Words(sectionName: "Example section", usedWords: ["aaaaa", "aaaaa", "aaaaa"])]
tableView.alpha = 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return favCapitals.count
}
struct Words {
var sectionName: String! = ""
var usedWords: [String]! = []
}
var wordsArray: [Words] = []
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as UITableViewCell
cell.textLabel?.text = wordsArray[indexPath.section].usedWords[indexPath.row]
cell.textLabel?.textColor = .black
return cell
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
let sectionName = "Favourite Capitals"
return sectionName
}
You will need to call the following methods before it listens to cellForRowAt:
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
another common problem is that the frame of the table is not set (e.g. inside a UITableViewCell, with automatic dimensions). The table requires a frame before it gets cells.
You can use tableView.reloadData() in the viewDidLoad Method.
I have a table view with different sections and for each section it has different prototype cells. I have created the prototype cell in storyboard but I could not make more than one cell in cellForRowAtIndexPath. I have attached the whole code for reference.
This is my storyboard design
This is the final output screen which it should look like
import UIKit
class PlacePeopleViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var friendlistTableView: UITableView!
var sectionHead = ["Friends", "Others"]
override func viewDidLoad() {
super.viewDidLoad()
friendlistTableView.delegate = self
friendlistTableView.dataSource = self
// Do any additional setup after loading the view.
}
// MARK: - tableview datasource & delegate
func numberOfSections(in tableView: UITableView) -> Int {
return sectionHead.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return self.sectionHead[section]
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return 5
}else {
return 10
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell1") as! RecentVizzTableViewCell
cell.placeName.text = "poland"
cell.placeAddress.text = "Simon Albania"
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 79
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 15
}
}
Note : You can do this using only one cell. just hide/show the connect Button by checking some condition.
If you want to use different cells for different sections, inside your cellForRowAt indexPath method return your cells based on your section like below .
switch indexPath.section {
case 0:
let cell = tableView.dequeueReusableCell(withIdentifier: "cell1") as! RecentVizzTableViewCellOne
return cell
default:
let defaultcell = tableView.dequeueReusableCell(withIdentifier: "defaultcell") as! RecentVizzTableViewCellDefatult
return defaultcell
}
hope this will help to you. good luck.
I have a tableview with 2 prototype cells in a view controller. I want each cell to display data from different arrays.
Below is my code. I can get the tableview to show jobs or schools, but not both. I don't understand how to make the table display cell1 (jobs) and then cell2 (schools) when each cell contains different data sources.
screenshot
Import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
let jobs = ["McDonalds", "Hardees", "Taco Bell"]
let schools = ["Univ of CO", "Univ of TX", "Univ of CA"]
override func viewDidLoad() {
super.viewDidLoad()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return jobs.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "JobsCell", for: indexPath) as! Jobs
let job = jobs[indexPath.row]
cell.jobLbl.text = job
return cell
}
}
Answer: I fixed this by adding numberOfSections function (thanks Robert). Updated code below if anyone else has this question:
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
let jobs = ["McDonalds", "Hardees", "Taco Bell"]
let schools = ["Univ of CO", "Univ of TX", "Univ of CA", "Univ of Camdenton"]
override func viewDidLoad() {
super.viewDidLoad()
}
func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if (section == 0) {
return jobs.count
} else {
return schools.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "JobsCell", for: indexPath) as! Jobs
let job = jobs[indexPath.row]
cell.jobLbl.text = job
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "SchoolsCell", for: indexPath) as! Schools
let school = schools[indexPath.row]
cell.schoolLbl.text = school
return cell
}
}
}
It sounds like you want to display one section with cells for jobs followed by a second section with cells for schools. If that's the case, you'll need to set the number of sections to 2, then rewrite your delegate functions to respond appropriately depending on the section number.
So numberOfRowsInSection is going to have to check the section number, then return the number of rows for that specific section. And cellForRowAt will need to check the section, then set up and return either a job or a school cell for the given row.
Here's what that would look like in your example:
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
let jobs = ["McDonalds", "Hardees", "Taco Bell"]
let schools = ["Univ of CO", "Univ of TX", "Univ of CA"]
override func viewDidLoad() {
super.viewDidLoad()
}
func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch(section) {
case 0: return jobs.count
default: return schools.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch(indexPath.section) {
case 0:
let cell = tableView.dequeueReusableCell(withIdentifier: "JobsCell", for: indexPath) as! Jobs
let job = jobs[indexPath.row]
cell.jobLbl.text = job
return cell
default:
let cell = tableView.dequeueReusableCell(withIdentifier: "SchoolsCell", for: indexPath) as! Schools
let school = schools[indexPath.row]
cell.schoolLbl.text = school
return cell
}
}
}
And here's the output in the simulator: