I want to identify many custom cell in table view "i build them in storyboard " but the are error ask from me to return value , i am trying to return nil and int value and cell but the error be same
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if indexPath == 0 {
let cell = tableView.dequeueReusableCellWithIdentifier("CheefsCell", forIndexPath: indexPath) as UITableViewCell
cell.accessoryType = .DisclosureIndicator
return cell }
else if indexPath == 1 {
let cell = tableView.dequeueReusableCellWithIdentifier("BeautyCell", forIndexPath: indexPath) as UITableViewCell
cell.accessoryType = .DisclosureIndicator
return cell }
else if indexPath == 2 {
let cell = tableView.dequeueReusableCellWithIdentifier("StudentServicesCell", forIndexPath: indexPath) as UITableViewCell
cell.accessoryType = .DisclosureIndicator
return cell }
else if indexPath == 3 {
let cell = tableView.dequeueReusableCellWithIdentifier("ArtAndDesigneCell", forIndexPath: indexPath) as UITableViewCell
cell.accessoryType = .DisclosureIndicator
return cell }
else if indexPath == 4 {
let cell = tableView.dequeueReusableCellWithIdentifier("StoreCell", forIndexPath: indexPath) as UITableViewCell
cell.accessoryType = .DisclosureIndicator
return cell }
else if indexPath == 5 {
let cell = tableView.dequeueReusableCellWithIdentifier("OthersCell", forIndexPath: indexPath) as UITableViewCell
cell.accessoryType = .DisclosureIndicator
return cell }
return
}
update ::
git hub link /
The method cellForRowAtIndexPath requires to return a non-optional UITableViewCell, so you must ensure to return a cell in any case. A simple return or return nil is not allowed.
The code can be simplified, most of it is redundant. The only difference is the identifier.
A suitable solution is a switch statement on the row property of the indexpath.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var identifier : String
switch indexPath.row {
case 0: identifier = "CheefsCell"
case 1: identifier = "BeautyCell"
case 2: identifier = "StudentServicesCell"
case 3: identifier = "ArtAndDesigneCell"
case 4: identifier = "StoreCell"
default: identifier = "OthersCell"
}
let cell = tableView.dequeueReusableCellWithIdentifier(identifier, forIndexPath: indexPath)
cell.accessoryType = .DisclosureIndicator
return cell
}
You're getting an error cause you're not returning a cell from the method.
Change your code so it always returns a cell.
When checking indexPaths, use their row property - indexPath.row.
Consider replacing your if-else tree with switch.
Another example based on #vadian's answer:
static let identifiers = [ "CheefsCell", "BeautyCell", "StudentServicesCell", "ArtAndDesigneCell", "StoreCell" ]
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let identifier = (indexPath.row < count) ? identifiers[ indexPath.row ] : "OthersCell"
var cell = tableView.dequeueReusableCellWithIdentifier(identifier, forIndexPath: indexPath)
if cell == nil {
cell = UITableViewCell() // allocate a new cell here
}
cell.accessoryType = .DisclosureIndicator
// configure your cell here
return cell
}
Related
How can I return a TableViewcell in cellForRowAtIndexPath delegate method , if I m using multiple UITableView in a Single ViewController, One TableView has Custom UITableViewCell and the other has default UITableViewCell . My problem is I m not able to cast the UITableViewCell to Custom TableViewCell type .
Code used as follows ,
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:UITableViewCell?
if tableView == self.tvCity {
var cell:UITableViewCell?
cell = tableView.dequeueReusableCellWithIdentifier(cityCellIdentifier, forIndexPath: indexPath) as UITableViewCell
let row = indexPath.row
cell!.textLabel?.text = self.cityList[row].cityEn
}
if tableView == self.tvBranchByCity {
var cell:BranchNearMeTableViewCell?
cell = (tableView.dequeueReusableCellWithIdentifier(branchCellIdentifier, forIndexPath: indexPath) as! BranchNearMeTableViewCell)
let row = indexPath.row
cell.branchName = self.branchList[row].name// here cell.branchName is not accessible.
}
return cell!
}
Please advise . Thanks in advance.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if tableView == self.tvCity {
var cell:UITableViewCell?
cell = tableView.dequeueReusableCellWithIdentifier(cityCellIdentifier, forIndexPath: indexPath) as UITableViewCell
let row = indexPath.row
cell!.textLabel?.text = self.cityList[row].cityEn
return cell!
}
if tableView == self.tvBranchByCity {
var cell:BranchNearMeTableViewCell?
cell = (tableView.dequeueReusableCellWithIdentifier(branchCellIdentifier, forIndexPath: indexPath) as! BranchNearMeTableViewCell)
let row = indexPath.row
cell.branchName = self.branchList[row].name as! String // here cell.branchName is not accessible.
return cell!
}
}
Differentiate tables with tag
see example :
if tableView.tag == 2000
{
identifier = "First Table"
let cell = tableView.dequeueReusableCellWithIdentifier(identifier, forIndexPath: indexPath)
return cell
}
else
{
identifier = "Second Table"
let cell = tableView.dequeueReusableCellWithIdentifier(identifier, forIndexPath: indexPath)
return cell
}
Hello In my TableViewController I need first three cells static and then dynamic cells. I have done some research and came up that I can do static cells in dynamic table Prototype but not vice versa.
So I drag a tableViewController and choose dynamic prototype and added 4 Prototype Cells(3-static cells. and 1 dynamic) and give each four of them different identifiers and also added the class TableViewCell to all four of them. I have created one TableViewCell class also.
right now I am getting this error
fatal error: unexpectedly found nil while unwrapping an Optional value
Here is my code
let NUMBER_OF_STATIC_CELLS = 3
var labels = ["label1","label2","label3"]
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return labels.count + 1
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell: TestViewCell!
print(indexPath.row)
if (indexPath.row == 0) {
cell = tableView.dequeueReusableCellWithIdentifier("static1", forIndexPath: indexPath) as! TestViewCell
}
if (indexPath.row == 1) {
cell = tableView.dequeueReusableCellWithIdentifier("static2", forIndexPath: indexPath) as! TestViewCell
//cell.cardSetName?.text = self.cardSetObject["name"] as String
}
if (indexPath.row == 2) {
cell = tableView.dequeueReusableCellWithIdentifier("static2", forIndexPath: indexPath) as! TestViewCell
//cell.cardSetName?.text = self.cardSetObject["name"] as String
}
cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! TestViewCell
cell.testLabel.text = "row \(indexPath.row)" // return test rows as set in numberOfRowsInSection
return cell; //getting error here
}
UPDATE
okay error has been removed. Now I come up another problem. I want to know if there are total 4 rows. 3 are static and then rest of them will be dynamic. what would be total number of rows then. I am doing this
labels.count+2 //2 static cells(0 1 2 )
But I am getting fatal error: Array index out of range
You have no code to return a cell if the row is 4 or more. Change this:
if (indexPath.row == 3) {
to this:
if (indexPath.row >= 3) {
Or just change it to:
else {
your code above has some of errors:
when indexPath.row == 2 it should be "static 3".
put the last line of the code that defines the "cell" inside an else statement, to stop it from always executing. When you have done that, it should work.
like this:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell: TestViewCell!
if (indexPath.row == 0) {
cell = tableView.dequeueReusableCellWithIdentifier("static1", forIndexPath: indexPath) as! TestViewCell
}
if (indexPath.row == 1) {
cell = tableView.dequeueReusableCellWithIdentifier("static2", forIndexPath: indexPath) as! TestViewCell
}
if (indexPath.row == 2) {
cell = tableView.dequeueReusableCellWithIdentifier("static3", forIndexPath: indexPath) as! TestViewCell
}
else{
cell = tableView.dequeueReusableCellWithIdentifier("dynamic\(indexPath.row-2)", forIndexPath: indexPath) as! TestViewCell
}
cell.testLabel.text = "row \(indexPath.row)"
return cell
}
Having a little problem with tableviews. I want to add a section to the tableview without messing with the content of the other data in the table. I want to add (cell3, thiscell) after every 2 indexpath.row
What i have is a section on the storyboard which is one cell that i want to add after every 2 index path without messing with all the other information. How would i use the insert section function? or is there any other way to do it?
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// Table view cells are reused and should be dequeued using a cell identifier.
if indexPath.section == 0 && cell1 == true{
let cellIdentifier = “cell1"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! SubCategoryTableViewCell
cell.nameLabel.text = “cell1"
cell.subNameLabel.text = ""
return cell
} else if indexPath.section == 2 && vally == true{
let cellIdentifier = "cell2"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! SubCategoryTableViewCell
cell.nameLabel.text = “Smiles"
cell.subNameLabel.text = ""
return cell
} else if indexPath.row == 2 {
let cellIdentifier = “cell3"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! thisCell
print("add this after indexpath 2")
return cell
} else if indexPath.section == 1 {
let cellIdentifier = "SubCategoryTableViewCell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! SubCategoryTableViewCell
cell.loading.hidden = false
cell.loading.startAnimating()
cell.nameLabel.text = subCat[indexPath.row].subCategoryName
cell.subNameLabel.text = subCat[indexPath.row].subCategoryDesc
return cell
}
let cell2: SubCategoryTableViewCell = tableView.dequeueReusableCellWithIdentifier("SubCategoryTableViewCell", forIndexPath: indexPath) as! SubCategoryTableViewCell
cell2.userInteractionEnabled = false
return cell2
}
You want to display for cell3 for indexPath.row = 2 in all sections or any specific section?
In case if you want to display in all sections:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// Table view cells are reused and should be dequeued using a cell identifier.
if(indexPath.row == 2){
let cellIdentifier = "cell3"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! thisCell
print("add this after indexpath 2")
return cell
}
else if indexPath.section == 0 && cell1 == true{
let cellIdentifier = "cell1"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! SubCategoryTableViewCell
cell.nameLabel.text = “cell1"
cell.subNameLabel.text = ""
return cell
} else if indexPath.section == 2 && vally == true{
let cellIdentifier = "cell2"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! SubCategoryTableViewCell
cell.nameLabel.text = “Smiles"
cell.subNameLabel.text = ""
return cell
} else if indexPath.section == 1 {
let cellIdentifier = "SubCategoryTableViewCell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! SubCategoryTableViewCell
cell.loading.hidden = false
cell.loading.startAnimating()
cell.nameLabel.text = subCat[indexPath.row].subCategoryName
cell.subNameLabel.text = subCat[indexPath.row].subCategoryDesc
return cell
}
let cell2: SubCategoryTableViewCell = tableView.dequeueReusableCellWithIdentifier("SubCategoryTableViewCell", forIndexPath: indexPath) as! SubCategoryTableViewCell
cell2.userInteractionEnabled = false
return cell2
}
And above code will add new cell cell3 in each section at indexPath.row -> 2
The indexPath.row value is intended to match indexes your underlying array of supporting data. Presenting additional "virtual" cells in place of rows does not add them, it merely shows a different cell at the corresponding row.
You have two choices:
1) take into account the progressive offset that your "in-between" cells create in the subCat[row] and the IndexPath.row.
2) use actual sections and segment and mat pairs of entries to indexPath.row 0 and 1 in each section.
For #1, you could create a pair of mapping functions and use them to convert indexPath.row to and from indexes in subCat[]
func indexFromRow(row:int) -> int?
{ return row % 3 == 2 ? nil : row - row/3 }
func rowFromIndex(index:Int) -> Int
{ return index + index/2 }
Then, when returning you cell, you can use the functions to establish the correspondance between rows and indexes:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
if let subCatIndex = indexFromRow(indexPath.row)
{
// build a SubCategoryTableViewCell cell, feed it with subCat[subCatIndex] data and return it
}
else
{
// build a thisCell cell and return it
}
}
you will also need to adjust the number of rows returned for the section to make room for the intermediate cells
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{ return rowForIndex(subCat.count-1) + 1 }
Everywhere in you code where you receive an IndexPath and need to know the index in subCat[], you'll need to use the rowToIndex() function
When you want to know the index path of an item in subCat[] at a given index, you'll have to us indexToRow() to build the indexPath
For #2, you will have to use a similar technique to map indexPath.row and indexes in subCat[], but you'll also have to deal with sections and I don't think you can use a reusable cell for section headers.
I'm struggling with grouped dynamic table view. I want to have 2 groups. Basically, in first group I want to have customers data and on second one orders. First group will have always same number of rows. Any what is my problem - I want to put text field into each row of first section (with different placeholder) but when I run application, textfield is only in last row. Does anybody know what Im doing wrong? Thank you
Declaration of my properties
var textField = UITextField()
var udaje = ["Jméno zákazníka","Kontaktní osoba","Telefon","Email","Fakturační adresa","Dodací adresa","IČO/DIČ"]
TableViewController.swift:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = UITableViewCell()
if (indexPath.section == 0) {
let cell = tableView.dequeueReusableCellWithIdentifier("udajeCell", forIndexPath: indexPath) as! UITableViewCell
self.textField.frame = cell.contentView.frame
self.textField.placeholder = self.udaje[indexPath.row]
cell.contentView.addSubview(textField)
} else if (indexPath.section == 1) {
let cell = tableView.dequeueReusableCellWithIdentifier("pilyCell", forIndexPath: indexPath) as! UITableViewCell
cell.textLabel?.text = "Přidat pilu"
cell.detailTextLabel?.text = "+"
}
return cell
}
try this way code:
your problem is use use the self.textField. not self.textField use cell.textField.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = UITableViewCell()
if (indexPath.section == 0) {
let cell = tableView.dequeueReusableCellWithIdentifier("udajeCell", forIndexPath: indexPath) as! UITableViewCell
cell.textField.frame = cell.contentView.frame
cell.textField.placeholder = self.udaje[indexPath.row]
cell.contentView.addSubview(textField)
} else if (indexPath.section == 1) {
let cell = tableView.dequeueReusableCellWithIdentifier("pilyCell", forIndexPath: indexPath) as! UITableViewCell
cell.textLabel?.text = "Přidat pilu"
cell.detailTextLabel?.text = "+"
}
return cell
}
I want to put 2 custom cell in TableView, but I have a small problem with it. I tried to find answer in Google and StackOverflow, but answers can't help me.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if indexPath.row == 0{
var cell: CustomCell = tableView.dequeueReusableCellWithIdentifier("FistCustomTableViewCell", forIndexPath: indexPath) as CustomCell
//set cell2
}
if indexPath.row >= 1{
var cell: CustomCell = tableView.dequeueReusableCellWithIdentifier("CustomTableViewCell", forIndexPath: indexPath) as CustomCell
let cons = aArray[indexPath.row - 1]
// set cell2
}
return cell // (!) Use of unresolved identifier "cell"
}
You need to draw the cell declaration outside:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell: CustomCell!
if indexPath.row == 0{
cell = tableView.dequeueReusableCellWithIdentifier("FistCustomTableViewCell", forIndexPath: indexPath) as CustomCell
//set cell2
}
if indexPath.row >= 1{
cell = tableView.dequeueReusableCellWithIdentifier("CustomTableViewCell", forIndexPath: indexPath) as CustomCell
let cons = aArray[indexPath.row - 1]
// set cell2
}
return cell
}
You have to declare the cell out of the if statement.