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

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
...

Related

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

UITableViewController not loading custom cells using xib file

I have a UITableViewController and want to populate it with custom cells. The cell I have created has it's own class and xib file, away from the main storyboard.
In the xib file, I have 'VisitCell' as the identifier.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "VisitCell", for: indexPath) as! VisitCell
let visit : BookingVisitItem = bookingDayItem.getVisitItems()[indexPath.row]
cell.locationLabel?.text = visit.getVenueName()
cell.timeLabel?.text = visit.getVisitTime()
cell.typeLabel?.text = visit.getVisitType()
return cell
}
If I run the code like this, it seems to crash. Maybe it can't find the custom cell?
However, if I add the following to viewDidLoad()
tableView.register(VisitCell.self, forCellReuseIdentifier: "VisitCell")
At this stage, it doesn't crash but the table view appears to be empty.
Any pointers? Thanks!
Register your nib cell in viewDidLoad()-:
override func viewDidLoad() {
super.viewDidLoad()
yourTableView.registerNib(UINib(nibName: "yourcell", bundle: nil), forCellReuseIdentifier: "CustomCellOne")
}

Why is my tableView not being populated?

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.

Share custom UITableViewCell to multiple UITableViewController in Swift

Currently, I have two table view controllers which contain some identical custom tableview cells. Each table view controller has its own custom tableview cells. I'm wishing to create only one custom table view cell which can be shared among these two table view controllers. Any guides can I refer to?
First you can create a UITableViewCell with code: (and you can design your cell view in a .xib file - see here for detail)
// MyCell.Swift
import UIKit
import Foundation
class MyCell: UITableViewCell {
// do whatever you want to customize the cell
}
Then in each of your two UITableViewController's classes, register your custom UITableViewCell class in viewDidLoad.
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.register(MyCell.self as AnyClass, forCellReuseIdentifier: "cell")
}
Then create/reuse this custom cell in cellForRowAtIndexPath function:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell: MyCell? = self.tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? MyCell
if cell == nil {
// if the cell is not yet created in the system, create a new cell object
cell = MyCell(style: .default, reuseIdentifier: "cell")
}
// customize your cell...
cell.textLabel?.text = "Your Label Text"
return cell!
}

IOS tableview issue

I'm having an issue where my app will freeze if when I press it to got the next scene which is a view controller with a tableview nested inside of it. the app will only freeze when I've declared how many rows the table will have. If anyone knows how to fix this problem its be greatly appreciated.
class ViewController: UIViewController, UITableViewDataSource {
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = UITableViewCell()
cell.textLabel?.text = "hello"
return cell
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Have you set dataSource of your table view? You must call tableView.dataSource = self somewhere in your code (most probably in viewDidLoad method)
The problem with your code is that in tableView(_:cellForRowAtIndexPath:) you are creating new cell every time the method is called. That is not how table views (or collection views) work.
The idea behind these components is to reuse their cells so that your application shows better performance. What if you have 1000 cells? You will create 1000 UITableViewCell objects for each cell? This is where dequeueReusableCellWithIdentifier(_:) comes in handy.
So set an identifier for your cell in Interface Builder, for example "Cell" and get the cell like this:
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! UITableViewCell
This is the right way to go.
You have to make sure you set the correct reuse identifier for your table view cell (either in storyboard, or code).
Storyboard:
Of if you want to do it in code, put this in viewDidLoad():
tableView.registerClass(UITableViewCell, forHeaderFooterViewReuseIdentifier: "cellIdentifier")
Important to know that you should only use one of the above. If you define your UI in Storyboards, I recommend the first approach.
Then when you create the cell in tableView(_:, cellForRowAtIndexPath), instead of this:
var cell = UITableViewCell()
Use a cell from the reuse queue like so:
var cell = tableView.dequeueReusableCellWithIdentifier("cellIdentifier", forIndexPath: indexPath) as! UITableViewCell
Everytime you are creating object for cell, make sure you use reuse identifier.
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! UITableViewCell

Resources