Domanda

Mi ci è voluto un po 'di sperimentazione per chiarire un po' di confusione sul linguaggio "ModalForWindow" di Objective-C e, successivamente, su come usare una sessione modale. Forse i seguenti suggerimenti salveranno qualcuno un po 'di tempo:

(Nel caso in cui tu sia nuovo per il concetto: quando una finestra, di solito un pannello, esegue modale, impedisce a qualche altra parte dell'app di rispondere fino a quando non è stata respinta.)

"ModalForWindow" significa cose diverse in circostanze diverse. Se si utilizza LoadNibnam per visualizzare un pannello definito da un XIB e si desidera che esegui il modale, chiamalo una volta visualizzato:

// Make panelReviewImports modal, so that no other part of app will respond.
[[NSApplication sharedApplication] runModalForWindow:self.panelReviewImports];

e seguire questo nei suoi metodi di licenziamento:

[[NSApplication sharedApplication] stopModal];

Ma per NSalert, la "finestra" in BeginSheetModalForWindow si riferisce alla finestra a cui sarà l'avviso Allegata Come foglio, la finestra verrà congelata fino a quando l'avviso non sarà licenziato. Ma il app non sarà congelato; Tutte le altre finestre rimarranno utilizzabili. Se si desidera collegare un avviso come un foglio e ancheCongela il resto dell'app, segui il codice di inizio con una semplice chiamata a RunModal e usa esplicitamente il codice di ritorno, in questo modo:

[alert beginSheetModalForWindow:self.window 
                  modalDelegate:self didEndSelector:@selector(abandonmentAlertDidEnd:returnCode:contextInfo:) 
                    contextInfo:nil];
NSInteger returnCode = [alert runModal];
[self abandonmentAlertDidEnd:alert returnCode:returnCode contextInfo:nil];

(Naturalmente, avrai implementato l'abandonmentAlertDidend: ReturnCode: ContextInfo: Codice come metodo di classe.)

Oppure, se si desidera che l'avviso funzioni come pannello centrato, chiama RunModal da solo.

Supponiamo di voler eseguire un Modal Panel, seguito da un avviso se l'utente presenta una voce non valida. Dovresti fermarsi prima di mostrare l'avviso - dopo di che, per qualche motivo, un'altra chiamata a RunModalForWindow non riesce a funzionare correttamente. Per questo scenario, hai bisogno di un sessione modale:

1) Aggiungi una proprietà NSMODALSESSION alla classe del controller, poiché la modalali deve essere accessibile su più metodi.

2) Una volta visualizzato il pannello, chiama BeginModalSessionForWindow per istanziare la modali:

self.modalSession = [[NSApplication sharedApplication] beginModalSessionForWindow:self.panelForInput];

3) Segui questo con un loop while che chiama RunModalsession, rompendo quando il suo ritorno non è uguale a NSRunContinuesResponse:

while ([[NSApplication sharedApplication] runModalSession:self.modalSession] == NSRunContinuesResponse)
    continue;

Il ciclo si romperà e l'app si libererà quando l'utente fa clic su uno dei pulsanti del pannello. (La digitazione nel campo di testo del pannello lascerà intatta la sessione modale.)

4) Nella gestione dei pulsanti, se la voce dell'utente non è valida, si chiama un avviso con RunModal.

5) Immediatamente sotto la chiamata di avviso, nel codice che eseguirà una volta licenziato l'allerta, si è messo lo stesso amato di cui sopra. La sessione modale del pannello riprende.

6) Nella gestione della tua chiusura del pannello, in caso di voce valida o annullamento, si chiama Endmodalsession, che, stranamente, non è sufficiente; Devi anche chiamare Stopmodal, anche se non hai mai chiamato RunModalForWindow.

[[NSApplication sharedApplication] endModalSession:self.modalSession];
[[NSApplication sharedApplication] stopModal];
[self.panelForInput close];
È stato utile?

Soluzione

La domanda è la risposta. Sto solo postando questo per chiuderlo. Ci scusiamo per aver tolto il formato stackoverflow.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top