2

I'm having a hard time presenting a popover correctly from the accessoryButton of a tableviewCell.

The reason I'm not using accessory view is because the cell is in edit mode and I couldn't display both the green plus sign + custom accessory view.. Maybe I overlooked something on that front?

Currently my popover shows correctly, but that's only the case for this configuration since I set a static distance from the origin... Any Ideas how to solve this?

Code:

-(void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{

UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];

if (![self duplicateDayContent]) {
    duplicateDayContent = [[self storyboard]instantiateViewControllerWithIdentifier:@"CopyDay"];
    [duplicateDayContent setDelegate:self];

    duplicateDayPopover = [[UIPopoverController alloc]initWithContentViewController:duplicateDayContent];
    duplicateDayPopover.popoverContentSize = CGSizeMake(320, 600);

}

CGRect rect = CGRectMake(cell.bounds.origin.x+800, cell.bounds.origin.y+10, 50, 30);

[duplicateDayPopover presentPopoverFromRect:rect inView:cell permittedArrowDirections:UIPopoverArrowDirectionRight animated:YES];

}
L00ps
  • 113
  • 2
  • 9
  • 1
    may be you would have considered cell.accessoryView.bounds or directly consider cell.accessoryView.frame – Sri Tirupathi Raju May 25 '13 at 17:12
  • thx a lot your your suggestion. I tried: CGRect rect = CGRectMake(cell.accessoryView.bounds.origin.x, cell.accessoryView.bounds.origin.y, 50, 30); But that doesn't work on the x side. Maybe because I don't actually load an accesory view? or am i missing something? – L00ps May 25 '13 at 17:35
  • cell.accessoryView.bounds.size.width-50 give a try using this in CGRectMake first argument – Sri Tirupathi Raju May 25 '13 at 17:55
  • http://stackoverflow.com/questions/3015400/how-to-correctly-present-a-popover-from-a-uitableviewcell-with-uipopoverarrowdir – Rachel Gallen May 25 '13 at 17:59
  • thank you again for your suggestion tirupathi, didn't solve it. Rachels hint helped me, thank you!! I somehow thought accessoryView is not valid because I use accessoryType. Lesson learned! – L00ps May 25 '13 at 18:05

3 Answers3

2

This works quite nicely for a cell with accessoryType .detailDisclosureButton:

if let ppc = vc.popoverPresentationController, let cell = tableView.cellForRow(at: indexPath) {
    ppc.sourceView = cell
    ppc.sourceRect = CGRect(x: cell.bounds.width - 58, y: cell.bounds.height/2 - 11, width: 22, height: 22)
    vc.modalPresentationStyle = .popover
}
present(vc, animated: true, completion: nil)

You would typically do this in tableView(_ accessoryButtonTappedForRowWith indexPath:)

You can also test the position of the calculated frame with a marker:

let marker = UIView(frame: ppc.sourceRect)
marker.backgroundColor = UIColor.red.withAlphaComponent(0.2)
cell.addSubview(marker)

Test marker

markiv
  • 1,578
  • 16
  • 12
1

this code from this thread helped me: How to correctly present a popover from a UITableViewCell with UIPopoverArrowDirectionRight or UIPopoverArrowDirectionLeft thanks to rachels hint

UIView *accessoryView       = cell.accessoryView; // finds custom accesoryView     (cell.accesoryView)
if (accessoryView == nil) {
    UIView *cellContentView = nil;

    for (UIView *accView in [cell subviews]) {
        if ([accView isKindOfClass:[UIButton class]]) {
            accessoryView   = accView; // find generated accesoryView (UIButton)
            break;
        } else if ([accView isKindOfClass:NSClassFromString(@"UITableViewCellContentView")]) {
            // find generated UITableViewCellContentView
            cellContentView = accView;
        }
    }
    // if the UIButton doesn't exists, find cell contet view (UITableViewCellContentView)
    if (accessoryView == nil) {
        accessoryView   = cellContentView;
    }
    // if the cell contet view doesn't exists, use cell view
    if (accessoryView == nil) {
        accessoryView   = cell; 
    }
}
Community
  • 1
  • 1
L00ps
  • 113
  • 2
  • 9
1

In swift, this has worked for me:

Create a popover presentation segue, then use prepareForSegue to configure the UIPopoverPresentationController of the destination view controller:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if (segue.identifier == Storyboard.providerInfoSegue) {
        if let vc = segue.destinationViewController.contentViewController as? /*DestinationViewControllerType*/ {
           //Configure view controllers here

            if let popOverPresentationController : UIPopoverPresentationController = vc.popoverPresentationController {


                if let cell = tableView.cellForRowAtIndexPath(selectedAccessoryIndexPath) {
                    var accessoryView: UIButton!
                    for accView in cell.subviews {
                        if accView is UIButton {
                            accessoryView = accView as? UIButton
                            break
                        }
                    }
                    popOverPresentationController.delegate = self
                    popOverPresentationController.sourceView                = cell
                    popOverPresentationController.sourceRect                = accessoryView.frame
                    popOverPresentationController.permittedArrowDirections  = UIPopoverArrowDirection.Right

                }
            }
        }
    }
}
Emma Labbé
  • 667
  • 7
  • 18