Why is my tableView not being populated? - ios

I'm trying to populate a basic tableview with sample data in code. Here's my ViewController:
import UIKit
class TableViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var postTableView: UITableView!
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 4
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "postcell", for: indexPath)
cell.textLabel?.text = "title"
cell.detailTextLabel?.text = "detail"
return cell
}
}
Here is my storyboard
I'm sure that the name "postcell" is correct and that I've hooked up the tableView to the ViewController as a datasource and delegate.
When I run the code in the iOS simulator, no cells show up. This is what I see:
Here are the constraints on my stack view
stack view properties
I don't want to use UITableViewController
How do I get the table cells to appear?

If "postcell" is not a prototype cell from your storyboard, you need to register it in your viewDidLoad:
postTableView.register(UITableViewCell.self, forCellReuseIdentifier: "postcell")
If it is a XIB table view cell you would register it as follows:
postTableView.register(UINib(nibName: "NibName", bundle: nil), forCellReuseIdentifier: "postcell")
If you were to do it from storyboard, drag a prototype cell (or table view cell) onto your table view and in the reuse identifier call it "postcell" as shown here:
Make sure you have also done the following in your viewDidLoad:
postTableView.delegate = self
postTableView.dataSource = self
Of course, you'll also need:
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}

in tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath)
let cell = tableView.dequeueReusableCell(withIdentifier: "postcell", for: indexPath) as postcell // add this line

Thank you #MrSaturn for pointing out in the comments that it's a problem with the stack view. In storyboard I had to change the stack view's alignment property from center to Fill.

Related

embed custom view into UITableViewCell

I already have a subclass of UIView, called CustomView, which I use in stack views.
I am wanting to redo the UI and use a table view instead. So, for that I just wanted to reuse the CustomView class I already have but for some reason the table view is not showing the cell at all.
I think the issue is the way I am using CustomView in CustomCell: UITableViewCell:
class CustomCell: UITableViewCell {
#IBOutlet var customView: CustomView!
}
in the view controller holding the table view, I have in viewDidLoad:
tableView.register(UINib(nibName: "CustomCell", bundle: Bundle.main), forCellReuseIdentifier: "CustomCell")
and
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
return tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
When I run the app, I just get a blank table view.
Good day I made the same code that you, and works , could you add breakpoint in this position.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
return tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath)
}
you shouldn't have problem using custom views inside cells.
You have to use designated initializer for your custom view like init(frame:CGRect) or add it to the interface builder, like a prototype cell.

Adding label to a prototype cell

I need to add a label to a prototype cell but I am getting the error "Value of type 'UITableViewCell' has no member 'movieTitleLabel'.
import UIKit
class FirstTableView: UITableViewController {
let model = MovieModel()
override func viewDidLoad() {
super.viewDidLoad()
}
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return model.MovieArray.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "movieCells", for: indexPath) as! TableViewCell
cell.movieTitleLabel?.text = model.movieArray[indexPath.row]
return cell
}
I have the FirstTableView set as the delegate and datasource, in the editor.
I created a new subclass named: TableViewCell, linked the label to that class. Now I am at at loss as to how to output the movieArray to that label.
You forgot to downcast cell to your UITableViewCell subclass so you have reference just to superclass UITableVoewCell and this superclass hasn’t any movieTitleLabel.
To fix this, add as! YourTableViewCellSubclass to the end of the line where you dequeue cell
let cell = tableView.dequeueReusableCell(withIdentifier: "movieCells", for: indexPath) as! YourTableViewCellSubclass
Look out into these points:
You have created an outlet of the label named as 'movieTitleLabel' in ViewController, but this label should be in TableCell class. Make correct reference of this label.
After the first point, now to access this label, follow this code:
Code:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "YourTableCellIdentifier", for: indexPath) as! YourTableCellClass
cell.movieTitleLabel.text = "Text" // Set your text here now
return cell
}
Your prototype cell should have specified an implementation class - this must be a subclass of UITableViewCell. If you've done this, downcast the result of dequeueReusableCell to this class.
You should also have connected the movieTitleLabel outlet in that class to the label in the storyboard. It looks from the above as if you've connected it to the UITableViewController instead (#IBOutlet weak var movieTitleLabel: UILabel!). You should remove this from the VC and only have it in the UITableViewCell class.

How to connect UITextField to UITableView?

I have 2 tableViews in one ViewController class.
In first tableView I have UITextField in custom cell with it's own UITableViewCell class.
I show textField in cell inside of cellForRowAt but i couldn't connect it like Outlet to VC and use it in ViewDidLoad.
How could I use textField Outlet from cell inside VC?
You can Not directly Connect outlet of Any Thing Embedded In TableCell
Follow Steps To Perform Code operation with Outlets Connected
Step 1- Create a new tableViewCell Class as Below ScreenSHot
Step 2- Now Assign Created Class to TableView cell in Storyboard as Below
Step 3- Time to connect outlets in Cell class created by normally dragging the TF to be Connected in cell class
output will be as Below
Step 4- Required Coding
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CustomTableCell
cell.fileNameLabel.text = coreClassObject.audioFileName
cell.durationLabel.text = coreClassObject.audioDuration
cell.uploadedStatusLabel.text = coreClassObject.audioUploadStatus
cell.playButton.addTarget(self, action: #selector(playSoundAtSelectedIndex(sender:)), for: .touchUpInside)
return cell
}
Re-Update Answer to Access TF in ViewDidLoad
----> my ViewController class
import UIKit
class tableViewVC: UIViewController
{
let staticArrayy = ["1","1","1","1","1","1","1","1","1","1"]
#IBOutlet weak var myDemoTableView: UITableView!
override func viewDidLoad()
{
super.viewDidLoad()
// Do any additional setup after loading the view.
///Set Delegates
myDemoTableView.delegate = self
myDemoTableView.dataSource = self
///Async operation
///To make sure cells are loaded
DispatchQueue.main.async
{
///Create a Reference TF
let MyTf : UITextField!
///Get Index Path of Which TF is to be Accessed
let indexPath = IndexPath(row: 0, section: 0)
///Create A new cell Reference
let newCell = self.myDemoTableView.cellForRow(at: indexPath)! as! CustomTableViewCell
///Assign Cell TF to our created TF
MyTf = newCell.cellTF
///Perform Changes
MyTf.text = "Changes text"
}
}
}
extension tableViewVC : UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return staticArrayy.count
}
//Setting cells data
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = self.myDemoTableView.dequeueReusableCell(withIdentifier: "Cell") as! CustomTableViewCell
cell.cellTF.placeholder = staticArrayy[indexPath.row]
return cell
}
//Setting height of cells
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
return 60
}
}
---> My cell class
import UIKit
class CustomTableViewCell: UITableViewCell
{
#IBOutlet weak var cellTF: UITextField!
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
}
}
----> My StoryBoard
---> Simulator Output
First of all it is bad idea to connect TextField with ViewController.
But if you want to, then first you need to check if you table consists of static cells and desired cell with textfield is among them. Then you can connect textField with viewcontroller's outlet and use it in viewDidLoad
TableView with dynamic cells will reload after viewDidLoad called so you cannot use textfield var in that method
You aren't supposed to link TableViewCell outlets in the ViewController – you should have a separate MyTableViewCell class where you link all of the outlets, such as:
class MyTableViewCell: UITableViewCell {
// MARK: Outlets
#IBOutlet weak var myTextField: UITextField!
}
You reference this table view in the view controller via the function tableView:cellForRowAtIndexPath and there you can handle all actions performed on the cell and by default, the TextField.
func tableView(_ tableView: UITableView, cellForItemAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withReuseIdentifier: "myCell", for: indexPath) as! MyTableViewCell
// Customize the cell and the TextField
return cell
}
Put your outlet inside your Cell class, and when you want to access it’s text from vc
U will do let cell = tableview.cellforrow(at indexpath) as! YourCellClass
Then access the textfield easily
let text = cell.yourTextField.text
But i advice you to remove the tableview and instead use scrollview if its simple viewcontroller

implementing UITextFieldDelegate

