2011-12-15 14 views
26

Ho un UIViewController che contiene uno UITableView. Questo UIViewController viene visualizzato in un UIPopoverController.Come modificare dinamicamente il contentSize di UIPopoverController?

Ora, le cose è che il numero di elementi nel tableView non è costante, e voglio la dimensione del popover (vale a dire - il popoverContentSize), per regolare in base al numero di elementi nella tableView

Ingenuamente, stavo pensando che se avrò impostato il contentSizeForViewInPopover in viewDidLoad dopo che sto caricando il tableView con tutti gli elementi - Lo farò.

Non ha funzionato.

Quindi, in breve, la mia domanda è: come posso cambiare il popoverContentSize direttamente dal contentViewController - dopo che è stato presentato?

Appendice: enter image description here

risposta

46

potrei essere molto tardi per rispondere, ma per un nuovo utente da iOS 7 si prega di utilizzare la seguente riga nel vostro UIViewController i, e contentViewController della vostra UIPopOverViewConotroller

-(void) viewDidAppear:(BOOL)animated{ 
    [super viewDidAppear:animated]; 
    self.preferredContentSize=myTableView.contentSize; 
} 

auguriamo che questo aiuto per l'utente di iOS 7.

+8

questo potrebbe funzionare meglio in ViewWillAppear, come accade prima che appaia la vista. – nh32rg

+1

se si utilizza navigationController all'interno di popover e si verifica un problema anche dopo aver impostato preferredContentSize. Prova [self.parentPopOverController setPopoverContentSize: CGSizeMake (250, 400) animato: YES]; prima di spingere il UIViewController – Hassy

+1

ha accettato la tua risposta perché è più aggiornata. Grazie! –

9

Beh, alla fine ho fatto qualcosa che io non sono sicuro se è la cosa giusta da fare, ma si sta lavorando.

ho aggiunto un punto di riferimento nel mio contentViewController al popoverController:

@property (nonatomic , assign) UIPopoverController *popoverControllerContainer; 

Poi, ho aggiunto il codice di ridimensionamento per viewWillAppear e viewDidAppear:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    [self.tableView reloadData]; 
} 

-(void) viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; 
    self.contentSizeForViewInPopover = self.tableView.contentSize; 
} 

-(void) viewDidAppear:(BOOL)animated 
{ 
    [super viewDidAppear:animated]; 
    [self.popoverControllerContainer setPopoverContentSize:self.contentSizeForViewInPopover animated:YES]; 
} 

Quindi, mantenendo un riferimento alla popover è tipo di hack-ish, quindi sono aperto a sentire idee migliori.

+0

Io uso il stesso meccanismo. Sto aggiungendo il metodo 'createPopover' a UIViewControllers che sono usati come contenuti popover. I metodi crea un popover da 'self' e quindi salva l'istanza di popover per un ulteriore accesso. – Sulthan

+0

Ciao @Avraham La tua risposta è stata quella che ho usato e funziona benissimo. Ho una domanda sulla tua soluzione: perché hai impostato il contenuto della vista nel metodo apparirà e la dimensione del popover in apparirà? Perché non può essere fatto in uno solo dei due metodi, perché ho provato e non ha funzionato? –

+0

Utilizza entrambi i codici e funzionerà :) –

7

Una classe UIViewController ha la proprietà

self.contentSizeForViewInPopover 

che ridimensionare la comparsa sopra w/out dover aggiungere un riferimento ad esso.

E per espandere una soluzione, ho utilizzato il metodo rectForSection: per ottenere la dimensione della sezione (il mio ha solo 1 sezione, così facile da ottenere) e quindi aggiunto l'altezza della barra di navigazione (sembra essere 20). quindi sono in grado di creare la popover la dimensione della vista tabella finale:

CGRect sectionRect = [view.tableView rectForSection:0]; 

if (sectionRect.size.height + 20 < POPOVER_SIZE.height) 
    view.contentSizeForViewInPopover = CGSizeMake(POPOVER_SIZE.width, sectionRect.size.height + 20); 
else 
    view.contentSizeForViewInPopover = POPOVER_SIZE; 

potrebbe risultare più difficile con più sezioni, io non l'ho provato. dovrei solo essere in grado di riassumere le altezze della sezione, ma potrebbero esserci problemi di spaziatura che non conosco.

+2

È deprecato, utilizzare "preferredContentSize" da iOS7 e versioni successive. – Satyam

