swift segue from tableView through a navigationController to a TableViewController - swift

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.

Related

Swift UITableview Reload Cell

I'm stuck with the following, any inputs would be highly appreciated.
My app has a UITableViewController with custom cells. Let's name its UITableView as TABLE VIEW-1. I am using XIB as its custom cell. Inside that xib, there is another UITableView, (TABLE VIEW-2), with another XIB as its custom cell.
My question is, How can I reload cells of (TABLE VIEW-2) from (TABLE VIEW-1) once I get data from an API in (TABLE VIEW-1). I want to use delegate and protocols to do this.
OR, What would be the correct way of performing this and how would I go about it?
Create a reference of TableView1 in the TableView2 ViewController. You can do this by
-- Open the Assistant Editor
-- Right-click and drag from your UI element (i.e. label) to the code file
-- Xcode auto inserts code for you to create the name and connection
Then call tableView2.reloadData(), where tableView2 is the name of the outlet you just created.
Create a reference of the TABLE VIEW-2 in the TABLE VIEW-1 custom cell (TABLE VIEW-1 CELL)
Create a method inside TABLE VIEW-1 CELL to reload its data alone with the TABLE VIEW-2 (Optional but useful to organize your code)
Inside the tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell of the TABLE VIEW-1 call reload function
class ViewController: UIViewController {
#IBOutlet weak var mainTable: UITableView!
let sampleData = [
(section: "News", SubSections: [
"Breaking news",
"Current Affairs",
"Local"
]) ]
override func viewDidLoad() {
super.viewDidLoad()
self.mainTable.estimatedRowHeight = 200
self.mainTable.rowHeight = UITableView.automaticDimension
let nib: UINib = UINib(nibName: String(describing: MainCell.self), bundle: Bundle.main)
self.mainTable.register(nib, forCellReuseIdentifier: String(describing: MainCell.self))
}
}
extension ViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
self.sampleData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: MainCell = tableView.dequeueReusableCell(withIdentifier: String(describing: MainCell.self), for: indexPath) as! MainCell
let sectionData = self.sampleData[indexPath.row]
cell.setUpData(title: sectionData.section, data: sectionData.SubSections)
return cell
}
}
class MainCell: UITableViewCell {
#IBOutlet weak var sectionTitle: UILabel!
#IBOutlet weak var internalTable: UITableView!
var tableData:[String]?
override func awakeFromNib() {
super.awakeFromNib()
self.internalTable.estimatedRowHeight = 200
self.internalTable.rowHeight = UITableView.automaticDimension
let nib: UINib = UINib(nibName: String(describing: InsideCell.self), bundle: Bundle.main)
self.internalTable.register(nib, forCellReuseIdentifier: String(describing: InsideCell.self))
}
func setUpData(title: String, data:[String]) {
self.sectionTitle.text = title
self.tableData = data
self.internalTable.reloadData()
}
}
extension MainCell: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
self.tableData?.count ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: InsideCell = tableView.dequeueReusableCell(withIdentifier: String(describing: InsideCell.self), for: indexPath) as! InsideCell
if let subSectionData = self.tableData?[indexPath.row] {
cell.subSectionTitle.text = subSectionData
}
return cell
}
}
class InsideCell: UITableViewCell {
#IBOutlet weak var subSectionTitle: UILabel!
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
}
}

How to fix 'tableview cellforrowat not called?'

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

tableView not showing data values

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.

How to use UITableViewAutomaticDimension?

I have a feedVC which shows updates from all user. I'm retrieving data from firebase and want the height to set automatically depending on the post length. the problem is, even after returning UITableViewAutomaticDimension from heightForRowAt, the cells don't resize automatically when the VC is first launched. if I navigate to other vc and come back to the feedVc it is working fine. Images Attached
When VC is launched for the first time
After switching to another VC from tabbar and then again tapping on feed, it's giving the desired results.
class FeedViewController: UIViewController, UITableViewDelegate, UITableViewDataSource{
#IBOutlet weak var tableviewFeed: UITableView!
var listPost = [Posts]()
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return listPost.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableviewFeed.dequeueReusableCell(withIdentifier: "feedCell") as! FeedCell
cell.lblUser.sizeToFit()
cell.lblPost.sizeToFit()
cell.lblUser.text = listPost[indexPath.row].user
cell.lblPost.text = listPost[indexPath.row].post
return cell
}
override func viewDidLoad() {
super.viewDidLoad()
tableviewFeed.estimatedRowHeight = 100
}
override func viewWillAppear(_ animated: Bool) {
FirebaseService.instance.retrievePost { (post) in
self.listPost = post.reversed()
self.tableviewFeed.reloadData()
}
}
}
You need to call
cell.lblUser.layoutIfNeeded()
after
cell.lblUser.sizeToFit()

Make Cell Clickable In UIViewController

I am using a UIViewController and a Table View/Table View Cell (extending to delegate/datasource). Whenever a cell is clicked from MessageController, it is supposed to be directed into another View Controller, called ChatController. Even though I am using didSelectRowAt and adding a segue with identifier, it does not switch to the ChatController.
import UIKit
class MessagesController: UIViewController, UITableViewDataSource, UITableViewDelegate {
var myIndex = 0;
#IBOutlet weak var tableView: UITableView!
var tableData: [MModel] = []
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
MData.getData { (data) in
self.tableData = data
self.tableView.reloadData()
}
func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tableData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MessageCell") as! MessagesCell
cell.setup(model: tableData[indexPath.row])
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 375
}
//clicking on cell
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "segue", sender: nil)
}
}
The problematic line is as follows:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "segue", sender: nil)
}
You must set the delegate also in viewDidLoad
self.tableView.delegate = self
You have not set the delegate to the tableview.
Set it as:
aftertableView.dataSource = self
tableView.delegate = self
my problem had to do with having a GestureRecognizer in my viewDidLoad(). after so many hours of troubleshooting i realize that what was breaking the code was that 'hide keyboard' code of GestureRecognizer.