I want to use https://github.com/intuit/AnimatedFormFieldTableViewCell in my project but I can’t get my head around the steps for setting it up. So far, I’ve dragged the files from the folder and followed the steps as:
In order to use AnimatedFormFieldTableViewCell, all you have to do is:
1) Register the AnimatedFormFieldTableViewCell nib on the ViewController on which you are implementing your UITableView for your reuse identifier.
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.registerCellNib(AnimatedFormFieldTableViewCell)
tableView.reloadData()
}
2) Dequeue your cell on CellForRowAtIndexPath as a AnimatedFormFieldTableViewCell.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellIdentifier = "cell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! AnimatedFormFieldTableViewCell
return cell
}
3) Change the placeholder's label text by calling setLabelText on the cell itself.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellIdentifier = "cell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! AnimatedFormFieldTableViewCell
cell.setLabelText("Enter title")
return cell
}
Notes:
1) You can still implement UITextFieldDelegate the same way you would implement on a regular UITextField, you just need to define the AnimatedFormFieldTableViewCell's delegate (there is no need to directly define the delegate for the embedded UITextField).
2) In order to access the embedded UITextField you can simply call the cell's cellTextField property.
I don’t get these last two steps.
If I run my app, I get the unexpectedly found nil on self.cellTextfield.delegate = self in the AnimatedFormFieldTableViewCell class.
What am I missing?
Hi waseefakhtar your code does not miss anything. just the only problem is you registered the nib with the wrong way that's why you got the unexpectedly found nil error on self.cellTextfield.delegate = self.
try this code:
let myNib = UINib.init(nibName: "AnimatedFormFieldTableViewCell", bundle: nil)
self.tableView.registerNib(myNib, forCellReuseIdentifier: "cell")
PS: just be aware that registerNib method syntax can differ depending on the swift version
My code is here, I don't know where you clerical error, but you can check my code to find out:
import UIKit
class ViewController2: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// register a nib like below
let nib:UINib = UINib.init(nibName: "AnimatedFormFieldTableViewCell", bundle: nil)
self.tableView.register(nib, forCellReuseIdentifier: "AnimatedFormFieldTableViewCell")
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 88.0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "AnimatedFormFieldTableViewCell", for: indexPath as IndexPath) as! AnimatedFormFieldTableViewCell
cell.setLabelText("Enter title")
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
}
}
The result:
So, just check the steps, where you go wrong.
The documentation notes this:
There is no need to directly define the delegate for the embedded UITextField
The instruction is to do the following:
You just need to define the AnimatedFormFieldTableViewCell's delegate
You'll want to set the AnimatedFormFieldTableViewCell's delegate rather than the cellTextField's delegate, so:
self.delegate = yourUITextViewDelegate
rather than self.cellTextField.delegate = yourUITextViewDelegate (this is wrong)
This is what the documentation describes
Edit: OP clarified that the delegate assignment code is not in their class; it's in the pod's class. I'm considering deleting this answer as I don't think it is solving the problem.

How to detected nib file table view cell to make ReusableCell?

I need to add cell identifier to make ReusableCell for tableView. However I don't see any cell in the tableView properties and table view hierarchical. how to add a cell in the table view .
note : basically i want to create a Xib file which should contain a tableView and that tableView should have custom UiTableViewCell
code here :
class SuggestNearTableViewCollectionViewCell: UICollectionViewCell , UITableViewDataSource,UITableViewDelegate{
#IBOutlet weak var suggestTableView : UITableView!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
self.suggestTableView.dataSource = self
self.suggestTableView.delegate = self
suggestTableView.register(UINib(nibName: "SuggestNearTableViewCell", bundle: nil), forCellReuseIdentifier: "SuggestNearTableViewCell")
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "SuggestNearTableViewCell", for: indexPath) as! SuggestNearTableViewCell
return cell
}
}
First of all go to File-> new -> Cocoa Touch Class and create class of UIViewCOntroller. Name your class accordingly.
Now you will have a Xib file and a Swift file. Xib would look something like this.
Now drag and drop a UITableView on the Xib and give it 4-pin constraints as top=0, bottom=0, leadin=0, and trailing=0. Now create an outlet of your tableView in your newly created swift file. Connect data Source and delegate as well.
Now again go to File->New-> Coucoa Touch Class and create a class for UItableViewCell also create a Xib file like below.
Now you will have a Xib for your cell and a swift file for your cell. Just design your cell as your need in this Xib. Lets say If you want to put an imageView or a label etc. Then create outlets of all components in swift file of your custom cell. Now add this function in swift file of your custom cell.
class func cellForTableView(tableView: UITableView, atIndexPath indexPath: NSIndexPath) -> YourCustomTableViewCell {
let kYourCustomTableViewCellIdentifier = "kYourCustomTableViewCellIdentifier"
tableView.registerNib(UINib(nibName: "YourCustomTableViewCell", bundle: NSBundle.mainBundle()), forCellReuseIdentifier: kYourCustomTableViewCellIdentifier)
let cell = tableView.dequeueReusableCellWithIdentifier(kYourCustomTableViewCellIdentifier, forIndexPath: indexPath) as! YourCustomTableViewCell
return cell
}
Your custom cell is ready to use.
Now go to the swift file of your tableView and in your cellForRowAtIndexPath just use use this cell like below.
let cell = YourCustomTableViewCell.cellForTableView(tableView, atIndexPath: indexPath)
cell.myImageView.image = "something"
// Do something with your cell
I hope it would be helpfull. Let me know if you find any difficulty.
Inside tableViewController in viewDidLoad you should register it like this:
tableView.registerNib(UINib(nibName: "CustomOneCell", bundle: nil), forCellReuseIdentifier: "CustomCellOne")
And inside cellForRowAtIndexPath just declare cell:
let cell: CustomOneCell = tableView.dequeueReusableCellWithIdentifier("CustomCellOne", forIndexPath: indexPath) as! CustomOneCell
If you are not doing it inside tableViewController then you gotta connect your tableView and delegate:
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
...
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// Table view delegate
self.tableView.delegate = self
self.tableView.dataSource = self
...

Resources