Comment présenter correctement un popover d'un UITableViewCell avec UIPopoverArrowDirectionRight ou UIPopoverArrowDirectionLeft

StackOverflow https://stackoverflow.com/questions/3015400

Question

J'essaie toujours de présenter un popover d'une cellule à l'intérieur d'une tableView de cette façon:

[myPopover presentPopoverFromRect:cell.frame inView:self.tableView permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

mais je ne peux pas utiliser UIPopoverArrowDirectionRight ou à gauche, parce que, selon la position de l'iPad (portrait ou paysage), le popover apparaît ailleurs.

Suis-je présenter le popover la bonne façon?

PS:. L'affichage du tableau est dans le DetailView d'un SPLITVIEW

Était-ce utile?

La solution

Voici la solution simple qui fonctionne bien pour moi

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

    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    CGRect rect=CGRectMake(cell.bounds.origin.x+600, cell.bounds.origin.y+10, 50, 30);
    [popOverController presentPopoverFromRect:rect inView:cell permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

}

Autres conseils

Vous obtenez le cadre de la cellule via la méthode rectForRowAtIndexPath. C'est correct. Cependant, le tableview est très probablement une sous-vue d'une vue iPad plus alors quand le popover obtient les coordonnées qu'il pense qu'ils sont dans la plus grande vue. Ceci est la raison pour laquelle l'popover apparaît au mauvais endroit.

Exemple, le CGRect de la ligne est (0,40,320,44). Au lieu de l'popover ciblage sur le cadre tableview il cible plutôt que cadre sur votre écran principal.

I a résolu ce problème en convertissant la trame à partir des coordonnées relatives de la table à coordonnées selon moi plus grande.

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];

L'espoir qui aide les autres à la recherche de cette question.

Je suis tombé sur ce problème aujourd'hui, et je l'ai trouvé une solution plus simple.
Lors de l'instanciation du popover, vous devez spécifier afficher le contenu de la cellule:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UIViewController *aViewController = [[UIViewController alloc] init];
    // initialize view here

    UIPopoverController *popoverController = [[UIPopoverController alloc] 
        initWithContentViewController:aViewController];
    popoverController.popoverContentSize = CGSizeMake(320, 416);
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    [popoverController presentPopoverFromRect:cell.bounds inView:cell.contentView 
        permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

    [aView release];
    // release popover in 'popoverControllerDidDismissPopover:' method
}

Dans Swift, entre les réponses ci-dessus Cela fonctionne pour moi sur un iPad dans une orientation:

if let popOverPresentationController : UIPopoverPresentationController = myAlertController.popoverPresentationController {

    let cellRect = tableView.rectForRowAtIndexPath(indexPath)

    popOverPresentationController.sourceView                = tableView
    popOverPresentationController.sourceRect                = cellRect
    popOverPresentationController.permittedArrowDirections  = UIPopoverArrowDirection.Any

}

Pour faire apparaître un popover à côté de la accesory u peut utiliser ce code:)

J'utilise cela pour plus utilisation avancée:

  1. trouve accesoryView personnalisé (cell.accesoryView)
  2. si elle est vide, trouver généré accesoryView (UIButton) si la cellule a
  3. si le UIButton n'existe pas, trouver une vue de Contet cellulaire (UITableViewCellContentView)
  4. si la vue Contet cellulaire n'existe pas, utilisez la vue cellulaire

Peut être utilisé pour UIActionSheet ou UIPopoverController .

Voici mon code:

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; 
    }
}

[actionSheet showFromRect:accessoryView.bounds inView:accessoryView animated:YES];

Testé dans iOS 4/3 à 5/1

Il vaut mieux utiliser comme méthode personnalisée:

-(UIView*)getViewForSheetAndPopUp:(UITableViewCell*)cell;

et le code de la méthode:

-(UIView*)getViewForSheetAndPopUp:(UITableViewCell*)cell {
UIView *accessoryView = cell.accessoryView;

if (accessoryView == nil) {
    UIView *cellContentView = nil;

    for (UIView *accView in [cell subviews]) {
        if ([accView isKindOfClass:[UIButton class]]) {
            accessoryView = accView;
            break;
        } else if ([accView isKindOfClass:NSClassFromString(@"UITableViewCellContentView")]) {              
            cellContentView = accView;
        }
    }       

    if (accessoryView == nil) {
        accessoryView   = cellContentView;
    }
    if (accessoryView == nil) {
        accessoryView   = cell;
    }
}

return accessoryView;
}

Je n'ai rencontré ce problème aussi bien. Une solution pour moi était de changer simplement la largeur de la rect retournée par 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]; 

créer une rect centrée à l'intérieur de la cellule. De cette façon, le popover a plus de chances de findind un bon endroit pour se positionner.

Le cadre cellulaire va être quelque chose comme 0,0, la largeur, la taille, je ne crois pas qu'il aura son X et Y par rapport à la tableView ... vous voulez utiliser - (CGRect) rectForRowAtIndexPath: (NSIndexPath * ) indexPath pour cela, cela devrait vous retourner le cadre approprié pour la cellule par rapport à la tableView ... voici un lien uitableview ref

J'ai eu le même genre de problème, voici la solution i utilisé:

  • dans mon UITableViewCell, j'ajouté Actions (IBActions que je produis mes cellules d'un NIB) pour les boutons spécifiques de cellules.
  • i alors défini un protocole de CellActionDelegate qui imite mes actions sélecteurs, que j'avais mon bouton (émetteur) et ma cellule (auto)
  • alors la detailViewController de mes splitViewController implémente ce protocole, la conversion de la cellule est à ses coordonnées ...

ici un exemple de code

En MyCustomTableViewCell.m:

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

et, en 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: Bien sûr, la « action » ne doit pas être un IBAction, et le cadre d'où provient le popover ne doit pas être un UIButton - un UIView serait bon:)

Voici comment je l'ai fait et fonctionne parfaitement bien.

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];

Cela a également travaillé pour moi:

        //Which are the ABSOLUTE coordinates in from the current selected cell
        CGRect frame =[self.view convertRect:[tbvEventsMatch rectForRowAtIndexPath:indexPath] fromView:tbvEventsMatch.viewForBaselineLayout];

La réponse acceptée ne peut pas compiler maintenant.

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];
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top