Trying to work out a couple of scenes in my app my I cant get the tableViews to work as they should.
Im doing a settings like tableView where the user choses between two possible settings. Each options leads to new tableView where the user must pick one of the available options. Once the user has chosen one, the label in the first scene will display the value chosen (which is stored also as NSUserDefaults). So if Im not mistaken this could be achieved with 3 static tableViews. The code following is how Im trying to do it:
Initial settings view controller:
class SettingsVC2: UITableViewController{
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 2
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if indexPath.section == 0{
let cell = tableView.dequeueReusableCellWithIdentifier("office_cell", forIndexPath: indexPath)
cell.textLabel?.text = "Select your office"
return cell
}
else {
let cell = tableView.dequeueReusableCellWithIdentifier("dept_cell", forIndexPath: indexPath)
cell.textLabel?.text = "Select your department"
return cell
}
One of the settings tableViews:
class SettingsDepartmentTVC: UITableViewController{
let departamentos: [String] = ["Sales", "Pre-Sales", "General Administration", "Customer Service", "Profesional Services", "Regionales"]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return departamentos.count
}
override func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
let cell: UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("department_cell", forIndexPath: indexPath)
cell.textLabel?.text = self.departamentos[indexPath.row]
return cell
}
}
I believe all datasources and delegates are hooked right and UIKit is imported even if not shown.
Erros Im getting:
Assertion failure in -[UITableView
dequeueReusableCellWithIdentifier:forIndexPath:]
Terminating app due to uncaught exception
'NSInternalInconsistencyException', reason: 'unable to dequeue a cell
with identifier office_cell - must register a nib or a class for the
identifier or connect a prototype cell in a storyboard
This is the method where I try to populate the tableView:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath)
-> UITableViewCell{
let cell = tableView.dequeueReusableCellWithIdentifier("CommentsRowTVC", forIndexPath: indexPath) as! CommentsRowTVC
let single_comment = self.AOS[indexPath.row]
cell.titulo_comentario?.text = single_comment.titulo_comment
cell.cuerpo_comentario?.text = single_comment.cuerpo_comment
cell.fecha_comentario?.text = single_comment.fecha_comment
return cell
}
class CommentsRowTVC: UITableViewCell {
#IBOutlet weak var titulo_comentario: UILabel!
#IBOutlet weak var cuerpo_comentario: UILabel!
#IBOutlet weak var fecha_comentario: 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
}
}
Here is the connections inspector for the UIViewController where the table is:
And this one for the UIViewCellController:
Errors to this point:
UIView tableView:numberOfRowsInSection: unrecognized selector sent to instance
Terminating app due to uncaught exception NSInvalidArgumentException, reason: [UIView tableView:numberOfRowsInSection:]: unrecognized selector sent to instance
If you're truly making static table view cells then you should just delete these methods. You only use them when you are dequeueing cells dynamically.
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return departamentos.count
}
override func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
let cell: UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("department_cell", forIndexPath: indexPath)
cell.textLabel?.text = self.departamentos[indexPath.row]
return cell
}
If you are actually trying to make dynamic cells then, as your error message suggests, you need to make sure your identifier matches what you have in interface builder:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
let cell: UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("{your_identifier}", forIndexPath: indexPath)
cell.textLabel?.text = self.departamentos[indexPath.row]
return cell
}
With the code you have provided it looks like you have not registered your table view cells and identifiers with the table view.
UITableView Class Reference
Discussion Prior to dequeueing any cells, call this method or the
registerNib:forCellReuseIdentifier: method to tell the table view how
to create new cells. If a cell of the specified type is not currently
in a reuse queue, the table view uses the provided information to
create a new cell object automatically.
If you previously registered a class or nib file with the same reuse
identifier, the class you specify in the cellClass parameter replaces
the old entry. You may specify nil for cellClass if you want to
unregister the class from the specified reuse identifier.
I would suggest that you register them in viewDidLoad().
let KDepartmentCellIdentifier = "department_cell"
tableView.registerClass(UITableViewCell.class, forCellReuseIdentifier: kKDepartmentCellIdentifier)
let KOfficeCellIdentifier = "office_cell"
tableView.registerClass(UITableViewCell.class, forCellReuseIdentifier: kOfficeCellIdentifier)
If you are using a nib then use
registerNib(_ nib: UINib?, forCellReuseIdentifier identifier: String)
Related
I have this code:
class UserProfilViewController: UIViewController {
// Outlets
#IBOutlet weak var userProfileTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.tabBarController?.navigationItem.title = "Profil"
}
}
// MARK: - Table View Data Source
extension UserProfilViewController {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "UserProfilCell", for: indexPath)
return cell
}
}
My project in bitbucket: https://bitbucket.org/trifek/karta-nauka/src/master/
I placed one tableviewcell cell on the tableview (UserProfil.storyboard). I have a form on it that I would like to display in this cell. The problem is the cell does not display. Does anyone know how to fix it?
As per the code you have shared, Please change your code to following.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "UserProfilCell", for: indexPath) as! UserProfilTableViewCell
return cell
}
Let me know in case of any queries.
IMHO, first try to clear your requirements. If you want to display fix number of cells then you can simply use static cells. If your cells are dynamic i.e their number depends on some calculation or other logic, then you can use dynamic cell. While using dynamic cell, verify if you have registered it or not (if you are using xib for cell) and also verify for the cell identifier.
#Lukasz
Please use the below code for this.
class UserProfileViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
setUIComponents()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
private func setUIComponents(){
registerNibs()
}
}
extension UserProfileViewController: UITableViewDelegate, UITableViewDataSource{
internal func registerNibs(){
tableView.register(UINib(nibName: String(describing: UserProfileTableCell.self), bundle: Bundle.main), forCellReuseIdentifier: kUserProfileCellReuseId)
}
//MARK: TableView Methods -
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let sessionCell: UserProfileTableCell.self = tableView.dequeueReusableCell(withIdentifier: kUserProfileCellReuseId, for: indexPath) as! UserProfileTableCell.self
cell.titleLabel.text = “TEST”
return sessionCell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
}
}
class UserProfileTableCell: UITableViewCell {
//Set the "kUserProfileCellReuseId" in nib to register identifier.
let kUserProfileCellReuseId = "kUserProfileCellReuseId"
//MARK: - Override Methods
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
setUIComponents()
}
private func setUIComponents(){
}
}
You never declare that your view controller conforms to the UITableViewDataSource or UITableViewDelegate protocols. Given that you don't do that, you would not be able to set your view controller as the data source or delegate of your table view.
I have embedded UITabbar in UIViewController and then I put some UITabbarItems in my UITabbar. I also created another UIViewController with UITableView embedded in it.
I have linked one of the UITabbarItem with this newly created UIViewController(with UITableView in it).
When I run the program and tap on that UITabbarItem it shows a table view but when I select any row of table, the data displaying in UITableView disappears.
I then debug the code and found that didSelectRowAtIndexPath method didn't call.
I searched on the internet and find this but cannot understand it well.
I tried by implementing both types of tableViews (UITableViewController,UIViewController with UITableView in it) but still same problem.
I am stuck here. Anyone please help me. How to get resolve this issue.
I will be very Thankful to you.
Here is my swift code
import UIKit
class DashboardViewController: UIViewController,UITableViewDataSource,UITableViewDelegate {
#IBOutlet weak var tableView: UITableView!
var selectedIndexPathForCheckMark:NSIndexPath?
var items: [String] = ["We", "Heart", "Swift"]
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "MyCell")
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("MyCell")!UITableViewCell
cell.textLabel?.text = self.items[indexPath.row]
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
print("You selected cell #\(indexPath.row)!")
selectedIndexPathForCheckMark = indexPath
tableView.reloadData()
}
here are its snapshots
Second UITabbarItem from right implements UITableView
Follow Steps:
1. Take A view controller and add tableview.
2. set outlet with MytabelView
3. set Datasource and delegate of tableview to ViewController
4. and put the following code in ViewController class
5. Take a custom tableview cell with name MyCell having cell identifier "MyCellid"
6. Create swift file with name MyCell, make it subclass of UITableViewCell
7. Choose custom cell and assign it class to MyCell.
I think Its done
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate{
#IBOutlet weak var MytableView: UITableView!
var items: [String] = ["We", "Heart", "Swift"]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.MytableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "MyCellid")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.MytableView.dequeueReusableCellWithIdentifier("MyCellid")! as UITableViewCell
cell.textLabel?.text = self.items[indexPath.row]
return cell
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
print("You selected cell #\(indexPath.row)!")
}
}
I've added TableView to my controller and created custom UITableViewCell. Later, I've tried to run this code:
func tableView(educationTableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> educationCell {
let cell:educationCell = educationTableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! educationCell
print("TableView runs")
return cell
}
but I do not get my print in logs TableView runs. I do not understand what happens and why it doesn't run. Who knows, why this problem appears?
I read other answers in SO, but noone helps =/
need the return value of numberOfRowsInSection greater than 0
Just make sure you have implemented proper DataSource and Delegate for controller, number of rows is greater then 0
import UIKit
class MyViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
var items: [String] = ["We", "Heart", "Swift"]
#IBOutlet var tableView: UITableView! //hook this to your storyboard tableview
// MARK: - Controller life cycle stack
override func viewDidLoad() {
super.viewDidLoad()
//confirm table's delegate and data source programmatically
tableView.delegate = self;
tableView.dataSource = self;
}
//table view delegate and data source methods
func tableView(tableView:UITableView, numberOfRowsInSection section:Int) -> Int
{
//number of rows must be greater then 0 to get called "CellForRowAtIndex"
return self.items.count;
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCellWithIdentifier("cell") as! CraditCardCell
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
print("You selected cell");
}
}
One reason could be because you modified the return type to educationCell, instdead of the standard UITableViewCell. Try changing that.
I have asked this question once before however I feel like i haven't been as thorough as can be. I am attempting to complete a very standard drill down table view hierarchy programmatically rather than using the IB to avoid unnecessary scramble due to the fact i have well over 40 different views i want to implement. I have decided to use the following switch-statement:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
var VC: UITableViewController
switch indexPath.row {
case 0: VC = SecondTableViewController()
default: ()
}
navigationController?.pushViewController(VC, animated: true)
}
as you can see it gives me the non-initialized error, so i then proceed to make my variable an optional to fix this issue & it compiles and runs:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
var VC: UITableViewController?
switch indexPath.row {
case 0: VC = SecondTableViewController()
default: ()
}
navigationController?.pushViewController(VC!, animated: true)
}
however when i select the designated row (which is correct at the value of 0 after running under the debugger) it crashes with this error:
what seems to be the issue? is it the default statement within my switch? or is it the variable within my "pushViewController" method? Might i add, when i change the parameter within this method from "VC/VC!" to "UITableViewController()" like such:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
var VC: UITableViewController?
switch indexPath.row {
case 0: VC = SecondTableViewController()
default: ()
}
navigationController?.pushViewController(UITableViewController, animated: true)
}
it runs & functions accordingly, but when the view is pushed, it is not to the TableViewController i designated in my switch statement, rather then just a blank table view. what am i missing?
HERE IS THE CODE FOR MY SecondTableViewController :
import UIKit
class SecondTableViewController: UITableViewController {
var myVariable = ["LIST OF STRINGS IN AN ARRAY"]
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return myVariable.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath) as! UITableViewCell
var superVariable = myVariable [indexPath.row]
cell.textLabel!.text = superVariable
return cell
}
}
The problem lies in SecondTableViewController where you didn't define an identifier for your cell. You should do something like this,
class SecondTableViewController: UITableViewController {
let theData = ["one", "two", "three", "four"]
override func viewDidLoad() {
super.viewDidLoad()
tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "Cell")
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return theData.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! UITableViewCell
cell.textLabel?.text = theData[indexPath.row]
return cell
}
}
Since I use xCode 6 beta 5 UITableViews with nib files for custom cells shows only a small stripe of the cell on the left and the rest is grey. When I open up the View Debugger it says that there are thousands of _UITableViewCellSeperatorViews in my TableView.
Here is the class of the TableViewController
override func viewDidLoad() {
super.viewDidLoad()
let nib = UINib(nibName: "TestTableViewCell", bundle: nil)
tableView.registerNib(nib, forCellReuseIdentifier: "newTestCell")
}
override func numberOfSectionsInTableView(tableView: UITableView!) -> Int {
return 1
}
override func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
return 1
}
override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
let cell = tableView.dequeueReusableCellWithIdentifier("newTestCell", forIndexPath: indexPath) as TestTableViewCell
cell.loadData("Test")
return cell
}
Here is the class of the cell:
#IBOutlet weak var someLabel: UILabel!
func loadData(text: String) {
someLabel.text = text
}
Now I've got a picture of the TableView in the View Debugger:
This is indeed puzzling. Here is how I fixed it: just after registering the nib add
tableView.rowHeight = 44 // or whatever