Doppelklicken Sie auf eine NSTableView-Zeile in Cocoa?

72

Ich brauche meine Anwendung, um ein Fenster zu öffnen, wenn ein Benutzer auf eine Zeile in einem doppelklickt NSTableView. Es fällt mir schwer, Informationen oder Beispiele zu finden, wie dies erreicht werden kann. Kann mich jemand in die richtige Richtung weisen?

Allyn
quelle

Antworten:

137

Schauen Sie sich die -setDoubleAction:Methode in NSTableView an. Sie können dies auf eine Methode einstellen, die genau wie das normale Zielaktionssystem aufgerufen wird, jedoch mit einem Doppelklick.

In dieser Aktionsmethode -clickedRowwird nützlich sein.

Jim Puls
quelle
8
Gibt es eine Möglichkeit, dies über IB zu verbinden?
Ivan Vučica
25
Denken Sie auch daran, das Ziel für die Tabellenansicht mit setTarget: festzulegen, dumm, kann aber übersehen werden
nduplessis
1
Sollten Sie -setDoubleAction: als Delegatmethode implementieren oder ein IBOutlet iVar für die Tabelle erstellen und -setDoubleAction: auf dem iVar aufrufen?
Amateur Barista
2
@ IvanVučica Ja, du kannst es in IB verbinden. Siehe diese Antwort .
Rob Mayoff
2
@robmayoff 5 Jahre später \ o /
Ivan Vučica
56

Hinzufügen grundlegenderer Informationen zu @ JimPuls Antwort zum Nutzen anderer Kakao-Neulinge.

  1. Ein IBOutlet für NSTableView muss in einer Schnittstelle deklariert werden. Ich nahm an, dass dies im Delegierten der Tabelle bevorzugt wird.
  2. Das IBOutlet zur Tabelle muss über den Interface Builder verbunden werden. Dazu Strg-Drag & Drop in IB aus der Klasse, die den Ausgang zur Tabellenansicht deklariert. Wenn Sie die Maus loslassen, sollte ein Popup mit dem Namen der Steckdose angezeigt werden, die Sie in Schritt 1 deklariert haben. Wählen Sie das aus.
  3. Rufen Sie im Abschnitt @implementation für die Methode -awakeFromNib -setTarget: und -setDoubleAction: für das in Schritt 1 deklarierte und in Schritt 2 verbundene IBOutlet auf.

Hier ist ein Auszug aus meinem Delegierten für die Tabellenansicht. Ich habe meinen Delegaten auch als Datenquelle eingerichtet, daher werden sowohl die damit verbundenen NSTableViewDelegate- als auch die NSTabeViewDataSource-Schnittstellen angezeigt.

// Schnittstellenauszug.

@interface MyTableViewDelegate : NSObject <NSTableViewDelegate, NSTableViewDataSource>
{
  // This iVar needs to be connected to the table view via the IB.
  IBOutlet NSTableView *tableOutlet;
}

@property (assign) IBOutlet NSTableView *tableOutlet;

- (void)doubleClick:(id)nid;

@end

// Implementierungsauszug.

@implementation MyTableViewDelegate

@synthesize tableOutlet = _tableOutlet;

- (void)awakeFromNib {
  [_tableOutlet setTarget:self];
  [_tableOutlet setDoubleAction:@selector(doubleClick:)];
}

- (void)doubleClick:(id)object {
  // This gets called after following steps 1-3.
  NSInteger rowNumber = [_tableOutlet clickedRow];
  // Do something...
}

Hoffe das hilft.

Amateur Barista
quelle
10

Wie PR Singh sagte, können Sie Kakaobindungen verwenden, Sie können auch die ausgewählten Objekte weitergeben.

  1. Wählen Sie Ihre Tabellenansicht in IB aus und richten Sie diese beiden Bindungen im Inspektor für Bindungen wie folgt ein:

    >Double Click Target
    
    bind to = Application delegate object (or file owner)
    model key path = self
    selector name = myMethod:
    
    >Double Click Argument
    
    bind to = array controller
    controller key = selectedObjects
    selector name = myMethod:
    

Wo myMethod implementiert ist als

- (void)myMethod:(NSArray*)selectedObjects
{
    NSLog(@"%@", selectedObjects);
}

Dies ist auch hier dokumentiert: https://developer.apple.com/library/mac/qa/qa1472/_index.html

GeoffCoope
quelle
Wenn die Zeilen plötzlich nicht mehr auswählbar sind, haben Sie wahrscheinlich das ":" nach dem Selektornamen vergessen ...
Mojo66
9

Wenn jemand nach einer schnellen 2.0-Version sucht: Das funktioniert bei mir. Scheint viel einfacher als der Objective C-Code.

@IBOutlet weak var searchResultTable: NSTableView!

override func viewDidLoad() {
    super.viewDidLoad()
    searchResultTable.doubleAction = "doubleClickOnResultRow"
}

