2016-07-20 1 views
2

Dans ce que je pense est une approche plutôt intelligente pour contourner le problème de lancer un popover à partir d'un UITableViewRowAction, je veux positionner un UIView clair sur l'action cible et l'utiliser pour le sourceRect pour ancrer le UIPopoverPresentationController. Dans ce cas, l'action cible est le bouton orange "Acct" montré dans la capture d'écran ci-dessous.Positionner un UIView au point de frappe pour lancer popover

J'utilise un UIView clair (self.clearTopView) sur toute tableview et j'initialiser le point de vue de lancement (tappedViewOverlay) avec un cadre dérivé de (donc je pensais) l'emplacement du robinet (point) dans la vue et CGSize (tappedRectSize). Ensuite, je l'ajoute en tant que sous-vue à self.clearTopView. Je le colorie actuellement en noir pour que je le trouve.

Comme le montre la capture d'écran suivante, une partie du schéma fonctionne comme prévu. La vue tappedViewOverlay est ajoutée et colorée de manière appropriée. Le popoverPresentationController (thisPPC) est lancé à partir de cette vue, comme prévu.

enter image description here

Le problème est que la vue est toujours placée dans le coin supérieur gauche de l'écran, au lieu de l'emplacement de votre choix, qui est l'endroit où le robinet a eu lieu. Voici le code correspondant: quelqu'un

else if ([[segue identifier] isEqualToString:@"AccountPopSegue"]) 
    { 

     UITapGestureRecognizer *tapGestureRecognizer; 

     CGPoint point = [tapGestureRecognizer locationInView:self.clearTopView]; 

     NSString *pointString = NSStringFromCGPoint(point); 

     NSLog(@"point is located at %@",pointString); 


     CGSize tappedRectSize= CGSizeMake(60,60); 
     CGRect tappedRect = {point,tappedRectSize}; 

     NSString * tappedRectString = NSStringFromCGRect(tappedRect); 

     NSLog(@"tappedRect = %@",tappedRectString); 


     tappedViewOverlay = [[UIView alloc]initWithFrame:tappedRect]; 
     tappedViewOverlay.backgroundColor = [UIColor blackColor]; 

     [self.clearTopView addSubview:tappedViewOverlay]; 

     [self.clearTopView setUserInteractionEnabled:NO]; 


     NSString *tappedOverlayFrame = NSStringFromCGRect(tappedViewOverlay.frame); 
     NSLog(@"tappedViewOverlay.frame = %@",tappedOverlayFrame); 


     UIViewController *controller = segue.destinationViewController; 
     controller.popoverPresentationController.delegate = self; 
     controller.preferredContentSize = CGSizeMake(320, 186); 
     UIPopoverPresentationController *thisPPC = controller.popoverPresentationController; 


     thisNavController = (UINavigationController *)segue.destinationViewController; 
     AccountChangeVC *acCVC = (AccountChangeVC *)thisNavController.topViewController; 
     acCVC.delegate = self; 

     thisPPC.sourceView = self.clearTopView; 
     thisPPC.sourceRect = tappedViewOverlay.bounds; 

Peut-s'il vous plaît me montrer où je vais mal?

Modifier

CoderWang a fait remarquer un oubli dans mon code, donc je l'ai corrigea:

else if ([[segue identifier] isEqualToString:@"AccountPopSegue"]) 
    { 

     UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc]init]; 

     [self.clearTopView addGestureRecognizer:tapGestureRecognizer]; 



     CGPoint point = [tapGestureRecognizer locationInView:self.clearTopView]; 

     NSString *pointString = NSStringFromCGPoint(point); 

     NSLog(@"point is located at %@",pointString); 


     CGSize tappedRectSize= CGSizeMake(60,60); 

     CGRect tappedRect = {point,tappedRectSize}; 

     NSString * tappedRectString = NSStringFromCGRect(tappedRect); 

     NSLog(@"tappedRect = %@",tappedRectString); 


     tappedViewOverlay = [[UIView alloc]initWithFrame:tappedRect]; 

     tappedViewOverlay.backgroundColor = [UIColor blackColor]; 

     [self.clearTopView addSubview:tappedViewOverlay]; 

     [self.clearTopView setUserInteractionEnabled:NO]; 


     NSString *tappedOverlayFrame = NSStringFromCGRect(tappedViewOverlay.frame); 
     NSLog(@"tappedViewOverlay.frame = %@",tappedOverlayFrame); 


     UIViewController *controller = segue.destinationViewController; 
     controller.popoverPresentationController.delegate = self; 
     controller.preferredContentSize = CGSizeMake(320, 186); 
     UIPopoverPresentationController *thisPPC = controller.popoverPresentationController; 


     thisNavController = (UINavigationController *)segue.destinationViewController; 
     AccountChangeVC *acCVC = (AccountChangeVC *)thisNavController.topViewController; 
     acCVC.delegate = self; 

     thisPPC.sourceView = self.clearTopView; 
     thisPPC.sourceRect = tappedViewOverlay.bounds; 

Ce changement (initialisation du tapGestureRecognizer et plus self.clearTopView) produit une légère changer dans la position de la vue tappedViewOverlay noir. Vous pouvez le voir cache derrière le « Retour » nav bouton dans la capture d'écran suivante:

enter image description here

Répondre

0

Le problème est que le « tappedRect » est incorrect, ne savent plus exactement la raison. Mais vous pouvez essayer la méthode suivante pour obtenir rect pour le bouton « Acct » converti en self.clearTopView:

CGRect tappedRect = [Acct.superview convertRect:acct.frame toView:self.clearTopView]; 

ou converti à la fenêtre (comme self.clearTopView est sur toute tableview):

CGRect tappedRect = [Acct.superview convertRect:acct.frame toView:nil]; 
+0

Pour autant que je sache, les boutons UITableViewRowAction n'ont pas de propriété frame, du moins pas celle accessible ... – rattletrap99

+0

Ensuite, vous pouvez utiliser la méthode associée: - (CGPoint) convertPoint: (CGPoint) point toView: (nullable Vue UIView *); avec CGPoint point = [tapGestureRecognizer locationInView: self.clearTopView]; – CoderWang

+0

Ce sera mieux si vous fournissez également les informations de journal. – CoderWang