I've created a tableView, but when I click it, I don't get any results. I wanted to add a new feature to improve my project, but I couldn't add the videos I watched and the things I researched.
Table View
import UIKit
class ViewController1: UIViewController {
#IBOutlet weak var FoodView: UITableView!
let dogfoods = ["pork", "banana", "chicken-leg"]
override func viewDidLoad() {
super.viewDidLoad()
FoodView.delegate = self
FoodView.dataSource = self
// not tapped no see
FoodView.allowsSelection = false
}
}
extension ViewController1: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 120
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dogfoods.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = FoodView.dequeueReusableCell(withIdentifier: "CustomCell") as! CustomCell
let dogfood = dogfoods[indexPath.row]
cell.foodImageView.image = UIImage(named: dogfood)
cell.nameLabel.text = dogfood
return cell
}
}
CustomCell
class CustomCell: UITableViewCell {
#IBOutlet weak var dogView: UIView!
#IBOutlet weak var nameLabel: UILabel!
#IBOutlet weak var foodImageView: 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
}
}
When I click on one of the cells in the picture, I want to write a larger version of the picture and a description, how can I do this? When I searched on the internet, I applied similar ones, but I couldn't get any results.
You have a few choices. You can add one or more buttons to your custom cell. You can attach a tap gesture recognizer to your cell's content view.
Probably the easiest way to respond to a tap on the whole cell is to have view controller conform to the UITableViewDelegate protocol and implement the tableView(_:didSelectRowAt:) method.
That method will be called when the user selects a cell, and you would use the indexPath of the tapped cell to figure out which one was tapped and do whatever is appropriate.
You can do that with easy and efficient way using Delegate in Swift
//create protocol as we used interface in Java
#objc protocol TableViewCellDelegate {
#objc func click(indexPath: IndexPath?)
}
// Modify your class CustomCell as:
#IBOutlet weak var dogView: UIView!
#IBOutlet weak var nameLabel: UILabel!
#IBOutlet weak var foodImageView: UIImageView!
var delegate: TableViewCellDelegate?
var indexPath: IndexPath?
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped(tapGestureRecognizer:)))
foodImageView.isUserInteractionEnabled = true
foodImageView.addGestureRecognizer(tapGestureRecognizer)
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
#objc func imageTapped(tapGestureRecognizer: UITapGestureRecognizer) {
let tappedImage = tapGestureRecognizer.view as! UIImageView
self.delegate.click?(indexPath: self.indexPath)
}
// Modify your tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) in ViewController1 as
let cell = FoodView.dequeueReusableCell(withIdentifier: "CustomCell") as! CustomCell
cell.delegate = self
cell.indexPath = indexPath
let dogfood = dogfoods[indexPath.row]
cell.foodImageView.image = UIImage(named: dogfood)
cell.nameLabel.text = dogfood
return cell
// And now add extension add the end of ViewController1
extension ViewController1: TableViewCellDelegate {
func click(indexPath: IndexPath?) {
// open image for preview here
}
}
You can do it in many ways
use a add a UITableViewDelegate method which is
override func tableView(_ tableView: UITableView, didSelectRowAt
indexPath: IndexPath){
//your code...
}
it will called every time when cell clicked.
if you prefer to trigger any button click rather then cell click then go for delegate (Izaan Saleem already explained), or you can use NotificationCenter, but for this task I prefer didSelect or delegate solution.
I am new to swift and have been experimenting with passing data between view controllers. I have been attempting to pass data from a view controller into a UITableViewCell, However once run my code has no effect.
DetailViewController
(passes data to the libraryViewController)
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let DestViewController: LibraryMovieViewController = segue.destination as! LibraryMovieViewController
DestViewController.movieTitle = movieTitle
DestViewController.movieRelease = movieReleaseDate
}
}
UITableViewCell
class MovieSearchTableViewCell: UITableViewCell {
#IBOutlet weak var titleLabel: UILabel!
#IBOutlet weak var posterView: UIImageView!
#IBOutlet weak var overviewLabel: UILabel!
}
LibraryViewController
struct libMovie {
//let mainImage: UIImage
let title: String
let release: String
}
class LibraryMovieViewController: UIViewController {
#IBOutlet weak var tableView: UITableView!
var dataSource: [libMovie] = []
var movieTitle: String!
var movieRelease: String!
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
// Do any additional setup after loading the view.
loadDataSource()
}
func loadDataSource(){
// dataSource.append(libMovie(title: " \(movieTitle)", release: " \(movieRelease)"))
}
}
extension LibraryMovieViewController: UITableViewDataSource, UITableViewDelegate{
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 115
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataSource.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let movieCell = tableView.dequeueReusableCell(withIdentifier: "libCell", for: indexPath) as? LibraryMovieTableViewCell else {
return UITableViewCell()
}
let libMovie = dataSource[indexPath.row]
movieCell.cellTitleLabel.text = "Movie Title: \(movieTitle)"
movieCell.cellReleaseLabel.text = "Release Date: \(movieRelease)"
return movieCell
}
}
I would expect that when the app is run that movieTitle and movieReleaseDate are passed from the detail view controller and input into the library table cell, this is initiated by tapping a button on the detail view controller.
However this seems to have no affect on the program or simply returns blank cells.
No errors are reported in console nor does the app crash
In prepareForSegue you've passed data to movieTitle and movieRelease, while you're using dataSource to inflate data on tableView.
Either pass and object of [libMovie] to DestViewController.dataSource if you want to inflate multiple rows of different movies or return 1 in numberOfRowsInSection and pass set the label content in cell with movieTitle and movieRelease.
In your code, numberOfRowsInSection is returning dataSource.count, but doesn't seem to pass that data to this view controller.
You can either hardcode the numberOfRowsInSection as 1 or pass the dataSource from the first view controller and update your cellForRowAtIndexPath method.
The data source in the destination view controller is empty, what do you expect?
Uncomment the line in loadDataSource and reload the table view.
func loadDataSource(){
dataSource.append(ibMovie(title: movieTitle, release: movieRelease))
tableView.reloadData()
}
And replace
movieCell.cellTitleLabel.text = "Movie Title: \(movieTitle)"
movieCell.cellReleaseLabel.text = "Release Date: \(movieRelease)"
with
movieCell.cellTitleLabel.text = "Movie Title: \(libMovie.title)"
movieCell.cellReleaseLabel.text = "Release Date: \(libMovie.release)"
I wrote a class that let me create multiple tableView simply. When I call this class for the first time, everything work well. But when I change some data, and reload the table, nothing changed.
Sample code:
class TestViewController: UIViewController {
var arrData = ["a","b","c"]
var myTableView: MyTableView?
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
myTableView = MyTableView(table: tableView, data: arrData)
}
#IBAction func buttonTapped(_ sender: UIButton) {
arrData = ["d","e","f"]
myTableView!.tableView.reloadData() //=> Not change anything
}
}
class MyTableView: NSObject, UITableViewDataSource {
var tableView: UITableView
var data: Array<String>
init(table: UITableView, data: Array<String>) {
self.data = data
self.tableView = table
super.init()
self.tableView.dataSource = self
self.tableView.register(MyTableViewCell.self, forCellReuseIdentifier: "myCell")
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.data.count
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath) as! MyTableViewCell
cell.textLabel!.text = self.data[indexPath.row]
return cell
}
}
class MyTableViewCell : UITableViewCell {
//something here
}
When the view was loaded, the table has 3 rows: a,b,c. When I tap the button, nothing changed (expected: d,e,f)
Please help me!
Swift arrays are copied by value so the line self.data = data will take a copy of your array. Later changing the array contents of the source will not be reflected in the copy in your MyTableView.
You'll need to pass the array over again and take a second copy to update the table, e.g. write a method in MyTableView similar to the following:-
func setNewValues(data: Array<String>)
{
self.data = data
self.tableView.reloadData()
}
and call that from your buttonTapped function, i.e.:
#IBAction func buttonTapped(_ sender: UIButton) {
arrData = ["d","e","f"]
myTableView!.setNewValues(data: arrData)
}
Be careful with the force-unwrapped myTableView though - I'd replace that '!' with '?'.
I intergrade SWRevealViewController to my project
my project flow is
viewcontroller ---> SWRevealViewController -->menu
--> nav-->front view
the segue method from my initial view controller to SWRevealViewController is model
my problem is when my I open toggle in front view for first time only
it give me empty menu(table view)
my front view code
#IBOutlet weak var open: UIBarButtonItem!
#IBOutlet weak var result: UILabel!
#IBAction func showmore(sender: AnyObject) {
performSegueWithIdentifier("resdes", sender: sender)
}
override func viewDidLoad() {
super.viewDidLoad()
var res = Uti.get_result()
result.text = res.description
open.target = self.revealViewController()
open.action = Selector("revealToggle:")
self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
// Do any additional setup after loading the view.
}
my rear code
class slidemenuVC : UITableViewController{
var menuItems = [String]()
override func viewDidAppear(animated: Bool) {
menuItems = ["Result","About us","References","Rest Test"]
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return menuItems.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier(menuItems[indexPath.row], forIndexPath: indexPath) as UITableViewCell
cell.textLabel?.text = menuItems[indexPath.row]
return cell
}
}
Second problem :
when I press at first menu item , navigation disappear
it should be like this have toggle
var cell = tableView.dequeueReusableCellWithIdentifier(menuItems[indexPath.row], forIndexPath: indexPath) as UITableViewCell
is wrong. You need your identifier has to be the actual cell id in your uitableviewcell
I want to use a UITableview with different custom tableViewCells. My 3 cells are as such:
Cell1: should have an image and a label.
Cell2: should have two labels.
Cell3: should have a dayPicker.
I don't want to code a tag for the cells. How can I manage this in Swift. Do I have to code my own class for every cell? Can I use one tableviewController? How can I populate data in different cells?
I would like to generate a tableView, like a contact app of an iOS device.
Let me start with answering your questions first.
Do I have to code an own class for every cell?=> Yes, I believe so. At least, I would do that way.
Can I use one tableviewController?=> Yes, you can. However, you can also have a table view inside your View Controller.
How can I populate data in different cells? => Depending on the conditions, you can populate data in different cells. For example, let's assume that you want your first two rows to be like the first type of cells. So, you just create/reuse first type of cells and set it's data. It will be more clear, when I show you the screen shots, I guess.
Let me give you an example with a TableView inside a ViewController. Once you understand the main concept, then you can try and modify anyway you want.
Step 1: Create 3 Custom TableViewCells. I named it, FirstCustomTableViewCell, SecondCustomTableViewCell, ThirdCustomTableViewCell. You should use more meaningful names.
Step 2: Go the Main.storyboard and drag and drop a TableView inside your View Controller. Now, select the table view and go to the identity inspector. Set the "Prototype Cells" to 3. Here, you just told your TableView that you may have 3 different kinds of cells.
Step 3:
Now, select the 1st cell in your TableView and in the identity inspector, put "FirstCustomTableViewCell" in the Custom class field and then set the identifier as "firstCustomCell" in the attribute inspector.
Do the same for all others- Set their Custom Classes as "SecondCustomTableViewCell" and "ThirdCustomTableViewCell" respectively. Also set the identifiers as secondCustomCell and thirdCustomCell consecutively.
Step 4: Edit the Custom Cell Classes and add outlets according to your need. I edited it based on your question.
P.S: You need to put the outlets under the class definition.
So, In the FirstCustomTableViewCell.swift, under the
class FirstCustomTableViewCell: UITableViewCell {
you would put your label and image view outlets.
#IBOutlet weak var myImageView: UIImageView!
#IBOutlet weak var myLabel: UILabel!
and in the SecondCustomTableViewCell.swift, add the two labels like-
import UIKit
class SecondCustomTableViewCell: UITableViewCell {
#IBOutlet weak var myLabel_1: UILabel!
#IBOutlet weak var myLabel_2: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
and the ThirdCustomTableViewCell.swift should look like-
import UIKit
class ThirdCustomTableViewCell: UITableViewCell {
#IBOutlet weak var dayPicker: UIDatePicker!
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
Step 5: In your ViewController, create an Outlet for your TableView and set the connection from storyboard. Also, you need to add the UITableViewDelegate and UITableViewDataSource in the class definition as the protocol list.
So, your class definition should look like-
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
After that attach the UITableViewDelegate and UITableViewDatasource of your table view to your controller. At This point your viewController.swift should look like-
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
P.S: If you were to use a TableViewController rather than a TableView inside a ViewController, you could have skipped this step.
Step 6: Drag and drop the image views and labels in your cell according to the Cell class. and then provide connection to their outlets from storyboard.
Step 7: Now, write the UITableViewDatasource's required methods in the view controller.
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if indexPath.row == 0 {
let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "firstCustomCell")
//set the data here
return cell
}
else if indexPath.row == 1 {
let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "secondCustomCell")
//set the data here
return cell
}
else {
let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "thirdCustomCell")
//set the data here
return cell
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
Swift 3.0 + update with minimum code
Basic concept:
Create a table view with dynamic cell prototypes. Assign identifier and create custom table view cell class for each cell prototype. Initiate and show custom cells in table view's delegate method.
1. Create cells on storyboard
Drag a tableView to your view controller, add prototype cells to it, and then drop UI element to your table view cells, add constraint properly if needed.
2. Create custom UITableViewCell classes
Add the following code to your project. I am putting it right above the view controller class.
class FirstTableCell: UITableViewCell {
}
class SecondTableCell: UITableViewCell {
}
class ThirdTableCell: UITableViewCell {
}
3. Assign custom class and identifier to cell prototypes
For each of the cell prototypes in storyboard, assign the custom class created from step 2, and then enter an unique identifier.
4. Connect UI elements to swift code
Control drag the table view and connect to the view controller class. Control drag the UI elements that get added to cell prototypes on step 1, and connect to the corresponding table view cell class.
5. Add code to view controller and control the table view
Make your view controller conform to table view delegate
class YourViewController: UIViewController, UITableViewDataSource, UITableViewDelegate
In viewDidLoad, set up table view's delegate and data source.
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.dataSource = self
self.tableView.delegate = self
}
Finally, add two delegate methods to control your table view, as per minimum requirement.
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "firstTableCell") as! FirstTableCell
// Set up cell.label
return cell
} else if indexPath.row == 1 {
let cell = tableView.dequeueReusableCell(withIdentifier: "secondTableCell") as! SecondTableCell
// Set up cell.button
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "thirdTableCell") as! ThirdTableCell
// Set up cell.textField
return cell
}
}
6. Give it a try :)
I recommend to use this simple and easy to use library, I made for Table and Collection views. You can add as many types of cells as you want and achieve more clean ViewControllers without boilerplate code.
https://github.com/deniskakacka/DKDataSources
For UI on first picture, all your code in ViewController is this:
lazy var dataSource = DKTableDataSource<CellType>(
models: [
DisclosureCellModel(title: "Disclosure 1", action: .action1),
TextFieldCellModel(title: "TextField 1", placeholder: "Placeholder 1"),
SwitchCellModel(title: "Switch 1", isOn: true),
BannerCellModel(imageName: "placeholder"),
SwitchCellModel(title: "Switch 2", isOn: false),
BannerCellModel(imageName: "placeholder"),
DisclosureCellModel(title: "Disclosure 2", action: .action2),
TextFieldCellModel(title: "TextField 2", placeholder: "Placeholder 2"),
BannerCellModel(imageName: "placeholder")
]
)
// in `viewDidLoad`
dataSource.registerCells(for: tableView)
tableView.dataSource = dataSource
Swift 5
Create 3 Custom TableViewCells. I named it,
FirstTableViewCell, SecondTableViewCell,
ThirdTableViewCell
Add All 3 Custom Cell Classes and add outlets according to your need.
I have added in below code.
class FirstTableViewCell: UITableViewCell {
#IBOutlet weak var myImageView: UIImageView!
#IBOutlet weak var myLabel: UILabel!
static let cellIdentifier = "FirstTableViewCell"
static let cellNib = UINib(nibName: "FirstTableViewCell", bundle: Bundle.main)
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
}
}
3: In your ViewController, create an Outlet for your TableView. Also, you need to add the UITableViewDelegate and UITableViewDataSource in the class definition.
#IBOutlet weak var tableView: UITableView! {
didSet {
tableView.delegate = self
tableView.dataSource = self
tableView.register(FirstTableViewCell.cellNib, forCellReuseIdentifier: FirstTableViewCell.cellIdentifier)
tableView.register(SecondTableViewCell.cellNib, forCellReuseIdentifier: SecondTableViewCell.cellIdentifier)
tableView.register(ThirdTableViewCell.cellNib, forCellReuseIdentifier: ThirdTableViewCell.cellIdentifier)
}
}
4.Now, write the UITableViewDatasource's required methods in the view controller.
extension ViewController: UITableViewDelegate,UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == 0 {
guard let cell = tableView.dequeueReusableCell(withIdentifier: FirstTableViewCell.cellIdentifier, for: indexPath) as? FirstTableViewCell else { return UITableViewCell() }
return cell
}else if indexPath.row == 1 {
guard let cell = tableView.dequeueReusableCell(withIdentifier: SecondTableViewCell.cellIdentifier, for: indexPath) as? SecondTableViewCell else { return UITableViewCell() }
return cell
}else {
guard let cell = tableView.dequeueReusableCell(withIdentifier: ThirdTableViewCell.cellIdentifier, for: indexPath) as? ThirdTableViewCell else { return UITableViewCell() }
return cell
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 50 //According requirement
}
}
Your code will look like below(View Controller Code)
class ViewController: UIViewController {
#IBOutlet weak var tableView: UITableView! {
didSet {
tableView.delegate = self
tableView.dataSource = self
tableView.register(FirstTableViewCell.cellNib, forCellReuseIdentifier: FirstTableViewCell.cellIdentifier)
tableView.register(SecondTableViewCell.cellNib, forCellReuseIdentifier: SecondTableViewCell.cellIdentifier)
tableView.register(ThirdTableViewCell.cellNib, forCellReuseIdentifier: ThirdTableViewCell.cellIdentifier)
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
extension ViewController: UITableViewDelegate,UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == 0 {
guard let cell = tableView.dequeueReusableCell(withIdentifier: FirstTableViewCell.cellIdentifier, for: indexPath) as? FirstTableViewCell else { return UITableViewCell() }
return cell
}else if indexPath.row == 1 {
guard let cell = tableView.dequeueReusableCell(withIdentifier: SecondTableViewCell.cellIdentifier, for: indexPath) as? SecondTableViewCell else { return UITableViewCell() }
return cell
}else {
guard let cell = tableView.dequeueReusableCell(withIdentifier: ThirdTableViewCell.cellIdentifier, for: indexPath) as? ThirdTableViewCell else { return UITableViewCell() }
return cell
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 50 //According requirement
}
}
The above answers are the best answers, but there are TONS of reasons to get this issue. Here is another potential solution for anyone with this problem:
My problem was that I was segueing to the ViewController class and not the storyboard view. So my reference to the storyboard cell was meaningless, since the storyboard wasn't being used.
I was doing this:
let viewControllerB = SubViewController()
viewControllerB.passedData = diseases[indexPath.row].name
navigationController?.pushViewController(viewControllerB, animated: true)
And I needed to do something like this:
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let nextViewController = storyBoard.instantiateViewController(withIdentifier: "SubViewStoryboardController") as! SubViewController
nextViewController.passedData = diseases[indexPath.row].name
self.present(nextViewController, animated:true, completion:nil)
Hope this helps someone.
If you're using custom XIBs as TableView Cells then follow the below code
//Write in viewDidLoad()
let nib = UINib(nibName: "PrinterTVC", bundle: nil)
tableView.register(nib, forCellReuseIdentifier: "CELL1")
let nib1 = UINib(nibName: "SelectAndEditTVC", bundle: nil)
tableView.register(nib1, forCellReuseIdentifier: "CELL2")
UITableViewController is inheriting UIViewController that already has UITableviewDataSource & UITableviewDelegate mapped on itself.
You might subclass UITableViewController or use a TableView inside your ViewController.
After that you must implement required methods(cellForRowAtIndexPath and numberOfRowsInSection) which are declared in the UITableviewDataSource.
Also in storyboard, you need to create cell prototypes with unique Id.
There are basic types of cell, with (title, subtitle for instance) - you can use them too if you don't need special configuration.
So, for picker, yes, you need to create your own custom cell. Create necessary custom UITableViewCell class holding date picker and make sure to use delegate to send back the desired result back to your ViewController.