2
votes

I am making a table view in Swift which each cell contains a button. When a button is tapped, a popover will display on that button.

My Problem is, no matter which cell I click the button inside, popover always display on the first cell.

Please see attached images for more understanding.

table popover

Below is my code in tableviewcontroller class. I use tag to detect touching on the button.

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        // Table view cells are reused and should be dequeued using a cell identifier.
        let cellIdentifier = "Cell01"
        let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as? UICell01
        //when tap share button
        cell!.shareButton.tag = indexPath.row
        cell!.shareButton.addTarget(self, action: "shareAction:", forControlEvents: .TouchUpInside)    
        return cell!
    }






    @IBAction func shareAction(sender: UIButton)    {
        //Create Action Sheet to be menu
        let alert:UIAlertController = UIAlertController(title: "Share on", message: nil, preferredStyle: UIAlertControllerStyle.ActionSheet)
        let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel)
        {
            UIAlertAction in
        }
        // Add the actions
        alert.addAction(cancelAction)

        // Present the controller
        if UIDevice.currentDevice().userInterfaceIdiom == .Phone
        {
            self.presentViewController(alert, animated: true, completion: nil)
        }
        else    //iPad
        {
             var popover:UIPopoverController?=nil
            popover = UIPopoverController(contentViewController: alert)
            popover!.presentPopoverFromRect(sender.frame, inView: self.view, permittedArrowDirections: UIPopoverArrowDirection.Any, animated: true)
        }

I think the problem is at the last line. "sender" that is passed to function is the button in the first cell only. How do I solve the problem?

4

4 Answers

0
votes

You are referencing sender.frame relative to its own cell, and not incorporating the cell's frame relative to the UITableView. Check sender's superview.

0
votes

Try to declare the shareAction inside a customer UITableViewCell class and assing it to the cell. Like below

import UIKit

class CellCustome: UITableViewCell {


    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    @IBAction func shareAction(sender: UIButton)    {
        //Create Action Sheet to be menu
        let alert:UIAlertController = UIAlertController(title: "Share on", message: nil, preferredStyle: UIAlertControllerStyle.ActionSheet)
        let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel)
        {
            UIAlertAction in
        }
        // Add the actions
        alert.addAction(cancelAction)

        // Present the controller
        if UIDevice.currentDevice().userInterfaceIdiom == .Phone
        {
            self.presentViewController(alert, animated: true, completion: nil)
        }
        else    //iPad
        {
            var popover:UIPopoverController?=nil
            popover = UIPopoverController(contentViewController: alert)
            popover!.presentPopoverFromRect(sender.frame, inView: self.view, permittedArrowDirections: UIPopoverArrowDirection.Any, animated: true)
        }

    }

    override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}
0
votes

Thanks all for enlighten me.

I can simply solve by changing the last line to

popover!.presentPopoverFromRect(sender.frame, inView: sender.superview!, permittedArrowDirections: UIPopoverArrowDirection.Any, animated: true)

Now the popover balloon displays on the correct button I touch.

But I still do not quite understand the inView argument.

If it is self.view, the popover balloon displays on the first cell. if is is sender.superview, the popover balloon displays on the correct cell.

0
votes

Update for Swift4:

In the View Controller:

popover?.sourceView = sender.superview
popover?.sourceRect = sender.frame
self.present(popoverContent, animated: true, completion: nil)