简体   繁体   中英

Get section number in custom cell button action

I have a tableView dynamically populated with custom cells in several sections.

In my CustomCell class I have an @IBAction for a custom checkbox button in the 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 = ???????

}

You can easily find the row by calculating the position of the sender and finding the row at that position in the 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
}

This is how Apple does it in the Accessory sample. https://developer.apple.com/library/ios/samplecode/Accessory/Listings/AccessoryViewController_m.html#//apple_ref/doc/uid/DTS40008066-AccessoryViewController_m-DontLinkElementID_4

In Swift 3.0, some things are slightly changed like 'CGPointZero' - > 'CGPoint.zero' & 'indexPathForRowAtPoint' -> 'indexPathForRow(at:position)' etc so you can get the real row and section of the tapped button 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

        }

For find indexPath in Swift 3 and Swift 4 when calling button,

// First you Add target on button in "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)")
}

One of the ways, suppose you have custom cell and button inside a cell ... Usual pattern would be: (if you're using table view with datasource) when configuring the cell inside:

- (UITableViewCell *)tableView:(UITableView *)tableView
     cellForRowAtIndexPath:(NSIndexPath *)indexPath

you can set:

cell.button.tag = sectionIndex

So in:

func checkboxButton(sender: CheckBox) { ...

sender.tag would be sectionIndex

Hope you got the idea.

I have recently come with a solution to this problem leveraging the use of Segues and implementing it in Swift 2.2 and XCode8.

I have a Custom Cell that I'm using for a header that has 2 Labels and a UIButton. All of my data is in an array and I want to dynamically access the data. Each section is an array of section headers and within that class the sections contain additional arrays to finish generating my tableView. My goal was to get the Index of the section based on a button click in the custom cell (header) and change the data in a different 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 the storyboard, the IBOutlet for the button (addMemberButton) in MyHeaderCell had the .tag field which I used to save the section index. So when I prepared segue I could use this value to dynamically access my array in the DataSource. As follows

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM