Come presentare correttamente un popover da un UITableViewCell con UIPopoverArrowDirectionRight o UIPopoverArrowDirectionLeft
-
26-09-2019 - |
Domanda
cerco sempre di presentare una popover da una cella all'interno di una tableView in questo modo:
[myPopover presentPopoverFromRect:cell.frame inView:self.tableView permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
ma non posso usare UIPopoverArrowDirectionRight o Sinistra, in quanto, a seconda della posizione del ipad (verticale o orizzontale), il popover appare da qualche altra parte.
I Am presentare la popover nel modo giusto?
PS:. Visualizzazione tabella è in detailview di uno SplitView
Soluzione
Ecco la soluzione semplice, che funziona bene per me
- (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];
}
Altri suggerimenti
che stai ricevendo il telaio dalla cella tramite il metodo rectForRowAtIndexPath. Questo è corretto. Tuttavia la Tableview è più probabile una visualizzazione secondaria di una più ampia visione iPad in modo che quando la popover ottiene le coordinate che pensano di essere nel più grande vista. Questo è il motivo per cui la popover appare nel posto sbagliato.
Esempio, il CGRect per la riga è (0,40,320,44). Invece del popover mira che fanno da cornice alla Tableview esso si rivolge, invece, che telaio sulla visualizzazione principale.
I risolto questo problema convertendo il telaio dalle relative coordinate della tabella di coordinate nel mio ingrandita.
codice:
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];
La speranza che aiuta gli altri alla ricerca di questo problema.
Mi sono imbattuto in questo problema oggi, e ho trovato una soluzione più semplice.
Quando un'istanza del popover, è necessario specificare vista del contenuto della cella:
- (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
}
In Swift, tra le risposte di cui sopra funziona questo per me su un iPad in qualsiasi orientamento:
if let popOverPresentationController : UIPopoverPresentationController = myAlertController.popoverPresentationController {
let cellRect = tableView.rectForRowAtIndexPath(indexPath)
popOverPresentationController.sourceView = tableView
popOverPresentationController.sourceRect = cellRect
popOverPresentationController.permittedArrowDirections = UIPopoverArrowDirection.Any
}
Per pop un popover accanto al accessorio u possibile utilizzare questo codice:)
Io uso questo per più uso avanzato:
- trova accesoryView personalizzato (cell.accesoryView)
- se è vuoto, trovare generato accesoryView (UIButton) se la cella ha
- se l'UIButton non esiste, trovare vista Contet cellulare (UITableViewCellContentView)
- se la vista Contet cella non esiste, vista di cella uso
Può essere l'uso per UIActionSheet o UIPopoverController .
Ecco il mio codice:
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];
Testato in iOS 4,3-5,1
meglio usare come metodo personalizzato:
-(UIView*)getViewForSheetAndPopUp:(UITableViewCell*)cell;
E codice di metodo:
-(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;
}
Io non sono venuto in questo problema pure. Una soluzione per me è stato quello di cambiare semplicemente la larghezza del rettangolo restituito da 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];
Questo crea un rettangolo centrato all'interno della cellula. In questo modo, il popover ha più probabilità di ritrovare i Un buon posto per la posizione stessa.
Il telaio cellulare sta per essere qualcosa come 0,0, larghezza, dimensioni, io non credo che avrà il suo X e Y rispetto al tableView ... che si desidera utilizzare - (CGRect) rectForRowAtIndexPath: (NSIndexPath * ) indexPath per questo, questo dovrebbe restituire la cornice giusta per la cella relativa al tableView ... qui è un collegamento UITableView ref
Ho avuto lo stesso tipo di problema, ecco la soluzione che ho usato:
- nel mio UITableViewCell, ho aggiunto le azioni (IBActions come genero le mie cellule da un pennino) per i pulsanti specifici della cella.
- Ho poi definito un protocollo CellActionDelegate che imita le mie azioni selettori, a cui ho avuto il mio tasto (mittente) e il mio cellulare (auto)
- allora la detailViewController dei miei attrezzi splitViewController questo protocollo, la conversione dalla cella è al suo coordinate ...
qui un esempio di codice
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];
}
e, 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: Naturalmente, il 'azione' non deve essere un IBAction, e il telaio da dove proviene il popover non deve essere un UIButton - un'unica UIView sarebbe bene:)
Questo è il modo che ho fatto e funziona perfettamente bene.
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];
Anche questo ha funzionato per me:
//Which are the ABSOLUTE coordinates in from the current selected cell CGRect frame =[self.view convertRect:[tbvEventsMatch rectForRowAtIndexPath:indexPath] fromView:tbvEventsMatch.viewForBaselineLayout];
La risposta accettata non può compilare ora.
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];