19 Stimmen

NSPopover - Ausblenden beim Verlust des Fokus? (geklickt außerhalb des Popovers)

Ich verwende die doubleClickAction eines NSTableView, um ein NSPopover anzuzeigen. Etwas wie dies:

NSInteger selectedRow = [dataTableView clickedRow];
NSInteger selectedColumn = [dataTableView clickedColumn];

// Wenn nichts ausgewählt wurde, können wir nichts anzeigen.
if(selectedRow < 0 || selectedColumn < 0)
{
    NSLog(@"Ungültige Auswahl (%ld,%ld)", selectedRow, selectedColumn);
    return;
} // Ende der Auswahl war nicht möglich

// Konfigurieren unseres ViewController, sicherstellen, dass wenn bereits ein Popover angezeigt wurde, dass wir dieses zuerst beenden. Schließlich das neue Popover erstellen und anzeigen.
DataInspectorViewController * controller =
[[DataInspectorViewController alloc] initWithNibName: @"DataInspectorViewController"
                                              bundle: nil];

if(nil != dataPreviewPopover)
{
    [dataPreviewPopover close];
} // Ende des Popovers war bereits sichtbar

dataPreviewPopover = [[NSPopover alloc] init];
[dataPreviewPopover setContentSize:NSMakeSize(400.0f, 400.0f)];
[dataPreviewPopover setContentViewController:controller];
[dataPreviewPopover setAnimates:YES];
[dataPreviewPopover showRelativeToRect: [dataTableView frameOfCellAtColumn: selectedColumn row: selectedRow]
                     ofView: dataTableView
              preferredEdge: NSMinYEdge];

Was einwandfrei funktioniert. Meine Popovers werden erstellt und entfernt, wenn ich auf die Zellen doppelklicke. Das Problem ist, dass ich möchte, dass das Popover verschwindet, wenn ich irgendwo außerhalb davon klicke (wie ein einfacher Klick auf eine andere Zelle). Ich habe herumgesucht, aber ich kann einfach nicht herausfinden, wie man es macht.

Das ist etwas, was ich vermute, dass in ein Popover eingebaut ist, (ich bin mir ziemlich sicher, dass es in der iOS UIPopoverController-Klasse war), also frage ich mich nur, ob ich etwas Einfaches übersehen habe.

69voto

sergeyne Punkte 1258

Sie müssen das Eigenschaftsverhalten Ihres Popovers (im Code oder im Interface Builder) ändern auf:

popover.behavior = NSPopover.Behavior.transient;

NSPopover.Behavior.transient
Das System schließt das Popover, wenn der Benutzer mit einem Benutzeroberflächenelement außerhalb des Popovers interagiert.

Erfahren Sie mehr darüber in der Apple-Dokumentation.

14voto

Confused Vorlon Punkte 8497

Die .transient Flagge funktioniert für mich nicht.

Ich kann jedoch Dinge zum Laufen bringen, indem ich Folgendes mache:

1) Immer wenn ich mein Popover anzeige, stelle ich sicher, dass ich die App aktiviere (meine App ist eine Menüleisten-App, also passiert das nicht automatisch)

NSApp.activate(ignoringOtherApps: true)

2) Wenn ich außerhalb der App klicke, wird meine App deaktiviert. Dies kann ich im AppDelegate erkennen

func applicationWillResignActive(_ notification: Notification) {
    print("deaktivieren")
}

und entsprechend handeln

2voto

Lal Krishna Punkte 13960

Nachdem Sie die Methode show(relativeTo:of:preferredEdge:) aufgerufen haben,

Fügen Sie die folgende Zeile hinzu

popover.contentViewController?.view.window?.makeKey()

Und stellen Sie sicher, dass Sie

popover.behavior = .transient

Entschuldigung, ich habe die Lösung in Swift hinzugefügt.

0voto

vauxhall Punkte 2700

Während transient für die meisten Fälle funktionierte, gab es ein Problem, wenn der Benutzer mit Elementen außerhalb der Anwendung interagierte, da das Popover sich versteckte, aber nicht geschlossen wurde.

Was schließlich für mich funktioniert hat war:

popover.behavior = .semitransient

Jetzt schließt sich das Popover beim Wechsel der App oder bei der Interaktion mit einem anderen Element außerhalb der App. Es wird sich jedoch nicht schließen, wenn man mit einem NSMenu interagiert, und vielleicht auch nicht mit anderen Interaktionen.

Laut der Dokumentation für NSPopover.Behavior.semitransient:

Die genauen Interaktionen, die dazu führen, dass semi-transiente Popovers sich schließen, sind nicht spezifiziert.

Ähnlich wie in der Dokumentation für NSPopover.Behavior.transient:

Die genauen Interaktionen, die dazu führen, dass transient popovers sich schließen, sind nicht spezifiziert.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X