How to correctly present a popover from a UITableViewCell with UIPopoverArrowDirectionRight or UIPopoverArrowDirectionLeft

后端 未结 11 781
失恋的感觉
失恋的感觉 2020-12-02 15:30

I always try to present a popover from a cell inside a tableView this way:

[myPopover presentPopoverFromRect:cell.frame inView:self.tableView permittedArrowD         


        
相关标签:
11条回答
  • 2020-12-02 16:00

    This is how i did and works perfectly fine.

    RidersVC *vc = [RidersVC ridersVC];
    vc.modalPresentationStyle = UIModalPresentationPopover;
    vc.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
    UIPopoverPresentationController *popPresenter = [vc popoverPresentationController];
    popPresenter.sourceView = vc.view;
    popPresenter.barButtonItem= [[UIBarButtonItem alloc] initWithCustomView:button];
    popPresenter.backgroundColor = [UIColor colorWithRed:220.0f/255.0f green:227.0f/255.0f blue:237.0f/255.0f alpha:1.0];
    [self.parentVC presentViewController:vc animated:YES completion:NULL];
    
    0 讨论(0)
  • 2020-12-02 16:02

    I did come across this problem as well. A solution for me was to simply change the width of the rect returned by CGRect)rectForRowAtIndexPath:(NSIndexPath *)indexPath :

    CGRect rect = [aTableView rectForRowAtIndexPath:indexPath];
    
    //create a 10 pixel width rect at the center of the cell
    
    rect.origin.x = (rect.size.width - 10.0) / 2.0; 
    rect.size.width = 10.0;  
    
    [self.addExpensePopoverController presentPopoverFromRect:rect inView:aTableView permittedArrowDirections:UIPopoverArrowDirectionAny  animated:YES]; 
    

    This create a rect centred inside the cell. This way, the popover has more chances of findind a good spot to position itself.

    0 讨论(0)
  • The accepted answer cannot compile now.

    CGRect rect =[tableView rectForRowAtIndexPath:indexPath]; //This is how to get the correct position on the tableView    
    UIPopoverPresentationController *popController = [controller popoverPresentationController];
    popController.sourceRect = rect;
    popController.permittedArrowDirections = 0;  //Here there is no arrow. It is my app's need
    popController.delegate = self;
    popController.sourceView = self.tableView;
    popController.sourceView.backgroundColor = [UIColor yellowColor];
    
    0 讨论(0)
  • 2020-12-02 16:10

    You're getting the frame from the cell via the rectForRowAtIndexPath method. This is correct. However the tableview is most likely a subview of a larger iPad view so when the popover gets the coordinates it thinks they're in the larger view. This is why the popover appears in the wrong place.

    Example, the CGRect for the row is (0,40,320,44). Instead of the popover targeting that frame on the tableview it instead targets that frame on your main view.

    I solved this problem by converting the frame from the relative coordinates of the table to coordinates in my larger view.

    code:

    CGRect aFrame = [self.myDetailViewController.tableView rectForRowAtIndexPath:[NSIndexPath indexPathForRow:theRow inSection:1]];
    [popoverController presentPopoverFromRect:[self.myDetailViewController.tableView convertRect:aFrame toView:self.view] inView:self.view permittedArrowDirections:UIPopoverArrowDirectionRight animated:YES];
    

    Hope that helps others searching for this issue.

    0 讨论(0)
  • 2020-12-02 16:10

    In Swift, between the above answers this works for me on an iPad in any orientation:

    if let popOverPresentationController : UIPopoverPresentationController = myAlertController.popoverPresentationController {
    
        let cellRect = tableView.rectForRowAtIndexPath(indexPath)
    
        popOverPresentationController.sourceView                = tableView
        popOverPresentationController.sourceRect                = cellRect
        popOverPresentationController.permittedArrowDirections  = UIPopoverArrowDirection.Any
    
    }
    
    0 讨论(0)
  • 2020-12-02 16:12

    I had the same kind of problem, here's the workaround i used :

    • in my UITableViewCell, i added Actions (IBActions as i generate my cells from a NIB) for cell's specific buttons.
    • i then defined a CellActionDelegate protocol that mimics my actions selectors, to which i had my button (sender) and my cell (self)
    • then the detailViewController of my splitViewController implements this protocol, converting from the cell's to its coordinates...

    here a example of code

    In MyCustomTableViewCell.m :

       -(IBAction)displaySomeCellRelativePopover:(id)sender{
            //passes the actions to its delegate
            UIButton *button = (UIButton *)sender;
            [cellActionDelegate displaySomeCellRelativePopoverWithInformation:self.info
                                                                   fromButton:button 
                                                                     fromCell:self];   
       }
    

    and the, in MyDetailViewController.m :

    -(void)displaySomeCellRelativePopoverWithInformation:(MyCellInformationClass *)info
                                              fromButton:(UIButton *)button 
                                                fromCell:(UIView *)cell{
    
    UIPopoverController * popoverController = nil;
    
    //create your own UIPopoverController the way you want
    
    //Convert your button/view frame
    
    CGRect buttonFrameInDetailView = [self.view convertRect:button.frame fromView:cell];
    
    //present the popoverController
    [popoverController presentPopoverFromRect:buttonFrameInDetailView
                                   inView:self.view permittedArrowDirections:UIPopoverArrowDirectionRight animated:YES];]
    
    
    //release objects created...
    }
    

    PS : Of course, the 'action' doesn't have to be a IBAction, and the frame from where the popover originates doesn't have to be a UIButton - a single UIView would be good :)

    0 讨论(0)
提交回复
热议问题