I want to add a cell into my tableview to the last row using another UserInterface.The code is like this.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:JoinCell = tableView.dequeueReusableCellWithIdentifier(reuseIdentifier, forIndexPath: indexPath) as! JoinCell
let lastSectionIndex = tableView.numberOfSections-1
let lastSectionLastRow = tableView.numberOfRowsInSection(lastSectionIndex) - 1
let lastIndexPath = NSIndexPath(forRow:lastSectionLastRow, inSection: lastSectionIndex)
let cellIndexPath = tableView.indexPathForCell(cell)
if cellIndexPath == lastIndexPath {
cell = tableView.dequeueReusableCellWithIdentifier("JoinFooterCell") as! JoinFooterCell
}
I got error message "Cannot assign value of type 'JoinFooterCell' to type 'JoinCell'"
Does anyone can give me advise? Thanks.
Do this and for datasource.sections.count use the same value you return in numberOfSectionInTableView() and for datasource.rows.count use the same value you return in your numberOfRowsForSection()
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if datasource.sections.count - 1 == indexPath.section && datasource.rows.count - 1 == indexPath.row {
let cell = tableView.dequeueReusableCellWithIdentifier("JoinFooterCell") as! JoinFooterCell
return cell
} else {
let cell = tableView.dequeueReusableCellWithIdentifier(reuseIdentifier, forIndexPath: indexPath) as! JoinCell
return cell
}
}
Do something like this
let lastSectionIndex = tableView.numberOfSections-1
let lastSectionLastRow = tableView.numberOfRowsInSection(lastSectionIndex) - 1
let lastIndexPath = NSIndexPath(forRow:lastSectionLastRow, inSection: lastSectionIndex)
let cellIndexPath = tableView.indexPathForCell(cell)
var cell
if cellIndexPath == lastIndexPath {
cell = tableView.dequeueReusableCellWithIdentifier("JoinFooterCell") as! JoinFooterCell
}
else {
cell = tableView.dequeueReusableCellWithIdentifier(reuseIdentifier, forIndexPath: indexPath) as! JoinCell
}
What actually am trying to do is create cell which you want to return. Don't initialize the cell first and then try to re assign. First determine whether its the last cell and based on that, initialize the kind of cell you want.
Let try this:
var cell: UITableViewCell!
if cellIndexPath == lastIndexPath {
cell = tableView.dequeueReusableCellWithIdentifier("JoinFooterCell") as! JoinFooterCell
} else {
cell = tableView.dequeueReusableCellWithIdentifier(reuseIdentifier, forIndexPath: indexPath) as! JoinCell
}
return cell
Related
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) at the 4th indexpath.row. What i have is a section on the storyboard which is one cell that i want to add at the 4th 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
}
So if there is 10 items in section one when it reach indexpath.row 4 it should insert another section then continue with the other items from section one.
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
}
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 running into some problems today in my application. I'm using a UITableView to present different cells some contain a specific button, some display a game your currently in, some are just for spacing between cells.
However im running into some problems when I do tableView.reloadData().
When I click on 'new game' a new game cell should be added, but instead of that the last cells are moved down (like expected, because something comes in between), however the upper cells that should change, they don't. I expect this to be because of reusing (or "caching"). Maybe someone can help me out on how to fix this.
Here is an image of what is happening explanation
Now I have different cells, all with their own Identifiers for example: "Emptycell", "Gamecell", "startnewgameBtnCell". I do this because I create each cell in storybuilder.
here is my code for cellForRowAtIndexPath
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = UITableViewCell()
let identifier = cell_identifiers[indexPath.row][0] as! String
if ((cell_identifiers[indexPath.row][1] as! String) == "MYTURN" ) {
var cell = tableView.dequeueReusableCellWithIdentifier(identifier, forIndexPath: indexPath) as! GameViewCell
let match = self.myTurnMatches[indexPath.row - 4]
setupGameViewCellObject(match)
}
if ((cell_identifiers[indexPath.row][1] as! String) == "NOT" ) {
var cell = tableView.dequeueReusableCellWithIdentifier(identifier, forIndexPath: indexPath) as! FirstMenuTableViewCell
}
return cell
In this code I check if its a gamecell or not, emptycells or cells that contain a label or button are all FirstMenuTableViewCell. Only GameCell have their own class GameViewCell.
I have also double checked to see if my identifiers are build up correctly and they are.
Maybe someone can explain me exactly whats happening and what might be the correct approach to solve the situation I'm in, I think I may not fully understand how to use UITableViewCell with custom cells.
Thanks for reading
You create new variables called cell in the if statements. You are hiding the outer cell.
Use one cell variable.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell: UITableViewCell
let identifier = cell_identifiers[indexPath.row][0] as! String
if ((cell_identifiers[indexPath.row][1] as! String) == "MYTURN" ) {
cell = tableView.dequeueReusableCellWithIdentifier(identifier, forIndexPath: indexPath) as! GameViewCell
let match = self.myTurnMatches[indexPath.row - 4]
setupGameViewCellObject(match)
}
if ((cell_identifiers[indexPath.row][1] as! String) == "NOT" ) {
cell = tableView.dequeueReusableCellWithIdentifier(identifier, forIndexPath: indexPath) as! FirstMenuTableViewCell
}
return cell
}
Try update your code:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = UITableViewCell()
let identifier = cell_identifiers[indexPath.row][0] as! String
if ((cell_identifiers[indexPath.row][1] as! String) == "MYTURN" ) {
var cell = tableView.dequeueReusableCellWithIdentifier(identifier, forIndexPath: indexPath) as! GameViewCell
let match = self.myTurnMatches[indexPath.row - 4]
setupGameViewCellObject(match)
return cell
}
if ((cell_identifiers[indexPath.row][1] as! String) == "NOT" ) {
var cell = tableView.dequeueReusableCellWithIdentifier(identifier, forIndexPath: indexPath) as! FirstMenuTableViewCell
return cell
}
return cell
if me, i coded:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let identifier = cell_identifiers[indexPath.row][0] as! String
if ((cell_identifiers[indexPath.row][1] as! String) == "MYTURN" ) {
let cell = tableView.dequeueReusableCellWithIdentifier(identifier, forIndexPath: indexPath) as! GameViewCell
let match = self.myTurnMatches[indexPath.row - 4]
setupGameViewCellObject(match)
return cell
}else { // if you sure just have 2 cell type
let cell = tableView.dequeueReusableCellWithIdentifier(identifier, forIndexPath: indexPath) as! FirstMenuTableViewCell
return cell
}
}
But i think you should use section in tableview,it is better. So, you have 3 section, and 2 headerofsection in there. the first section have 1 row, the second have self.myTurnMatches.count row.... :
override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
if section == 0 || section == 1{
return 44
}else{
return 0
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if indexPath.section == 1{
let cell = tableView.dequeueReusableCellWithIdentifier("GameViewCell 's identifier", forIndexPath: indexPath) as! GameViewCell
let match = self.myTurnMatches[indexPath.row - 4]
setupGameViewCellObject(match)
return cell
}else{
let cell = tableView.dequeueReusableCellWithIdentifier("FirstMenuTableViewCell 's identifier", forIndexPath: indexPath) as! FirstMenuTableViewCell
return cell
}
}
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
}