Get section number in custom action of cell button
I have a tableView dynamically populated with custom cells in multiple sections.
In my CustomCell class, I have an @IBAction for a custom checkbox button in a cell. Is there a way to get the section number of the sender button in the IBAction function?
Something like:
@IBAction func checkboxButton(sender: CheckBox) {
//Change Button state
if sender.isChecked == true { sender.isChecked = false }
else { sender.isChecked = true }
//Get section number of clicked button
var sectionNumber = ???????
}
source to share
One way, suppose you have a custom cell and a button inside a cell ... Conventional model: (if you are using a table view with a data source) when setting up a cell inside:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
you can install:
cell.button.tag = sectionIndex
So in:
func checkboxButton(sender: CheckBox) { ...
sender.tag will be sectionIndex
Hope you have an idea.
source to share
You can easily find a string by calculating the position of the sender and finding the string at that position in UITableView
var position: CGPoint = sender.convertPoint(CGPointZero, toView: self.tableView)
if let indexPath = self.tableView.indexPathForRowAtPoint(position)
{
let section = indexPath.section
let row = indexPath.row
}
Here's how Apple does it in the accessories example. https://developer.apple.com/library/ios/samplecode/Accessory/Listings/AccessoryViewController_m.html#//apple_ref/doc/uid/DTS40008066-AccessoryViewController_m-DontLinkElementID_4
source to share
In Swift 3.0 some things have changed a bit, like "CGPointZero" → "CGPoint.zero" and "indexPathForRowAtPoint" → "indexPathForRow (at: position)" etc., so you can get the real string and section involved from this code :
let position: CGPoint = sender.convert(CGPoint.zero, to: self.tableView)
if let indexPath = self.tableView.indexPathForRow(at: position)
{
let section = indexPath.section
let row = indexPath.row
}
source to share
I recently came up with a solution to this problem using using Segues and implementing it in Swift 2.2 and XCode8.
I have a custom cell that I am using for a header with two labels and a UIButton. All my data is in an array and I want to access the data dynamically. Each section is an array of section headers and in this class the sections contain additional arrays to complete my tableView creation. My goal was to get the index of a section based on a button click in a custom cell (header) and change the data in another view.
To populate the tableView with my custom header cells, I used:
override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let myCell = tableView.dequeueReusableCellWithIdentifier("REUSABLE ID")! as! MyHeaderCell
let team = array[section]
myCell.teamName.text = team.name
myCell.projectName.text = team.project
myCell.addMemberButton.tag = section
return myCell
}
Using storyboard, the IBOutlet for the button (addMemberButton) in MyHeaderCell has a .tag field that I used to store the index of the section. So when I prepared the segue, I could use that value to dynamically access my array in the DataSource. Properly
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "segue1" {
...
}else if segue.identifier == "AddMemberSegue"{
let ix = sender?.tag
let destVC = segue.destinationViewController as! AddMemberViewController
self.myArray = array[ix!]
destVC.delegate = self
}else if segue.identifier == "segue3"{
...
}
}
Here the sender is the button, so the .tag field gives us the specific section index to access the correct location in the array
Hope this helps someone.
source to share
For finding indexPath in Swift 3 when calling a button
// First you add the target button to "cellForRowAt"
cell.myBtn.addTarget(self, action: #selector(self.btnAction(_:)), for: .touchUpInside)
// Add function
func btnAction(_ sender: UIButton) {
let point = sender.convert(CGPoint.zero, to: yourTableView as UIView)
let indexPath: IndexPath! = yourTableView.indexPathForRow(at: point)
print("indexPath.row is = \(indexPath.row) && indexPath.section is = \(indexPath.section)")
}
source to share