OSX Swift NSTextField Unterbinden, dass bei betätigen der ENTER-Taste zum nächsten NSTextField gesprungen wird.

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • OSX Swift NSTextField Unterbinden, dass bei betätigen der ENTER-Taste zum nächsten NSTextField gesprungen wird.

    Hallo,

    folgendes beschäftigt mich gerade sehr. Ein NSViewController enthält mehrere Eingabefelder vom Typ NSTextField, welche wiederum ihre eigenen Action Funktionen inne haben. Im Augenblick kann der Anwender die TAB-Taste bzw. die ENTER-Taste verwenden um zum nächsten NSTextField zu gelangen. Hier genau liegt auch schon meine Herausforderung. Wie kann ich es unterbinden, dass die Eingabefelder auf die ENTER-Taste reagieren bzw. das nächste Eingabefeld selektiert wird? Also alle in diesem NSViewController enthaltenen Eingabefelder vom Typ NSTextField sollen nur auf die TAB-Taste und nicht auf die ENTER-Taste reagieren.

    Mein Ansatz lt. eine neue Klasse anlegen und diese allen Eingabefeldern zuweisen:

    Quellcode

    1. class MyTextField: NSTextField {
    2. // und nun sehe ich den Wald vor lauter Bäumen nicht mehr
    3. }
    Ich hoffe mal mein Vorgehen stimmt soweit? Vielleicht kann mir hier noch jemand einen Tipp oder ein Beispiel posten wie ich nun weiter vorgehen muss. Gibt es eine Möglichkeit die ENTER-TASTE für diesen VC völlig abzuschalten, wäre dies der bessere Weg?

    Danke mal vorab.
  • Ohne es jetzt tiefer recherchiert zu haben: Es gibt eine Delegate-Methode doControlBySelector, mit der müsstest Du den selector insertNewLine abfragen können und dann YES zurückgeben. Dein Controller muss dann natürlich Delegate der NSTextFields sein.

    Ist aber wirklich ungetestet, nur ein Gedankenanstoß...

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von MyMattes ()

  • MyMattes schrieb:

    Ohne es jetzt tiefer recherchiert zu haben: Es gibt eine Delegate-Methode doControlBySelector, mit der müsstest Du den selector insertNewLine abfragen können und dann YES zurückgeben. Dein Controller muss dann natürlich Delegate der NSTextFields sein.

    Ist aber wirklich ungetestet, nur ein Gedankenanstoß...

    Mattes
    @MyMattes: Danke

    Werde es probieren und hoffen, dass es mich zu Ziel bringt. Im übrigen bin ich nun mit meinem obigen Ansatz etwas weitergekommen. Nur wie werden jetzt die einzelnen ACTION Funktionen der jeweiligen Textfelder aufgerufen bzw. gesteuert? ?( Muss ich nun eine Variable auf TRUE setzen und diese in den jeweiligen ACTION Funktionen abfragen? Das geht doch bestimmt einfacher?

    Quellcode

    1. class MyTextField: NSTextField {
    2. override func mouseDown(theEvent:NSEvent) {
    3. // Nun bin ich mir nicht sicher wie es weitergehen müsste?
    4. // Eigentlich müsste an dieser Stelle nun die ACTION des
    5. // jeweiligen Textfeldes abgearbeitet werden. Nur wie rufe ich
    6. // dieses auf???
    7. }
    8. }

    P.S.: Vielleicht sitze ich hier heute schon ein wenig zu lange. :rolleyes:

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von OSXDev ()

  • MyMattes schrieb:

    ?( Was hat jetzt mouseDown mit der Return-Taste zu tun...? Oder der Enter-Taste (meintest Du wirklich die)...?
    War gestern einfach schon zu müde. :D

    Meine Überlegung war, dass die zugehörige Action Funktion des Textfeldes beim selektieren derer, nur auf die Maustaste reagiert. Die Verarbeitung sollte nach verlassen - gedrückter TAB-Taste, nicht ENTER-TASTE - bzw. beim Selektieren des nächsten Eingabefeldes durchgeführt werden. Um nicht alle entsprechenden Action Funktionen ändern zu müssen, wollte ich eine neue Klasse vom Typ NSTextField erstellen und diese allen Objekten vom Typ NSTextField zuweisen. Nur bin ich mir an dieser Stelle nicht sicher, wie ich die verschiedenen Action Funktionen für die Abarbeitung aufrufen kann? ;(

    Auch musste ich feststellen, dass nur ein Objekt vom Typ NSButton, ein Ergebnis hinsichtlich gedrücktem MouseButton bzw. gedrückter TAB-, ENTER-Taste liefert. ?(

    Bei einem NSTextField erhalte ich nur ein Ergebnis hinsichtlich einer gedrückten ENTER- bzw. TAB-Taste, nicht jedoch einer MouseButton.

    Der Anwender kann nach der Eingabe im Textfeld die ENTER-Taste drücken. Diese verlässt dann das aktuelle TextFeld und springt zum nächsten.

    Nun meine Fragen hierzu:

    1. Wie kann ich feststellen, dass ein Objekt vom Typ NSTextField via MouseButton selektiert wurde? Mit NSEvent.EventType.leftMouseUp funktioniert dies in diesem Kontext bei mir nicht.
    2. Wie kann ich innerhalb eines Objektes vom Typ NSTextField herausfinden welche Taste (ENTER- bzw. TAB-Taste oder MouseButton) gedrückt wurde?

    Mit NSEvent.EventType.keyDown kann ich nicht zwischen TAB- bzw. ENTER-TASTE unterscheiden, oder?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von OSXDev ()

  • Tolibi schrieb:

    OSXDev schrieb:

    Wie kann ich es unterbinden, dass die Eingabefelder auf die ENTER-Taste reagieren bzw. das nächste Eingabefeld selektiert wird?
    Wieso aktiviert die Enter Taste überhaupt das nächste Feld? Normalerweise wird doch der gesamte Text ausgewählt.
    Wurde so vorgesehen. Ich hoffe ich muss nicht den ganzen Sourcecode ändern um die o.g. Änderung einpflegen zu können.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von OSXDev ()

  • MyMattes schrieb:

    Hast Du die von mir genannte Delegate-Methode ausprobiert...? Ich habe den Eindruck, Du denkst zu kompliziert.
    Da könntest Du wohl richtig liegen. Warum einfach wenn es auch kompliziert geht. :D

    Bin auch noch nicht wirklich wach. Café hilft heute auch nur bedingt. :)

    Bin gerade dabei eine Beispielapp bzgl. Deines Vorschlages zu realisieren. Melde mich nach Fertigstellung.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von OSXDev ()

  • @MyMattes

    Habe Deinen Vorschlag mal in einer Testapp implementiert. Hat auch soweit funktioniert. Zwecks Prüfung habe ich das Objekt ausgegeben s.u.:

    TextField was changed!
    insertNewLine = Optional(<NSTextView: 0x600003309a40>
    Frame = {{2.00, 2.00}, {232.00, 17.00}}, Bounds = {{0.00, 0.00}, {232.00, 17.00}}
    Horizontally resizable: YES, Vertically resizable: YES
    MinSize = {232.00, 17.00}, MaxSize = {40000.00, 40000.00}
    )

    Nur wie hilf mir diese jetzt die Unterscheidung durchzuführen? Regiert wird nach wie vor auf beide Tasten?
  • Google doch einfach einmal die in meinem Posting fett hervorgehobenen Begriffe, dann findest Du Code-Bespiele, wie man die betätigte Taste identifizieren kann. Spezifisch brauchst Du eigentlich nichts mehr machen, außer dem Control mitteilen, dass die Standardbehandlung nicht mehr durchgeführt werden soll. Soweit zumindest meine Überlegung...

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • MyMattes schrieb:

    Google doch einfach einmal die in meinem Posting fett hervorgehobenen Begriffe, dann findest Du Code-Bespiele, wie man die betätigte Taste identifizieren kann. Spezifisch brauchst Du eigentlich nichts mehr machen, außer dem Control mitteilen, dass die Standardbehandlung nicht mehr durchgeführt werden soll. Soweit zumindest meine Überlegung...

    Mattes
    Dies habe ich selbstverständlich durchgeführt. Die Ergebnismenge war überschaubar. ;)

    Die geringe Anzahl von Lösungen zu diesem Thema hat mich doch sehr ins Grübeln gebracht. ?(

    Ein Café geholt und während dessen über den ganzen Algorithmus nachgedacht, erspart einem doch eine ganze Menge Arbeit. :D

    Eine einfachere Lösung ist mir dabei auch eingefallen.


    Vielen Dank für die Anregungen
  • OSXDev schrieb:

    Die geringe Anzahl von Lösungen zu diesem Thema hat mich doch sehr ins Grübeln gebracht. ?(
    Naja, das ist ja nichts schlimmes, wenn die Lösung dabei ist. Das "Technical Q&A" von Apple zeigt Dir z. B. alles, was Du brauchst. Ich war nun auch neugierig und habe es einmal ausprobiert: Das reine Implementieren der Delegate-Methode und Zurückgeben von YES (="ich habe mich schon um alles gekümmert, mach' nix") bei einem <Enter> reicht aus:

    Quellcode

    1. - (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector
    2. {
    3. NSLog(@"control: %@\ntextView: %@\nselector: %@", control, textView, NSStringFromSelector(commandSelector));
    4. BOOL result = (commandSelector == @selector(insertNewline:)) ? YES : NO;
    5. return result;
    6. }

    OSXDev schrieb:

    Eine einfachere Lösung ist mir dabei auch eingefallen.
    Lässt Du uns teilhaben?

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • MyMattes schrieb:

    OSXDev schrieb:

    Die geringe Anzahl von Lösungen zu diesem Thema hat mich doch sehr ins Grübeln gebracht. ?(
    Naja, das ist ja nichts schlimmes, wenn die Lösung dabei ist. Das "Technical Q&A" von Apple zeigt Dir z. B. alles, was Du brauchst. ...


    Lässt Du uns teilhaben?

    Mattes
    @MyMattes:
    Da hast Du mich missverstanden. Selbstverständlich ist es nicht tragisch - im Gegenteil es zeigt mir, dass meine Vorgehensweise evtl. nicht den optimale Lösungsweg darstellt. 8)

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von OSXDev ()

  • MCDan schrieb:

    Es wäre sehr schön, wenn Du die Lösung dann auch hier zur Verfügung stellen würdest. ;)
    @MCDan , @MyMattes :
    Vorgehensweise inkl. Beispiel-Sourcecode s.u..


    Erst einmal wird der Pointer auf das NSEvent des aktuellen NSViewController benötigt.

    Erklärung ist hier zu finden:
    Xcode Swift 4 OSX NSButton Wie stelle ich fest ob ein Button mit einem Mausklick bzw. mit der Enter-Taste betätigt wurde?

    Mit dem nachfolgenden Sourcecode wird der KeyCode der gedrückten Taste ermittelt und ausgegeben:

    Quellcode

    1. override func viewDidAppear()
    2. {
    3. view.window?.makeFirstResponder(self)
    4. }
    5. override func keyDown(with theEvent: NSEvent)
    6. {
    7. print("\nEvent KeyCode: ", theEvent.keyCode)
    8. switch theEvent.keyCode
    9. {
    10. case 36:
    11. // Verarbeitung ENTER-Taste
    12. case 48:
    13. // Verarbeitung TAB-Taste
    14. case 49:
    15. // Verarbeitung SPACE-Taste
    16. default:
    17. // Do nothing!
    18. }
    19. }
    Alles anzeigen
    So erspare ich mir viel Arbeit und Zeit. Diese Lösung ist für dieses Problem ein guter Ansatz..


    Viel Spaß :thumbsup:

    Dieser Beitrag wurde bereits 6 mal editiert, zuletzt von OSXDev ()