2011-01-19 10 views
6

Sto cercando di visualizzare un UISplitViewController presentandolo come un controller di visualizzazione modale nella mia app per iPad. Riesco a visualizzarlo, ma per qualche ragione c'è una lacuna alla sinistra della vista modale delle dimensioni di una barra di stato che viene preservata anche quando l'orientamento viene modificato.Come utilizzare un UISplitViewController come controller di visualizzazione modale?

alt text

Qualcuno sa perché questo sta accadendo? O se questo è anche possibile? Forse sto solo scavando un buco enorme.

risposta

6

Il supporto UISplitViewController è stato progettato per essere utilizzato solo come controller di visualizzazione radice. La presentazione di una modally va contro le linee guida Apple Human Interface e ha un'alta probabilità di essere respinta dal team di revisione app. Inoltre, è possibile ricevere l'errore:

Application tried to present Split View Controllers modally

+2

alternativa è quella di cercare un controllore aftermarket SplitView per le dimensioni, come https://github.com/SlavaBushtruk/APSplitViewController –

+1

upvoted a "vista del regolatore aftermarket" –

3

Tecnicamente, questo è quello che ho fatto:

1/Sottoclasse un UIViewController es. @interface aVC: UIViewController

2/In viewDidLoad, impostare uno splitViewController, ad es. aSplitVC

3/Poi self.view = aSplitVC.view

Dopo tutto, presenti AVC come modalViewController

+0

Non lavorare Xcode 8, IOS 8+ C'è il registro degli errori: "Una vista può essere associata ad un massimo di un controller di visualizzazione alla volta!" – Jerome

3

Sono d'accordo con Evan che questo è un po 'off-colore per Apple, ma sono stato in grado di completare una versione funzionante di questo con la seguente soluzione:

UISplitViewController *splitVC = [[UISplitViewController alloc] init]; 
    splitVC.delegate = VC2; 
    splitVC.viewControllers = [NSArray arrayWithObjects:navcon1, navcon2, nil]; 

    UINavigationController *splitNavCon = [[UINavigationController alloc] init]; 
    splitNavCon.modalTransitionStyle = UIModalTransitionStyleCoverVertical; 
    [splitNavCon.view addSubview:splitVC.view]; 
    VC2.splitParentViewController = splitNavCon; 

    [self presentViewController:splitNavCon animated:YES completion:nil]; 

questo mi ha permesso di avere un pulsante a lavorare di nuovo nella nuova UISplitViewController che è stato presentato modale sullo schermo.

Noterete che in realtà passo il VC2 (il delegato di UISplitViewController) al suo genitore UINavigationController. Questo è stato il modo migliore che ho trovato ho potuto respingere l'UISplitViewController dall'interno del VC2:

[splitParentViewController dismissViewControllerAnimated:YES completion:nil]; 
+1

L'idea di base qui funziona abbastanza bene, ma ARC può mangiare il 'UISplitViewController' se qualcos'altro non lo trattiene. Quindi se i bambini della vista scompaiono dopo essere stati presentati in questo modo, spostali in una proprietà o qualcosa del genere. – Nuthatch

8

Come per molti di voi, ho bisogno di un 'modo modale' di utilizzare l'UISplitViewController. Questo sembra essere un vecchio problema, ma tutto ciò che ho trovato in StackOverflow era, nella migliore delle ipotesi, una spiegazione del perché il problema si verifica quando si tenta di farlo (come la risposta accettata sopra) o "hack-around".

Tuttavia, a volte non è molto comodo cambiare gran parte del codice base e rendere UISplitViewController l'oggetto iniziale solo per far funzionare la sua funzionalità.

A turno, c'è un modo per rendere tutti felici (comprese le linee guida Apple). La soluzione che ho trovato meglio, è stato quello di utilizzare l'UISplitViewController normalmente, ma quando necessario, per essere mostrato/respinto, utilizzare il seguente approccio:

-(void)presentWithMasterViewController: (UIViewController *) thisMasterViewController 
    andDetailViewController: (UIViewController *) thisDetailViewController 
         completion:(void(^)(void))completion 
{ 
    masterViewController = thisMasterViewController; 
    detailViewController = thisDetailViewController; 

    [self setViewControllers:[NSArray arrayWithObjects:masterViewController, detailViewController, nil]]; 

    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
    self.window.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; 

    self.window.rootViewController = self; 

    [self.window makeKeyAndVisible]; 

    if(completion) 
     completion(); 
    } 

-(void)dismissViewControllerWithCompletion:(void (^)(void))completion 
{ 
    self.window = nil; 
    masterViewController = nil; 
    detailViewController = nil; 
    if(completion) 
     completion(); 
} 

Dove "finestra", è una proprietà della vostra sottoclasse UISplitViewController. E il sistema si prenderà cura di tutto il resto!

Per comodità/di riferimento, ho caricato questo come una sottoclasse UISplitViewController a GitHub:

ModalSplitViewController

--EXAMPLE su come utilizzare -

mySplitViewController = [[ModalSplitViewController alloc] init]; 
    mySplitViewController.delegate = self; 

    [mySplitViewController presentWithMasterViewController:masterViewController andDetailViewController:detailViewController completion:nil]; 

    // when done: 

    [mySplitViewController dismissViewControllerWithCompletion:nil]; 
    mySplitViewController = nil; 

Side-nota: Credo la maggior parte della confusione deriva dal fatto che l'esempio di utilizzo di UISplitView dalla documentazione Apple utilizza la finestra creata nell'appDelegate e per il fatto che molte persone non sono così familiare con il concetto di finestra - perché di solito non abbiamo bisogno di (vengono creati una volta in StoryBoards o nel codice boilerplate).

Inoltre, se si sta eseguendo il ripristino dello stato, non si dovrebbe dimenticare che UIViewControllers creato in modo programmatico non verrà ripristinato automaticamente dal sistema. .

0

Credo che si possa fare il contrario: invece del controller personalizzato che presenta il controller diviso, è possibile impostare il controller diviso come controller della finestra radice nello storyboard e, in cima alla sua vista, è possibile aggiungere il controller personalizzato (cioè, schermata di accesso) e rimuoverlo dallo schermo (ad esempio removeFromSuperview) quando è necessario.

0

Questa risposta non è effettivamente corretta, perché non è più valida da iOS8 e se è necessario supportare anche iOS7, è possibile farlo come se si inserisse in modo modale UIViewController che ha un contenitore come SplitView.

let mdSplitView = self.storyboard?.instantiateViewControllerWithIdentifier("myDataSplitView") as! MyData_SplitVC 
    self.addChildViewController(mdSplitView) 

    mdSplitView.view.bounds = self.view.bounds 
    self.view.addSubview(mdSplitView.view) 
    mdSplitView.didMoveToParentViewController(self) 
Problemi correlati