func doubleClickOnResultRow()
{
    print("doubleClickOnResultRow \(searchResultTable.clickedRow)")
}
Alfred Schilken
quelle
Das ist wirklich hilfreich. Für diejenigen, die mehr darüber erfahren möchten, besuchen doubleActionSie diesen Link .
Metropolis
2
Für Swift 3 wäre der FunktionswählersearchResultTable.doubleAction = #selector(doubleClickOnResultRow)
l
7

Sie können die Doppelklick-Aktion in Interface Builder verkabeln. Klicken Sie bei gedrückter Ctrl-Taste auf Ihre Tabellenansicht (stellen Sie sicher, dass Sie die Tabellenansicht erhalten , nicht die Bildlaufansicht oder die Clipansicht oder eine Tabellenspalte), um das Verbindungsfenster aufzurufen. Suchen Sie das Element "doubleAction" im Abschnitt "Gesendete Aktionen". Verbinden Sie es mit der IBAction Ihrer Wahl.

Rob Mayoff
quelle
Einfache Zitrone peasy. Sie können die angeklickte Zeile über die clickedRow-Methode der Tabellenansicht abrufen. Sie benötigen weiterhin die in Antwort Nummer zwei beschriebene Steckdose.
Joseph Ruth
Sie benötigen nicht unbedingt eine mit der Tabellenansicht verbundene Steckdose, da sich die Tabellenansicht als Absenderargument der Aktionsnachricht selbst bereitstellt.
Rob Mayoff
1

Unter SWIFT 4.1 Sie legen die doubleAction-Methode des TableView-Objekts in Ihrem Code so fest, dass eine @ objc-Funktion mithilfe eines #selector (nameOfYourFunction) ausgeführt wird.

Innerhalb dieser Funktion rufen Sie einen Segue auf. Sie können Ihr neues Fenster mit dem Ursprungsfenster von InterfaceBuilder verknüpfen (nicht mit dem NSTableView-Objekt, sondern mit dem eigentlichen ViewController-Objekt.

Führen Sie dann alle Einstellungen für das neue Fenster durch, um sich auf den Übergang vorzubereiten:

Okay zuerst auf Interface Builder:

Geben Sie hier die Bildbeschreibung ein

Geben Sie diesem Abschnitt natürlich eine Kennung:

Geben Sie hier die Bildbeschreibung ein

Als nächstes in unserem ersten View Controller (wo sich die Tabellenansicht befindet) Code:

 //We use this function: prepare for segue
override func prepare(for segue: NSStoryboardSegue, sender: Any?) {
        // check if we are referring to the actual segue we want
          if segue.identifier?.rawValue == "segueToYourNewWindow" {
    // now create a reference to that new window
            let yourNewWindow = segue.destinationController as! newWindowViewController
    // now change variables inside that view controller code, remember that the objects might fail if they are not yet visible to the user so first set up the variables or call them using the main thread, up to your design.
           yourNewWindow.selectedRowVariable = thisTableView.clickedRow
        }

Dann brauchen wir eine Funktion, um den Übergang zum Doppelklick der Tabellenansicht durchzuführen. Diese Funktion wird mit einem #selector aufgerufen und muss daher für Objective C sichtbar sein (auch wenn wir in Swift programmieren). Wir starten die Funktion einfach mit @ Objc das ist es.

@objc func doubleClickOnResultRow() {
//beware of double-clicking also triggers this function when no rows is selected with the selectedRow being -1
 if (thisTableView.selectedRow > -1 ) {
  performSegue(withIdentifier: NSStoryboardSegue.Identifier(rawValue: "segueToYourNewWindow"), sender: nil)
 }
}

Schließlich setzen wir diese Funktion auf die doubleAction-Methode der TableView im ersten Setup-Teil unseres Codes wie folgt:

override func viewDidLoad() {
    super.viewDidLoad()
    thisTableView.doubleAction = #selector(doubleClickOnResultRow)
}
Ryuuzaki Julio
quelle
1

Sie können dasselbe mit den Bindungen tun, indem Sie zunächst einen Mentod in der .h-Datei deklarieren

-(IBAction)openWindow:(id)sender

in der .m-Datei implementieren Sie das gleiche

-(IBAction)openWindow:(id)sender
{
    //do something here;
}

Gehen Sie zu der Spitze, in der Ihre Tabellenansicht vorhanden ist, wählen Sie die Tabellenansicht aus und erhalten Sie die vorletzte Registerkarte des Attributinspektors (Bindungen). Öffnen Sie das double click argumentOffenlegungsdreieck Der Name lautet "openWindow:". Der gleiche Vorgang wird mit der Offenlegung "Doppelklickziel" durchgeführt. Dies funktioniert

PR Singh
quelle
1

Alfreds Antwort für Swift 5 wurde aktualisiert

@IBOutlet weak var searchResultTable: NSTableView!

override func viewDidLoad() {
    super.viewDidLoad()
    searchResultTable.target = self
    searchResultTable.doubleAction = #selector(doubleClickOnResultRow)
}

@objc func doubleClickOnResultRow()
{
    print("doubleClickOnResultRow \(searchResultTable.clickedRow)")
}
iphaaw
quelle