I am working on an app in which I need to show multiple rows with a header. In my case only one section is showing. I have searched everything but can't find a suitable solution.
Here is my code:
class Timeline: UITableViewCell {
#IBOutlet weak var timelineData: UITextView!
}
class StudenTimelineViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
let section = ["pizza", "deep dish pizza", "calzone"]
let items = [["Margarita", "BBQ Chicken", "Peproni"], ["sausage", "meat lovers", "veggie lovers"], ["sausage", "chicken pesto", "prawns & mashrooms"]]
override func viewDidLoad() {
super.viewDidLoad()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items[section].count
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return section.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return self.section[section]
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TimelineId", for: indexPath) as! Timeline
let gpsData = items[indexPath.section][indexPath.row]
cell.timelineData.text = gpsData
return cell
}
func tableView(tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 40
}
What I am getting
How will I get all the sections. Thanks in advance.
This is because your method name func numberOfSectionsInTableView(tableView: UITableView) -> Int is incorrect and hence not called.
Replace the name with func numberOfSections(in tableView: UITableView) -> Int and see the magic happen.
//MARK: - Table view data source
func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return 3
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "tableviewCell", for: indexPath)
cell.selectionStyle = UITableViewCellSelectionStyle.none
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat
{
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
{
let cell: UITableViewCell
cell = tableView.dequeueReusableCell(withIdentifier: "tableviewHeader")!
cell.selectionStyle = UITableViewCellSelectionStyle.none
cell.backgroundColor = UIColor.white
return cell
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 32;
}
Related
import UIKit
private let reuseableIdentifier = "cell"
class TableViewController: UITableViewController{
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UITableViewCell.self,forCellReuseIdentifier: reuseableIdentifier)
}
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 0
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let cell = tableView.dequeueReusableCell(withIdentifier: reuseableIdentifier, for: indexPath )
return cell
}
}
So this is my code but at the dequereuseableCell for: indexPath it showing error like can not find indexPath in scope.
You need to return a number greater than 0 in the method of numberOfSections and numberOfRowsInSection
You need to return a cell in the method of cellForRowAt indexPath
import UIKit
private let reuseableIdentifier = "cell"
class TableViewController: UITableViewController{
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UITableViewCell.self,forCellReuseIdentifier: reuseableIdentifier)
}
override func numberOfSections(in tableView: UITableView) -> Int {
// return number of sections
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// return number of rows in sections
return 10
}
// add method
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: reuseableIdentifier, for: indexPath )
return cell
}
}
You are still missing one method:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// dequeue your cell here
}
the method you use should read:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
//return the number of elements to show here
}
documentation
tutorial
Interface:
Interface in debugger:
Here is configuration of tableview
private func configureTableView(){
view.addSubview(tableView)
tableView.delegate = self
tableView.dataSource = self
tableView.separatorStyle = .none
// tableView.rowHeight = UITableView.automaticDimension
tableView.register(DishCell.self, forCellReuseIdentifier: "dishCell")
// tableView.sectionHeaderHeight = UITableView.automaticDimension
}
Here is tableView extensions
extension MenuViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.section == 0 {
return 380
}
return 48
}
func tableView(_ tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat {
return 122
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return UITableView.automaticDimension
}
}
extension MenuViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return viewModel.dishes.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return viewModel.dishes[section].count
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let dishType = viewModel.dishTypes[section]
if section == 0 {
let restaurant = viewModel.restaurant
return FirstMenuHeader(restaurant: restaurant, dishType: dishType)
}else{
return DefaultMenuHeader(dishType: dishType)
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "dishCell") as! DishCell
let dish = viewModel.dishes[indexPath.section][indexPath.row]
cell.set(dish: dish)
return cell
}
}
Just to clarify DishCell, FirstMenuHeader and DefaultMenuHeader look well if you put them outside of UITableview. And they have constraints that define their height. However their height is dynamic and depends on amount of line of text.
Problem was in dishCell.I made constraints with view, while I had to make constraints with contentView.
I have rewrote my constraints and problem was resolved.
My structure is the following:
UIViewController -> UIVIew -> UITableView
tableView(_ tableView: UITableView, numberOfRowsInSection section: Int)
and
tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath)
is called but
tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
is not called.
class ViewcontrollerA : UIViewController , UITableViewDelegate , UITableViewDataSource {
override func viewDidLoad() {
super.viewDidLoad()
self.doctortableView.delegate = self
self.doctortableView.dataSource = self
self.doctortableView.allowsSelection = true
}
func callTable() {
doctortableView.frame = CGRect(......)
view1.addSubview(doctortableView)
doctortableView.isUserInteractionEnabled = true
self.view.addSubview(view1)
}
// Tableview Functions
// Number of Sections in Table
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
var count = Int()
return count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = UITableViewCell()
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//This function is not called
}
}
The problem seems to be in this datasource method at first glance.
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
var count = Int()
return count
}
Doesn't Int() return 0? That means your tableview doesn't have any cells.
As per discussion on Chat
You are creating TableView programatically and add to self.view
func callTable() {
doctortableView.frame = CGRect(......)
view1.addSubview(doctortableView)
doctortableView.isUserInteractionEnabled = true
self.view.addSubview(view1)
}
but your tableView is not on top, so you are not able to scroll it and that's why delegate are not working
following line is missing
self.view.bringSubview(toFront: doctortableView)
Here is Full code
func callTable() {
doctortableView.frame = CGRect(......)
view1.addSubview(doctortableView)
doctortableView.isUserInteractionEnabled = true
self.view.addSubview(view1)
self.view.bringSubview(toFront: doctortableView)
}
I've got a sample code but rows per section won't show, since numberOfRowsInSection doesn't exist in SWIFT 3 anymore.
I currently have the ff code:
let section = ["pizza", "deep dish pizza", "calzone"]
let items = [["Margarita", "BBQ Chicken", "Pepperoni"], ["sausage", "meat lovers", "veggie lovers"], ["sausage", "chicken pesto", "prawns", "mushrooms"]]
override func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
return self.section[section]
}
override func numberOfSections(in tableView: UITableView) -> Int {
return self.section.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "tableCell", for: indexPath)
// Configure the cell...
cell.textLabel?.text = self.items[indexPath.section][indexPath.row]
return cell
}
Result:
Can someone show the correct code for updated swift 3? Thanks!
For your information numberOfRowsInsection exists in swift3, see below
override func numberOfSections(in tableView: UITableView) -> Int {
return section.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items[section].count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")
cell?.textLabel?.text = items[indexPath.section][indexPath.row]
return cell!
}
Thanks:)
import UIKit
class exploreViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var searchBar: UISearchBar!
#IBOutlet weak var exploreTableView: UITableView!
var CELLHEIGHT = 200
var SECTIONHEADER = "SECTIONHEADER"
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
exploreTableView.delegate = self
exploreTableView.dataSource = self
exploreTableView.register(UINib(nibName: "answerCell", bundle: nil), forCellReuseIdentifier: "cell1")
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 2
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return SECTIONHEADER
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 2
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = self.exploreTableView.dequeueReusableCell(withIdentifier: "cell1", for: indexPath) as! answerCell
cell.name.text = "222222"
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return CGFloat(CELLHEIGHT)
}
}
My numberOfSectionsInTableView is never called and I can't get 2 sections.
From your code, I believe you are using Swift3. Then, the following are delegate and datasource methods for UITableView in Swift3
func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 0
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)
// Configure the cell...
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
}
As you can see, your numberOfSections function's syntax is wrong.That is the reason.
This is actually due to access level resolution. When we don't specify the "public" ourselves, the compiler resolves it as to be some privately implemented function and even warns that it nearly matches a public function. If one ignores this then it neglects this function and rather calls the default implementation. Hope this helps someone.
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}