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...
}
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 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 feedVC which shows updates from all user. I'm retrieving data from firebase and want the height to set automatically depending on the post length. the problem is, even after returning UITableViewAutomaticDimension from heightForRowAt, the cells don't resize automatically when the VC is first launched. if I navigate to other vc and come back to the feedVc it is working fine. Images Attached
When VC is launched for the first time
After switching to another VC from tabbar and then again tapping on feed, it's giving the desired results.
class FeedViewController: UIViewController, UITableViewDelegate, UITableViewDataSource{
#IBOutlet weak var tableviewFeed: UITableView!
var listPost = [Posts]()
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return listPost.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableviewFeed.dequeueReusableCell(withIdentifier: "feedCell") as! FeedCell
cell.lblUser.sizeToFit()
cell.lblPost.sizeToFit()
cell.lblUser.text = listPost[indexPath.row].user
cell.lblPost.text = listPost[indexPath.row].post
return cell
}
override func viewDidLoad() {
super.viewDidLoad()
tableviewFeed.estimatedRowHeight = 100
}
override func viewWillAppear(_ animated: Bool) {
FirebaseService.instance.retrievePost { (post) in
self.listPost = post.reversed()
self.tableviewFeed.reloadData()
}
}
}
You need to call
cell.lblUser.layoutIfNeeded()
after
cell.lblUser.sizeToFit()
I am trying to implement a tableview with different sections. Before putting this code in, the app ran fine. I understand this error pops up from outlets that are not connected properly, so I believe the error is coming from the IBOutlet I set with my TableView. But I am not sure what I am doing wrong. Below is my code:
import UIKit
class MainPageVC: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
let textCellIdentifier = "cell"
let items = ["My Items", "Needed Items", "Future Items"]
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return items[section]
}
func numberOfSections(in tableView: UITableView) -> Int {
return items.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: textCellIdentifier, for: indexPath)
return cell
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
I did not put in a prototype cell in the tableview, this got rid of the error.