0

Stavo avendo lo stesso problema e nessuna delle risposte che ho trovato funzionava. Mi sono accartocciato e penso che funzioni bene.

Ho un array nel mio initWithCoder che contiene i miei valori. Eseguo semplicemente questo codice:

- (id)initWithCoder:(NSCoder *)aDecoder 
{ 
//Popover Choices 

_importantChoices = [NSMutableArray array]; 
[_importantChoices addObject:@"Bakery"]; 
[_importantChoices addObject:@"Beverage Dry Mix"]; 
[_importantChoices addObject:@"Beverage RTD"]; 
[_importantChoices addObject:@"Crisps"]; 
[_importantChoices addObject:@"Meat"]; 
[_importantChoices addObject:@"Supplements"]; 


//Calculate size of Popover 
self.clearsSelectionOnViewWillAppear = NO; 
NSInteger rowsCount = [_importantChoices count]; 
NSInteger singleRowHeight = [self.tableView.delegate tableView:self.tableView 
             heightForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]]; 
NSInteger totalRowsHeight = rowsCount * singleRowHeight; 
CGFloat largestLabelWidth = 0; 
for (NSString *tmp in _importantChoices) { 
    CGSize labelSize = [tmp sizeWithAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:20.0f]}]; 
    if (labelSize.width > largestLabelWidth) { 
     largestLabelWidth = labelSize.width; 
    } 
} 
CGFloat popoverWidth = largestLabelWidth + 100;  //Add a little padding to the width 
self.preferredContentSize = CGSizeMake(popoverWidth, totalRowsHeight); 
return self; 
} 
7

Per iOS 7 o versione successiva.

- (CGSize)preferredContentSize { 
    return CGSizeMake(320, 550); 
} 

Se sei un figlio di un contenitore, reindirizza la dimensione del contenuto a te stesso. Per esempio. In una sottoclasse UINavigationController:

- (CGSize)preferredContentSize { 
    return self.topViewController.preferredContentSize; 
} 
+0

Solo una nota per gli altri che provano l'approccio di Robert. È molto pulito e funziona per questa domanda. Tuttavia, potrebbe non funzionare per te, se stai presentando un UITableView all'interno di un UINavigationController. Avinash sembra funzionare in quel caso. – DenVog

+0

@DenVog - Buon posto. Preferirei ancora sottoclasse 'UINavigationController' per ottenere la sua barra di stato preferita da topViewController. Generalmente trovo l'approccio di dichiarare ciò che si richiede meglio dell'impostazione di un valore in quanto previene i bug in cui 2 diverse classi possono calpestare la stessa proprietà con valori diversi che possono portare a risultati diversi a seconda dell'ordine in cui si fanno le cose. Questo è simile al motivo per cui 'preferredStatusBarStyle' è stato creato in iOS 7. – Robert

+0

Questa è stata l'unica soluzione che ha funzionato per me. L'impostazione di self.preferredContentSize non ha avuto alcun effetto. – pls

0

iOS 8/9 soluzione - semplicemente ignorare preferredContentSize e forzare la visualizzazione tabella di layout prima di restituire è contentSize.

- (CGSize)preferredContentSize { 
    [self.tableView layoutIfNeeded]; 
    return self.tableView.contentSize; 
} 
+0

aumenta la vista ma non la riduce se incorporata in una gerarchia 'UINavigationController'. – Mojo66

1

mia app ha un menu con sottomenu proveniente da una popover e incorporato in un controller di navigazione, vale a dire qualcosa come UINavigationController ->TopMenuViewController ->SubMenuViewController xN.

Nessuna delle soluzioni di cui sopra ha funzionato per me.

La mia soluzione: Nel mio menu principale classe di visualizzazione del controller, da cui tutti gli altri controller di visualizzazione dei menu in eredità, aggiungere il seguente codice:

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    self.navigationController.preferredContentSize = CGSizeMake(450.0f, 0.0f);// increase standard width (320.0) 
} 


- (void)viewDidAppear:(BOOL)animated { 
    [super viewDidAppear:animated]; 
    self.navigationController.preferredContentSize = self.tableView.contentSize; 
} 
0

Questo dovrebbe fare il trucco

override func viewWillLayoutSubviews() { 
    super.viewWillLayoutSubviews() 

    self.preferredContentSize = CGSizeMake(0, self.tableView.contentSize.height)} 
Problemi correlati