I have a tableview with variable number of cells representing addon items. They are custom cells with a checkbox button which triggered to new ViewController.
How can I pass the Addon items which is displayed in cell on triggered the button?
I have tried to pass the cell number using tag property from the button but what about the data passing on button click.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("itemCell")as! ItemTableViewCell
cell.itemName.text = (items?[indexPath.row] as? [String:AnyObject])?["name"] as? String
cell.itemPrice!.text = "£\((items?[indexPath.row] as? [String:AnyObject])?["price"] as! String)"
itemAddon = (items![indexPath.row] as! [String:AnyObject])["addon"] as? String
cell.orderBtnOutlet.tag = indexPath.row
return cell
}
I have to pass itemname, itemPrice, and itemaddon to ItemTableViewCell based on its button click on each cell. How can I pass??
If you have access to button in your presented vc, you can access cell by let cell = button.superview as! ItemTableViewCell
Then you can access cell labels text.
But it is not good approach.
If you assigned button action in storyboard to present anothet virw controller, it anyway has segue. Assign it an identifier and in your tableviewcontroller override method prepareForSegue, where you can assign needed properies of targetVC
Related
I have an application wherein when tableview cell is clicked, another tableview is loaded and an api call is made. Based on the response from api, table view list is loaded and when a particular item in the second tableview is selected, there is a selected checkbox displayed just besides the tableview text label and at the same time database is updated with selected value,
so when I come back to the first tableview I display a label with selected item.
When the first tableview cell I clicked, api is called and results of api should be compared with the active list from database and that particular cell should remain selected.
When there is some item selected in first tableview and when i click on that particular cell, api results reload the tableview and selection for respective cell is not displayed.
Following is the code:
for selectedDict in (appDelegate?.selectedCategoryFilterArray)! {
let selectedUuid = selectedDict.categoryUuid
print("selectedUuid\(selectedUuid)")
for allDict in self.requestedFiltersArray!{
let allUuid = allDict.objectForKey("uuid") as? String
if selectedUuid == allUuid {
cell.imgSelected.image = UIImage(named: "radio_selected")
continue
}else{
cell.imgSelected.image = UIImage(named: "radio")
}
print("allUuid\(allUuid)")
}
}
This is not working as expected, no cell is displaying as selected even if their is a cell selected.
Where have you placed this code?
From what I think you might be trying to achieve, here is an approach that I would suggest.
For your second tableView which is loaded based on the API call results, I would add a String property called uuid to your custom UITableViewCell class.
Then when you call cellForRowAtIndexPath to populate your second tableView, instantiate each cell as your custom UITableViewCell and set its uuid property to the appropriate value based on the results array, using the indexPath.row.
After setting that, next you can run the for loop with your condition to match the cell's uuid property value against the selectedUuid value from your AppDelegate and thereafter set the image as per the logic.
A rough implementation:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier") as! YourCustomTableViewCell
let allDict = self.requestedFiltersArray[indexPath.row]
let allUuid = allDict.objectForKey("uuid") as? String
cell.uuid = allUuid
for selectedDict in (appDelegate?.selectedCategoryFilterArray)! {
let selectedUuid = selectedDict.categoryUuid
if selectedUuid = cell.uuid {
cell.imageSelected.image = UIImage(named: "radio_selected")
} else {
cell.imageSelected.image = UIImage(named: "radio")
}
}
}
I have two UITableViewCells and displaying them based on condition in
cellForRowatIndexPath. Both cells related to a creation of a post and than displaying them in UITableView.
In cellForRowAtIndexPath method i don't have any issues to use condition to display cell.
For example:
if postType[indexPath.row] == "Regular" {show this sell }
else {show another}`
This is working perfect. postType array is created during the post creation.
The issue that i have is to show a proper cell outside of cellForRowAtIndexPath method.
I have a button and when user click on it they would be going to the proper cell, just like they would click on the cell it self. However I don't know how to condition an array at proper indexPath or maybe there other way. I'm not that good because just starting out to learn swift.
I can do for a one cell but i want a condition first and than display a proper cell.
This statement works for a one cell.
#IBAction func usernameBtn_click(_ sender: AnyObject) {
let i = sender.layer.value(forKey: "index") as! IndexPath
let cell = tableView.cellForRow(at: i) as! postCell
}
In my case I have two cells. How to have a condition based on post type value in array and have a proper index inserted to check the value and than display a cell.
I have these two cells:
let cell = tableView.cellForRow(at: i) as! postCell
let cell = tableView.cellForRow(at: i) as! moreinfoCell
Any suggestion would be helpful.
You mention that the button does the same as if the user selects the cell so if you have that working just deselect "User Interaction Enable" of your button.
In interface builder:
Programmatically:
button.isUserInteractionEnabled = false
Doing that the touch will be done on the UITableViewCell and the didSelectRowAt indexPath: method will be fired.
I have created a tableview prototype cell in storyboard and I have added a button to cell and set its tag to indexpath.row. When I scroll my cells the scrolled cell on the top of tableview always set tag to zero instead of correct tag.
public func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier("autoLoadReuseIndentifier", forIndexPath: indexPath)
print("indexpath :\(indexPath.row)")
cell.contentView.viewWithTag(100)?.layer.cornerRadius = 5
tableView.separatorStyle = UITableViewCellSeparatorStyle.None
let tempDict : NSDictionary = savedCardsArray.objectAtIndex(indexPath.row) as! NSDictionary
let bankName = cell.contentView.viewWithTag(102) as! UILabel
deleteButton = cell.contentView.viewWithTag(106) as? UIButton
deleteButton?.tag = indexPath.row
deleteButton?.addTarget(self, action: "deleteCard1:", forControlEvents: UIControlEvents.TouchUpInside)
print("delete button:\(deleteButton)")
// print("indexpath delete tag :\(deleteButton.tag)")
if(self.isSetUpAutoloadSelected){
deleteButton?.hidden = true
}else{
deleteButton?.hidden = false
}
return cell;
}
Whenever I scroll the cells, delete button tag is always set to zero.
If you should go with other way so use follow code and get indexPath.
func deleteCard1(_ sender:deleteCard) {
let buttonPosition:CGPoint = sender.convert(CGPointZero, to:self.tableView)
let indexPath = self.tableView.indexPathForRow(at: buttonPosition)
}
I think you don't need to follow this approach because firstly you set button tag statically in storyboard and again you are change it's tag in cellforrowatindexpath so when you scroll, cell will never find button with tag 106.If you want to follow this approach then you need to create customButton and add Variable of type NSInteger or whatever you want and store indexpath.row into that variable of customButton.
Another Approach is Create CustomTableViewCell Class and create button outlet in this custom Cell class and set indexpath.row into button tag like this
CustomCellClassObject.buttonName.tag = indexPath.row
As Sumit said, it’s better to use a custom cell and create outlet for the buttons and labels, as fetching sub views using tags will be tough to maintain the code in the future.
Additionally, you don’t have to create the variable deleteButton, as I don’t see a valid purpose.
Assign tag to the button and add target in cellForRowAtIndexPath, it should work fine.
My TableView features custom Cells which have a button to display corresponding detailed info in another view.
This thread here got me started and I tried to implement the approach with the delegate inside the customCell:
How to access the content of a custom cell in swift using button tag?
What I want to achieve is that when I click on the button it reads the name of the cell and passes it on to the next controller. However it seems that I cannot pass the name with the delegate method and its field is nil.
How can I get the specific content of a cell when clicking on its button?
This is what I did so far:
In the class creating my own cell I set delegate:
protocol CustomCellDelegate {
func cellButtonTapped(cell: DemoCell)
}
(........)
var delegate: CustomCellDelegate?
#IBAction func buttonTapped(sender: AnyObject) {
delegate?.cellButtonTapped(self)
}
In the TableViewController I have the following:
override func tableView(tableView: UITableView, cellForRowAtIndexPath
indexPath: NSIndexPath) -> UITableViewCell {
let cell =
tableView.dequeueReusableCellWithIdentifier("FoldingCell",
forIndexPath: indexPath) as! DemoCell
cell.delegate = self
//TODO: set all custom cell properties here (retrieve JSON and set in cell), use indexPath.row as arraypointer
let resultList = self.items["result"] as! [[String: AnyObject]]
let itemForThisRow = resultList[indexPath.row]
cell.schoolNameClosedCell.text = itemForThisRow["name"] as! String
cell.schoolNameOpenedCell.text = itemForThisRow["name"] as! String
self.schoolIdHelperField = itemForThisRow["name"] as! String
cell.schoolIntroText.text = itemForThisRow["name"] as! String
//call method when button inside cell is tapped
cell.innerCellButton.addTarget(self, action: #selector(MainTableViewController.cellButtonTapped(_:)), forControlEvents: .TouchUpInside)
cell.school_id = itemForThisRow["name"] as! String
// cell.schoolIntroText.text = "We from xx University..."
return cell
}
And finally the target method when the button inside the cell is clicked
func cellButtonTapped(cell: DemoCell) {
print("the school id: ")
print(cell.schoolNameOpenedCell) //this line throws an error EXC_BAD_ACCESS 0x0
}
Firstly, the object innerCellButton is not a Cell, it's a button. The simple way to solve your problem is, just refer the index of the button. Please find the below method.
func cellButtonTapped(AnyObject: sender) {
let resultList = self.items["result"] as! [[String: AnyObject]]
//Get the tag value of the selected button.
//Button tag should be matching with the corresponding cell's indexpath.row
let selectedIndex = sender.tag
let itemForThisRow = resultList[selectedIndex]
print("the school id: \(itemForThisRow[\"name\"])")
}
* And set each button's tag as indexPath.row *
E.g.,
override func tableView(tableView: UITableView, cellForRowAtIndexPath
indexPath: NSIndexPath) -> UITableViewCell {
// Dequeue your cell and other code goes here.
// set the button's tag like below.
cell.innerCellButton.tag = indexPath.row
return cell
}
Close. I wouldn't use Suresh's method since it does not help find the IndexPath, which includes section and row.
First, I would recommend a model object for your table view data source. Learn more about the MVC pattern as well as parsing a JSON response to an object with mapping. However, this would give you the data you want.
func cellButtonTapped(cell: UITableViewCell) {
let indexPath = tableView.indexPathForCell(cell)
let resultList = self.items["result"] as! [[String: AnyObject]]
let itemForThisRow = resultList[indexPath.row]
let name = itemForThisRow["name"] as! String
}
I have one ui table view controller, that has four custom cells, each one of them has a custom ui table view cell.
now let's say i have added some buttons to the third custom ui table view cell, and i want to when one button of them clicked to access data (such as labels) that are in the second custom ui table view cell.
how can i do that?
this is a one example of the third custom ui table view cell
class thirdCellc: UITableViewCell {
//here i want to access data that are in another custom ui table view cell
}
keep on mind that i have also a custom ui table view controller like this:
class PageTwoViewController: UITableViewController {
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let rowNumber = indexPath.row
switch rowNumber {
case RequestData.numberOfPeople.rawValue:
let cell = tableView.dequeueReusableCellWithIdentifier(CellIdentefiers.numberOfPeopleCell.rawValue) as! NumberOfPeopleTableViewCell
return cell
case RequestData.dayOfMeal.rawValue :
let cell = tableView.dequeueReusableCellWithIdentifier(CellIdentefiers.dayCell.rawValue) as! DayTableViewCell
return cell
case RequestData.timeOfMeal.rawValue:
let cell = tableView.dequeueReusableCellWithIdentifier(CellIdentefiers.timeCell.rawValue) as! TimeTableViewCell
return cell
case RequestData.preferences.rawValue:
let cell = tableView.dequeueReusableCellWithIdentifier(CellIdentefiers.preferencesCell.rawValue) as! PreferencesTableViewCell
return cell
default:
return UITableViewCell()
}
}
}
you need to create an outlet from the tableView to the custom class, then you can write code as follows
#IBOutlet weak var tableView: UITableView! //outlet you created
let indexPath = NSIndexPath() //Get index Path of cell you want in tableView
let cell = tableView.cellforRowAtIndexPath(indexPath) as! FirstCell //Or whatever the other cell class was.
cell.textLabel.text //Now you have all the dot properties of whatever cell at indexPath you passed in.