I am using a Custom TableViewCell in TableViewController.
Even the data is getting populated but my TableViewCell does not display it.
Here is my Custom TableViewCell Code
class PlaceItemCellCustom: UITableViewCell {
#IBOutlet weak var placeFace: UILabel?
#IBOutlet weak var placeName: UILabel?
override func awakeFromNib() {
super.awakeFromNib()
}
}
Here is my TableViewContoller
class PlaceListViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
loadListFromSource()
}
// Other code
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return places.count
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let place = places[indexPath.row]
// I am getting the data
print(place.placeName?.description ?? " " )
let customCell = tableView.dequeueReusableCell(withIdentifier: "PlaceListIdentifier", for: indexPath) as! PlaceItemCellCustom
customCell.placeName?.text = place.placeName
return customCell
}
}
What am I missing here? I am new to IOS app development.
Found similar questions but did not help
Edit: It was working fine for the default TableViewCell.
But when I changed it to custom TableViewCell it does not work. I have set the class name in the storyboard as well.
Here is my Storyboard
Here is the output
As much as I can understand you must have forgotten to connect the IBOutlet of placeName in PlaceItemCellCustom:
In your PlaceItemCellCustom keep placeName as :
#IBOutlet weak var placeName: UILabel!
and in cellForRowAt:
customCell.placeName.text = place.placeName
in this way if you forgot to connect segue Xcode will throw error as :
Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
You can read more about it here :
https://cocoacasts.com/should-outlets-be-optionals-or-implicitly-unwrapped-optionals
You need using this method for get data.
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return places.count
}
Related
I'm new to swift, I made a simple table and added 21 data in it.
When I debug, the compiler enters here, I see that there are 21.
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print(menus.count)
return menus.count
}
but it doesn't go into this part
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "mCell", for: indexPath) as! HomeViewCell
let men = menus[indexPath.row]
print(men.Title)
cell.mTitle.text = men.Title
cell.subTitle.text = men.SubTitle
return cell
}
I'm learning new things from books, videos, sorry for the newbie question
I think I've done all the work but I couldn't figure out what I'm skipping I watched too many videos and I'm confused
all code,
class ViewController: UIViewController , UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var menuTable: UITableView!
var menus = [Menu]()
override func viewDidLoad() {
super.viewDidLoad()
loadMenus()
}
override func viewDidLayoutSubviews(){
}
func loadMenus(){
for index in 0...20 {
menus.insert(Menu(Image: "0", Title: "String \(index)", SubTitle: "String"), at: index)
}
self.menuTable.reloadData()
// DispatchQueue.main.async {
//
// }
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print(menus.count)
return menus.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "mCell", for: indexPath) as! HomeViewCell
let men = menus[indexPath.row]
print(men.Title)
cell.mTitle.text = men.Title
cell.subTitle.text = men.SubTitle
return cell
}
}
class HomeViewCell: UITableViewCell {
#IBOutlet weak var mTitle: UILabel!
#IBOutlet weak var subTitle: UILabel!
#IBOutlet weak var mImage: UIImageView!
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
I tried your code and everything works well.
The only thing I can think of:
Make sure you have assigned the class to the table view cell and connected the outlets.
What you showed me above is the identifier. See below for class.
After I do this, I see the result:
Output in the console
21
21
21
String 0
String 1
String 2
String 3
String 4
String 5
String 6
String 7
String 8
String 9
String 10
String 11
String 12
String 13
String 14
Can you confirm you assigned HomeViewCell class to the Cell in storyboard ?
Update
You use auto layouts to set up your table and give the cell a height of 138 but you do not add any constraints for the subviews within your cell so I believe the runtime is unable to determine the actual height of your cell if the subviews in the cell do not have proper constraints.
add this UITableView delegate method and run your app to see if you see results:
func tableView(_ tableView: UITableView,
heightForRowAt indexPath: IndexPath) -> CGFloat {
return 138
}
Of Course, change 138 to whatever you want or better yet configure your cell layout in autolayout.
End result:
Try adding this in viewDidLoad:
menuTable.register(HomeViewCell.self, forCellReuseIdentifier: "mCell")
I am trying to pass data from tableview to another page (view controller) but problem is i am getting an error from tableview. Below is the code and i have marked the error where i am getting.
P1ViewController.Swift
class P1ViewController: ViewController,UITableViewDelegate,UITableViewDataSource {
var name=["Table1","Table2"]
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return name.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell=tableView.dequeueReusableCell(withIdentifier: "cell")
cell?.textLabel?.text=name[indexPath.row]
return cell!
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let detail=self.storyboard?.instantiateViewController(withIdentifier: "DetailViewController") as! DetailViewController
detail.lblName=name[indexPath.row] //This is the error i am getting "Cannot assign value of type 'String' to type 'UILabel'"
self.navigationController?.pushViewController(detail, animated: true)
}
override func viewDidLoad() {
super.viewDidLoad()
}
}
DetailViewController.Swift
class DetailViewController: ViewController {
#IBOutlet weak var lblName: UILabel!
var name:String!
override func viewDidLoad() {
super.viewDidLoad()
lblName.text=name
}
}
Actually you would have to write
detail.lblName.text = name[indexPath.row]
but this will cause a crash. Assign the value to the name property
detail.name = name[indexPath.row]
I'm setting up a tableview with customtableview cell, but when i run the app, the data is not shown.
I already check all the connection, identifier, class name, etc
import UIKit
class ViewController: UITableViewController {
#IBOutlet var testingTableView: UITableView!
var data = ["Indomie","Kacang Tanah","Soya"]
override func viewDidLoad() {
super.viewDidLoad()
testingTableView.register(UINib(nibName: "TableViewCell", bundle: nil), forCellReuseIdentifier: "customCell")
// Do any additional setup after loading the view.
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = testingTableView.dequeueReusableCell(withIdentifier: "customCell", for: indexPath) as! customTableViewCell
cell.customLabel.text = data[indexPath.row]
return cell
}
override func numberOfSections(in tableView: UITableView) -> Int {
return data.count
}
}
This is my code for the table view, it's should call the cellforrowat but it's not
You are missing tableView(_:numberOfRowsInSection:) implementation.
You have number of data.count section, but each section has 0 row.
Try replacing numberOfSections(in:) to tableView(_:numberOfRowsInSection:)
I guess you need additional code as below-
testingTableView.delegate = self
testingTableView.datasource = self
testingTableView.reloadData() // I think you missed it!
1). Add this line
#IBOutlet var testingTableView: UITableView! {
didSet {
testingTableView.delegate = self
testingTableView.dataSource = self
}
}
2). You also can add this feature via Stroyboard. Click on your table and using right click drag the pointer on ViewController and add delegate and dataSource.
And i think you missed
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 0 //As per your need.
}
You are using the wrong API, numberOfSections returns the number of sections but you have to return the number of rows
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { {
return data.count
}
There is no need to override numberOfRowsInSection, the default value is 1.
And delete
#IBOutlet var testingTableView: UITableView!
There is an implicit tableView property of UITableViewController
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 cannot get this to segue to another TableViewController. I keep getting a crash... I know it is because it is going through the NavigationController and I do not know how to segue from the main controller to pass it and go to the tableView. Heres the look
the segue from the navControl to the tableView is called "ChildsInfo"
Here is what I am trying and crashing.
class PagesViewController: UIViewController, UITableViewDelegate {
#IBOutlet weak var pagesTableView: UITableView!
#IBOutlet weak var infoProgressBar: UIProgressView!
let pages = ["Page 1","Page 2","Page 3"]
var myIndex = 0
var selectedPage: String?
override func viewDidLoad() {
super.viewDidLoad()
pagesTableView.dataSource = self
pagesTableView.delegate = self
// Do any additional setup after loading the view.
}
}
extension PagesViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "pagesTableViewCell")
cell?.textLabel?.text = pages[indexPath.row]
return cell!
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return pages.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 71.0
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.row == 0 {
performSegue(withIdentifier: "ChildsInfo", sender: self)
}
}
}
Based on the images you have posted I'm assuming the crash you are getting is that the segue is not found. This is because you should be trying to perform the segue to the navigation controller itself from the table view (i.e. the link on the left in your image). The navigation controller then has a root view controller and you can push others onto the stack as required.