I was following a coding tutorial of making a simple app, everything looked and worked okay at first but after a while I ran into an error says:
use of unresolved identifier 'UITableViewCell'.
The tutorial's code worked fine in its video and I wrote the exact same code however it was an error on my computer. I guess it's the matter of different versions of Xcode.
Here is my code:
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.tableView.dataSource = self
self.tableView.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 6
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
**let cell = UITableviewCell()**
*//Where the error message is at. //*
return cell
}
}
The error message is at the line:
let cell = UITableViewCell()
I cannot comment on the answer posted by Stefan Salatic but you have to indeed use dequeable cells but to add to that, you should not forget to set the identifier in the main.storyboard to the CellIdentifier you used to create dequeable cell.
let cell = tableView.dequeueReusableCellWithIdentifier("Identifier", forIndexPath: indexPath) as UITableViewCell
In the storyboard go to the TableViewController -> Attribute Inspector -> Identifier and set it to:
Identifier
If you have an array of data you can fill the cell using:
cell!.textLabel?.text = data[indexPath.row]
You should dequeue UITableViewCells. Something like this
let cell = tableView.dequeueReusableCellWithIdentifier("CellIdentifier", forIndexPath: indexPath) as UITableViewCell
You want to reuse cells, not create a new one each time. This is the preferred way of doing it.
Related
I wanna populate a dynamic tableview inside a static tableview cell, by the same class for both of these.
As you can see in the picture under the cell 'GRE Test Information'.
I'm using the code inside the the class named as MenuController, which is a tableview controller.
class MenuController: UITableViewController,MFMailComposeViewControllerDelegate {
#IBOutlet weak var tablle: UITableView!
var items = [String]()
override func viewDidLoad() {
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()
items = ["A "," BB "]
tablle.delegate = self
tablle.dataSource = self
self.tablle.registerClass(MainTableViewCell.self, forCellReuseIdentifier: "cellNew")
}
// Table Data Source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 2
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath)
-> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cellNew", forIndexPath: indexPath) as! MainTableViewCell
print("Aasim Khaan")
cell.customCell01.text = items[indexPath.row]
return cell
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
But it's not populating that at runtime, and says
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'unable to dequeue a cell with identifier cellNew - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'
However I'm using the same identifier named as cellNew both in the code and storyboard.
Well after astonishing efforts regarding this one, I've found the solution.
Concerning the following:
Swift: TableView within Static UITableViewCell
Where the problem solver says : As far as I can determine by experimenting with this, you can't use the same UITableViewController as the data source and delegate of both table views. With a static table view, you're not supposed to implement the data source methods at all. The strange thing is, even if I disconnect the data source and delegate connections between my static table view and the table view controller, that table view still calls numberOfRowsInSection in my table view controller class. If I explicitly set the data source to nil in code, that stops it from calling the data source methods, but the embedded dynamic table view also fails to call them, so this structure doesn't work.
However, you can get around this by using a different object to be the data source and delegate of your embedded dynamic table view. Make an IBOutlet for your embedded table view, and set its data source and delegate to this new object (The class is DataSource in this example, and it's a subclass of NSObject).
I've modified my code in this way now :
import Foundation
import UIKit
import MessageUI
class DataSource: NSObject, UITableViewDataSource, UITableViewDelegate {
var items : [String] = ["GRE Test Structure ","GRE Score "]
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1;
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 2;
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cellNew", forIndexPath: indexPath) as! MainTableViewCell
cell.customCell01.text = items[indexPath.row]
return cell
}
}
class MenuController: UITableViewController,MFMailComposeViewControllerDelegate {
#IBOutlet var tablle0: UITableView!
#IBOutlet weak var tablle: UITableView!
var dataSource = DataSource()
override func viewDidLoad() {
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem =
self.editButtonItem()
tablle.delegate = dataSource
tablle.dataSource = dataSource
}
}
Now it works exactly fine.
in viewDidLoad
// First Register the UITableViewcell class from nib
let cellNib = UINib(nibName: "MainTableViewCell", bundle: bundle)
self.tableView.registerNib(cellNib, forCellReuseIdentifier:"cellNew")
Then Check with below screeshots
STEP 1: Select MainTableViewCell from Identity Inspector-Custom Class-Click Class Drop Down arrow.It shows you list.From that you can click the MainTableViewCell
STEP 2:Once you click that it shows the name with selected table view cell.
While the existing answers explain how you can do this, they don't address whether you should do this. From the example you provided, it seems that all you need is a single UITableView with multiple dynamic cell types. Each cell type can specify its contentInsets to indent the content as needed.
Terminating app due to uncaught exception
'NSInternalInconsistencyException', reason: 'unable to dequeue a cell
with identifier cellNew - must register a nib or a class for the
identifier or connect a prototype cell in a storyboard'
However I'm using the same identifier named as cellNew both in the
code and storyboard.
You're getting this error because you are dequeing/retrieving the prototype cell from the wrong table!
The line in your cellForRowAtIndexPath should be:
let cell = tablle.dequeueReusableCellWithIdentifier("cellNew", forIndexPath: indexPath) as! MainTableViewCell
Having said that, even once that is working, asking a tableViewController to act as data source and delegate for both a static and a dynamic table causes problems later.
I'm using Xcode 7.0, Swift 2
I'm basically trying to create a custom class that will build a UITable, then in the ViewController I make a new object of the table and load it into self.view;
The problem I'm having is that the function func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell isn't being called at all from within the custom class. I've been looking for a solution for 3 days now and I've tried rebuilding the App and code several times with no luck.
Please note, if I use the same code (that is everything required to build the table; excluding init functions, etc) in the ViewController.swift file, it works fine.
I know the problem is with the cellForRowAtIndexPath function because it will not print out the statement I set in that block of code when it runs. All other functions are called, but for some reason this isn't being called. Not sure if I overlooked something here. Any help would be appreciated. Thanks in advance.
class sideTest: NSObject, UITableViewDelegate, UITableViewDataSource {
let tesTable: UITableView = UITableView()
var items: [String]?
var mView: UIView = UIView()
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print("The number of rows is: \(self.items!.count)")
return self.items!.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
print("\nLets create some cells.")
let sCell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell!
sCell.textLabel?.text = self.items![indexPath.row]
sCell.textLabel?.textColor = UIColor.darkTextColor()
return sCell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
print("You selected cell #\(indexPath.row)!")
}
func tblSetup() {
self.tesTable.frame = CGRectMake(0, 0, 320, mView.bounds.height)
self.tesTable.delegate = self
self.tesTable.dataSource = self
self.tesTable.backgroundColor = UIColor.cyanColor()
// load cells
self.tesTable.registerClass(UITableViewCell.self, forCellReuseIdentifier: "Cell")
self.tesTable.reloadData()
print("Currenlty in tblSetup.\nCurrent rows is: \(self.items!.count)")
}
//Init
override init() {
super.init()
self.items = nil
self.tblSetup()
}
init(sourceView: UIView , itemListAsArrayString: [String]) {
super.init()
self.items = itemListAsArrayString
self.mView = sourceView
self.tblSetup()
}
}
Here is the code from ViewController.swift; Please do note that the table gets built, but the cells do not populate, even if I manually enter cell info by doing: sCell.textLabel?.text = "test cell"
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let myTable: sideTest = sideTest(sourceView: self.view, itemListAsArrayString: ["Cell 1", "Cell 2", "Cell 3"])
self.view.addSubview(myTable.tesTable)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Again, any help is greatly appreciated. Thanks.
Your view controller don't have a strong reference to your sideTest var.
Once your view did load finished,your sideTest is nil.Although you have a tableview(by add subview), but you no longer have a data source.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {}
is called after view did load. That cause the problem.
change your view controller to:
var tb :sideTest?
override func viewDidLoad() {
super.viewDidLoad()
let myTable: sideTest = sideTest(sourceView: self.view, itemListAsArrayString: ["Cell 1", "Cell 2", "Cell 3"])
print(myTable.tesTable.frame)
tb=myTable
self.view.addSubview(myTable.tesTable)
}
change your cellforrowatindexpath to:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
print("create cells")
var cell :UITableViewCell?
if let sCell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier("cell"){
cell=sCell
}else{
cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "cell")
}
cell!.textLabel?.text = self.items![indexPath.row]
cell!.textLabel?.textColor = UIColor.darkTextColor()
return cell!
}
this will fix most of the problems.
Your code:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let myTable: sideTest = sideTest(sourceView: self.view, itemListAsArrayString: ["Cell 1", "Cell 2", "Cell 3"])
self.view.addSubview(myTable.tesTable)
}
I would think that the myTable variable goes out of scope and is released when viewDidLoad finishes, so there is no data source or delegate after that. Did you verify that the self.view.addSubview(myTable.tesTable) retains it? Try moving declaration of myTable outside of the function level (to property level) or add a diagnostic print to deinit..
I am new to Swift, and iOS development in general. I am attempting to create a custom UITableViewCell. I have created the cell in my main storyboard on top of a UITableView that is inside a UIViewController. When I loaded one of the default cells, I was able to populate it with data. However, now that I am using a custom cell, I cannot get any data to appear in the table. I have gone through all kinds of tutorials and questions posted on the internet, but I can't figure out why it is not working. Any help would be appreciated.
Here is my code for the UIViewController that the tableview resides in.
import UIKit
class FirstViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tblView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
//self.tblView.registerClass(UITableViewCell.self, forCellReuseIdentifier : "Cell")
self.tblView.registerClass(CustomTableViewCell.self, forCellReuseIdentifier : "Cell")
tblView!.delegate = self
tblView!.dataSource = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataMgr.data.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell : CustomTableViewCell = self.tblView.dequeueReusableCellWithIdentifier("Cell", forIndexPath : indexPath) as! CustomTableViewCell
var values = dataMgr.data[indexPath.row]
cell.newTotalLabel?.text = "\(values.newTotal)"
cell.winLoseValueLabel?.text = "\(values.newTotal - values.currentTotal)"
cell.dateLabel?.text = "5/17/2015"
return cell
}
}
I have stepped through the program where it is assigning values to the cell variables. The variable 'values' is being populated with data, but when stepping over the assignment lines to the cell variables, I found that they are never assigned. They all remain nil.
When you make a custom cell in the storyboard, don't register the class (or anything else). Just be sure to give the cell the same identifier in the storyboard that you pass to dequeueReusableCellWithIdentifier:forIndexPath:.
I'm trying to use UITableViewDataSource in my application.But when I add to UITableViewDataSource to viewControllerClass
This is my code
class SecondViewController: UIViewController,UITableViewDataSource{
And there is error what I am getting
'SecondViewController' does not conform to protocol 'UITableViewDataSource'
self.messageTableView!.registerNib(UINib(nibName: "MessageCell", bundle: nil), forCellReuseIdentifier: "MessageCell")
self.messageTableView!.rowHeight = UITableViewAutomaticDimension;
self.messageTableView!.estimatedRowHeight = 44.0;
self.messageTableView!.keyboardDismissMode = .Interactive
self.view.addSubview(self.messageTableView!)
I reconstructed your code except for the custom message cell and it compiled. I noticed that the improper use of ! in the two required functions for the UITableView will give that message. If you click on the error message (marked in red) it will display additional error messages in the lines causing the problem. Start by removing the ! and sometimes the compile will provide a correctionI also saw on another stack overflow that there was change between 6 and 6.1. I am using 6.1. ([iOS : 'MyViewController' does not conform to protocol 'UITableViewDataSource')
class SecondViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
var messages = ["A", "B", "C"]
#IBOutlet var tableView: UITableView?
override func viewDidLoad() {
super.viewDidLoad()
tableView!.dataSource = self
tableView!.delegate = self
self.tableView!.registerNib(UINib(nibName: "MessageCell", bundle: nil), forCellReuseIdentifier: "MessageCell")
self.tableView!.rowHeight = UITableViewAutomaticDimension;
self.tableView!.estimatedRowHeight = 44.0;
self.tableView!.keyboardDismissMode = .Interactive
self.view.addSubview(self.tableView!)
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return messages.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
var cell:UITableViewCell=tableView.dequeueReusableCellWithIdentifier("MessageCell") as UITableViewCell
var msg=self.messages[indexPath.row]
//cell.configureWithMessage(msg)
return cell
}
}
You have to implement the non optional functions of the protocol, which are:
tableView:numberOfRowsInSection
tableView:cellForRowAtIndexPath
I've searched around for an answer to this one but haven't had any success. I am essentially following a tutorial to create a simple todo app, many other's are commenting with the same error as below. The author doesn't have a solution yet. Any help would be appreciated.
I'm getting the error: 'UITableViewCell?' does not have a member named 'textLabel'
Here's my code so far:
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
// tells iphone what to put in each cell
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 4
}
// Tells iphone how many cells ther are
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
cell.textLabel?.text = "table cell content"
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.
}
}
I am following the same tutorial, so I can feel your pain! :) In the tutorial the fellow has you delete and recreate the view controller, only then he forgets to mention that you need to name your view controller again. Any way, to save some aggravation, just create a new project, drop a Table View into the view controller, right click on the Table View, and link dataSource, delegate, and view to the View Controller.
Next, here is the code that works for me as of XCode 6.1. God knows what they are going to change next. But in short, you don't need the '?' after textLabel.
import UIKit
class ViewController: UIViewController, UITableViewDelegate {
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.
}
var items = ["test 1", "test 2", "test 3", "test 4"]
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 4
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
let cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "cell")
cell.textLabel.text = self.items[indexPath.row]
return cell
}
}
Hope that helps.
I had to fight with the same / a similar issue today. It happens because you are trying to use custom cells in a standard table view controller. You need to tell the controller in the function that the cell with its custom name should be used as the (= instead of the) TableViewCell. Then Xcode will know where to look for the names.
So right after the closing braces for the indexPath you type:
as! TableViewCell
Try this:
var cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
cell.textLabel?.text = "table cell content"
return cell!
This should do the trick
cell?.textLabel?.text = array[indexPath.row]
I'm assuming you are using 6.1 as this is not an issue in 6.0.1, but they have changed things once again in the latest release.
Hope this works for you