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.
Related
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 have a table view that is rendering some static data into a UITableView but occasionally when running on a physical device the data is replaced with ? (see screenshot). I have listed the code below if anyone has an idea why this is occurring?
Here is the code for the table view
import UIKit
class OvenViewController: UIViewController {
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
extension OvenViewController : UITableViewDataSource,UITableViewDelegate{
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return GridData.ovenTempConvArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: OvenCell.className, for: indexPath) as! OvenCell
let data = GridData.ovenTempConvArray[indexPath.row]
cell.lblFTemp.text = "\(data["f"] ?? "") F"
cell.lblCTemp.text = "\(data["c"] ?? "") C"
cell.lblGasMark.text = data["gm"]
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
}
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'm trying to use UITableView Inside UIViewController. However, when I tried to so it it gives me an error when I start the app.
the error says "method doesnt override ant method from superclass"
import UIKit
class GPATableViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
struct Objects {
var sectionName : String!
var sectionObjects : [String]!
}
var objectsArray = [Objects]()
override func viewDidLoad() {
super.viewDidLoad()
objectsArray =
[Objects(sectionName: "Section1" , sectionObjects: ["","",""]),
Objects(sectionName: "Section2" , sectionObjects: ["","",""]),
Objects(sectionName: "Section3" , sectionObjects: ["","",""])]
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as UITableViewCell!
// cell?.textLabel!.text = objectsArray[indexPath.section].sectionObjects[indexPath.row]
print
return cell!
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return objectsArray[section].sectionObjects.count
}
override func numberOfSections(in tableView: UITableView) -> Int {
return objectsArray.count
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return objectsArray[section].sectionName
}
}
When you implement the UITableViewDatasource in an UIViewController, you are not overriding the methods.
Remove override from the methods that the compiler is tell you to.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as UITableViewCell!
// cell?.textLabel!.text = objectsArray[indexPath.section].sectionObjects[indexPath.row]
print
return cell!
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return objectsArray[section].sectionObjects.count
}
func numberOfSections(in tableView: UITableView) -> Int {
return objectsArray.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return objectsArray[section].sectionName
}
NOTE: If you were using a UITableViewController, then you would need the override, which is probably what was going on in whatever file you copied this from.
Functions involving tableView such as numberOfSections(...), cellForRowAt etc. are not part of the UIViewController.
Instead, they belong to the UITableViewDelegate and UITableViewDataSource.
To fix your errors, remove the override keyword in front of these functions. You are not overriding them but instead "implementing" them at the request of the protocols.
Be sure to also set the view controller as the delegate and dataSource if you have not already done so in a Storyboard:
override func viewDidLoad()
super.viewDidLoad()
// other code...
tableView.delegate = self
tableView.dataSource = self
// other code...
}
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
}
}