Reputation: 5052
I have a table view and I use UITableViewRowAction
to present two options to the user when a swipe is done on a row, 'delete' and 'more', and I want the more to show a popover. The popover needs to know the view it is anchored at, so how do I get a reference to the button which says 'more'?
My code:
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]? {
var moreRowAction = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "More", handler:{action, indexpath in
let p = SomeViewController(aClient: client)
let aPopover = UIPopoverController(contentViewController: p)
let popRect = self.view.frame
// What should x be?
let x: UIView = self.tableView.cellForRowAtIndexPath(indexPath)!
aPopover.presentPopoverFromRect(popRect, inView: x, permittedArrowDirections: UIPopoverArrowDirection.Any, animated: true)
});
var deleteRowAction = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "Delete", handler:{action, indexpath in
// Do something to delete.
});
return [deleteRowAction, moreRowAction];
}
This code shows the popover as anchored at the whole cell, not at the 'more' button.
I have searched the documentation about UITableViewRowAction
, but nothing there gave me a lead. The type of the action
argument is also UITableViewRowAction
so I'm not sure it can be used.
According to the comment, I got it working. I call a method in the custom cell view controller, there I access the subviews array. I don't like accessing subviews array and assuming the position of the button in that array.
The working code:
In the tableview callback I do:
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]? {
var moreRowAction = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "Plus", handler:{action, indexpath in
let cell = self.tableView.cellForRowAtIndexPath(indexPath)! as MyCell
cell.showPopover()
});
Inside MyCell I do:
func showPopover() {
let p = ClientLongPressViewController(client: self.client)
let aPopover = UIPopoverController(contentViewController: p)
let x: UIView = self.subviews[0].subviews[1] as? UIView ?? self
let popRect = x.frame
aPopover.setPopoverContentSize(CGSize(width: 215, height: 241), animated: true)
aPopover.presentPopoverFromRect(popRect, inView: x, permittedArrowDirections: UIPopoverArrowDirection.Any, animated: true)
}
I tried (inside MyCell) to access self.contentView
but this only contains elements from the main cell view, not the swiping elements.
Also tried using self.editingAccessoryView
, but it is nil.
So I would still like a nicer way to get the "delete confirmation view", which I now access with self.subviews[0]
(The second subview[1]
is okay in my opinion because I decide it's position when I return [deleteRowAction, moreRowAction]
.
Upvotes: 3
Views: 1677
Reputation: 104082
There doesn't seem to be any straight forward way access the button itself, but after you swipe the cell, I believe that what happens, is that the cell is moved to the left, and a new view called the UITableViewCellDeleteConfirmationView is added on the right. So, if you position the popover at the cell's origin plus its width, it will be at the right edge of the cell, which will be just to the left of your button (assuming that your button is the left most one if you have multiple buttons).
var moreRowAction = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "More", handler:{action, indexpath in
let p = SomeViewController(aClient: client)
let aPopover = UIPopoverController(contentViewController: p)
let cell: UITableViewCell = self.tableView.cellForRowAtIndexPath(indexPath)!
let popRect = CGRectMake(cell.frame.origin.x + cell.frame.size.width, cell.frame.size.height/2.0, 1, 1);
aPopover.presentPopoverFromRect(popRect, inView: cell, permittedArrowDirections: .Right, animated: true)
});
Upvotes: 1