I've created a UITableView inside my ViewController. Here's the code I've added to fill the TableView with content. However, no content is showing up. I've created a customized tableView Cell which I am calling in the cellNib as PostTableViewCell. When the program is running, it shows the prototype cells with the divider lines, but none of the custom content.
import Foundation
import UIKit
import Firebase
class HomeViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var tableView:UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView = UITableView(frame: view.bounds, style: .plain)
//tableView.backgroundColor = UIColor.blue
let cellNib = UINib(nibName: "PostTableViewCell", bundle: nil)
tableView.register(cellNib, forCellReuseIdentifier: "postCell")
view.addSubview(tableView)
var layoutGuide:UILayoutGuide!
if #available(iOS 11.0, *) {
layoutGuide = view.safeAreaLayoutGuide
} else {
layoutGuide = view.layoutMarginsGuide
}
tableView.leadingAnchor.constraint(equalTo: layoutGuide.leadingAnchor).isActive = true
tableView.topAnchor.constraint(equalTo: layoutGuide.topAnchor).isActive = true
tableView.trailingAnchor.constraint(equalTo: layoutGuide.trailingAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo: layoutGuide.bottomAnchor).isActive = true
tableView.delegate = self
tableView.dataSource = self
tableView.reloadData()
// 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 12
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "postCell", for: indexPath) as! PostTableViewCell
return cell
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
You're not actually configuring the cell in your tableView:cellForRowAt: method:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "postCell", for: indexPath) as! PostTableViewCell
return cell
}
Typically you need to insert values into the elements of your custom cell. The "content" of your cell label text, images etc is usually inserted into the cells elements in this method. If you look at the code in a new Xcode project you will see:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let object = objects[indexPath.row] as! NSDate
cell.textLabel!.text = object.description
return cell
}
Note the line retrieving the data: let object = objects[indexPath.row] as! NSDate
Followed by the line in setting the text value of the textLabel:
cell.textLabel!.text = object.description
Code looks right..
Make sure you have assign content to table cell in cellForRowAt datasource methods.
Related
The UITableView accessory view is not being displayed in a table view that is set to another view's input view and presented as such when that view becomes first responder.
For example, this code displays a table view controller with a single table view cell that has a checkmark for its accessory.
import PlaygroundSupport
import UIKit
class TableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
1
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.textLabel?.text = "Hello world"
cell.accessoryType = .checkmark
return cell
}
}
let tableViewController = TableViewController()
PlaygroundPage.current.liveView = tableViewController
When I set this same table view controller as the input view to a text field, it comes up when the user taps on the text field in gray.
import PlaygroundSupport
import UIKit
class TableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
1
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.textLabel?.text = "Hello world"
cell.accessoryType = .checkmark
return cell
}
}
let tableViewController = TableViewController()
let textField = UITextField()
textField.backgroundColor = .gray
textField.frame = CGRect(origin: .zero, size: CGSize(width: 100, height: 20))
let frame = CGRect(origin: .zero, size: CGSize(width: 360, height: 780))
let view = UIView(frame: frame)
view.addSubview(textField)
textField.inputView = tableViewController.view
PlaygroundPage.current.liveView = view
However, it is missing the checkmark accessory now.
How can you show the accessory view on the UITableViewCell when the UITableView is used as an input view?
Tried as Xcode project (works well as expected), and hold a reference to the table view controller, otherwise, it goes out of scope and deallocated (Not sure this is the root cause of the issue here).
Source code, your table view controller and adding text field in storyboard and having a reference of table view controller in view controller.
class TableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
1
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.textLabel?.text = "Hello world"
cell.accessoryType = .checkmark
return cell
}
}
class ViewController: UIViewController {
#IBOutlet weak var tx: UITextField!
var tableViewController : TableViewController!
override func viewDidLoad() {
super.viewDidLoad()
self.tableViewController = TableViewController()
self.tx.inputView = self.tableViewController.view
}
}
My code:
//
// ForumViewController.swift
// Kode4Kids
//
// Created by Caleb Clegg on 17/06/2020.
// Copyright © 2020 Group9. All rights reserved.
//
import UIKit
class ForumViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
tableView = UITableView(frame: view.bounds, style: .plain)
tableView.backgroundColor = UIColor.white
let cellNib = UINib(nibName: "ForumViewCell", bundle: nil)
tableView.register(cellNib, forCellReuseIdentifier: "ForumCell")
view.addSubview(tableView)
var layoutGuide:UILayoutGuide!
if #available(iOS 11.0, *){
layoutGuide = view.safeAreaLayoutGuide
} else {
//fallback on previous versions
layoutGuide = view.layoutMarginsGuide
}
tableView.leadingAnchor.constraint(equalTo: layoutGuide.leadingAnchor).isActive = true
tableView.topAnchor.constraint(equalTo: layoutGuide.topAnchor).isActive = true
tableView.trailingAnchor.constraint(equalTo: layoutGuide.trailingAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo: layoutGuide.bottomAnchor).isActive = true
tableView.delegate = self
tableView.dataSource = self
tableView.reloadData()
}
#IBAction func backTapped(_ sender: Any) {
let homeViewController = self.storyboard?.instantiateViewController(identifier: Constants.Storyboard.homeViewController) as? HomeViewController
self.view.window?.rootViewController = homeViewController
self.view.window?.makeKeyAndVisible()
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 12
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ForumCell", for: indexPath) as! ForumViewController
return cell
}
}
[I keep getting: "Cannot convert return expression of type 'ForumViewController' to return type 'UITableViewCell', I've been at this for two days and my project is due for college next week. I'd really appreciate some help. "][1]
Any ideas on what might need to change?
[1]: https://i.stack.imgur.com/Dgxfn.png
You need to return UITableViewCell not UIViewController in cellForRow function so replace the as ForumViewController to “as ForumCell” or whatever the name of your custom UITableViewCell is.
You can't cast UITableViewCell as UIViewController.
Replace this:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ForumCell", for: indexPath) as! ForumViewController
return cell
}
With this:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
tableView.dequeueReusableCell(withIdentifier: "ForumCell", for: indexPath) // since you're not doing any additional stuff here this would do
}
Note: If you've made a xib file for defining the layout of your UITableViewCell use it's class for downcasting. In your case as! ForumViewCell.
I am creating a UITableView using code, I am not using any storyboard or IB.
Following is my code:
class UserListController: UIViewController , UITableViewDelegate, UITableViewDataSource {
var chatTableView: UITableView = {
let table = UITableView()
table.translatesAutoresizingMaskIntoConstraints = false
return table
}()
func setChatTableView(){
chatTableView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
chatTableView.topAnchor.constraint(equalTo: chatSegmentControl.bottomAnchor).isActive = true
chatTableView.widthAnchor.constraint(equalTo:view.widthAnchor).isActive = true
chatTableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
}
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(chatTableView)
setChatTableView()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
let cellIdentifier = "cellId"
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath
// ) as UITableViewCell
let cell = UITableViewCell(style: .subtitle, reuseIdentifier: cellIdentifier)
cell.textLabel?.text = "LaLaLa"
return cell
}
I have created chatTableView which is my TableView and have add this on the main view i am not using UITableViewController.
I can see the table view on screen but there is no message in rows so what I should do to populate table view please help.
I am new to the ios and using a swift 4.
Thank you in advance.
Please provide UITableViewDataSource and UITableViewDelegate
var chatTableView: UITableView = {
let table = UITableView()
table.dataSource = self
table.delegate = self
table.translatesAutoresizingMaskIntoConstraints = false
return table
}()
You can also get full tutorial over Here.
I am having a problem trying to show an array of images on each cell, for a tableview.
I have a separate TableViewCell Swift file where I have a UIImage on the cell linked up. The outlet is named: CellVenueImage
For some reason when I try to implement the image on my TableView view controller, I get an error that says: Value of type 'TableViewCell' has no member 'CellVenueImage'
Here is the line in which that happens:
cell.CellVenueImage.image = imagename
Using Swift 3.
Here is the code for the TableView:
import UIKit
class VenueTableViewController: UITableViewController {
let VenueImageList = ["1970s.png","1980s.png","1990s.png"]
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return VenueImageList.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "VenueCell", for: indexPath) as! TableViewCell
let imagename = UIImage(named: VenueImageList[indexPath.row])
cell.CellVenueImage.image = imagename
return cell
}
TableViewCell code:
import UIKit
class VenuesTableViewCell: UITableViewCell {
#IBOutlet weak var CellVenueImage: UIImageView!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
The mistake is, that you're not using your created TableViewCell Subclass, you are using a regular UITableViewCell.
let cell = tableView.dequeueReusableCell(withIdentifier: "VenueCell", for: indexPath) as! TableViewCell
You need to cast it as your UITableViewCell subclass.
If it is called "VenuesTableViewCell", for example: class VenuesTableViewCell: UITableViewCell {, then cast it as VenuesTableViewCell.
let cell = tableView.dequeueReusableCell(withIdentifier: "VenueCell", for: indexPath) as! VenuesTableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "VenueCell", for: indexPath) as! VenuesTableViewCell
I have this View Controller (see code below) linked to a table view controller storyboard. I get the actual table view showing but not my custom cell. Any ideas of what I am doing wrong?
Good to know:
- I have a separate swift file specifically made for my cell
- I have connected the cell with a cell identifier
- This is not my main view controller.
Thanks in advance!
import UIKit
class ForecastTableViewController: UITableViewController {
var forecasts = [Forecast]()
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.reloadData()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return forecasts.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: "forecastCell", for: indexPath) as? ForecastCell {
let forecast = forecasts[indexPath.row]
cell.configureCell(forecast: forecast)
return cell
} else {
return ForecastCell()
}
}
}
Add below lines in viewDidload above reload function,
self.tableView.delegate = self
self.tableView.dataSource = self
And no need of self.tableView.reloadData() in viewDidload so remove it!
Put this inside your viewDidLoad() method
self.tableView.registerNib(UINib(nibName: "ForecastCell", bundle: nil), forCellReuseIdentifier: "forecastCell")
Also make sure that you actually set the cell's identifier not restoration ID (common mistake)
Have you register your cell, if not register it first.
tableView.registerClass(MyCell.classForCoder(), forCellReuseIdentifier: kCellIdentifier)
OR if you are using cell with Xib then register
self.tableView.registerNib(UINib(nibName: "UICustomTableViewCell", bundle: nil), forCellReuseIdentifier: "UICustomTableViewCell")
Try to change your code in this way and remember to put your data inside your forecasts array
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "forecastCell", for: indexPath) as? ForecastCell
let forecast = forecasts[indexPath.row]
cell.configureCell(forecast: forecast)
return cell
}