Wdrożenie metody delegowania w polu NSTextField

0

Pytanie

Staram się wdrożyć metody delegowania na NSTextField jak opisano w tym artykule od Apple. Moim celem jest, aby NSTextField do odbioru zwrotów karetki i kart. Czytałem w innym miejscu (w tym związanych z artykułu), że NSTextView jest to najlepszy wybór. Jednak pracuję w ramach wieloplatformowy struktury, w której brak obsługi NSTextViewi NSTextField wykonam tę pracę, jeśli mogę zmusić go do przyjęcia powrót karetki.

Opierając się na artykule, oto mój kod:

@interface MyTextFieldSubclass : NSTextField
{}
- (BOOL)control:(NSControl*)control textView:(NSTextView*)textView doCommandBySelector:(SEL)commandSelector;
@end

@implementation MyTextFieldSubclass
- (BOOL)control:(NSControl*)control textView:(NSTextView*)textView doCommandBySelector:(SEL)commandSelector
{
   BOOL result = NO;

   if (commandSelector == @selector(insertNewline:))
   {
      // new line action:
      // always insert a line-break character and don’t cause the receiver to end editing
      [textView insertNewlineIgnoringFieldEditor:self];
      result = YES;
   }
   else if (commandSelector == @selector(insertTab:))
   {
      // tab action:
      // always insert a tab character and don’t cause the receiver to end editing
      [textView insertTabIgnoringFieldEditor:self];
      result = YES;
   }

   return result;
}
@end

Ponadto, w inspektorze identyfikacji pola tekstowego zmieniłem nazwę klasy domyślnie NSTextField do tytułu mojej klasy. Jednak, gdy uruchamiam swój program, metody delegata nigdy nie jest wywoływana. Czy jest coś jeszcze, co powinienem zrobić, aby skonfigurować to w budowniczy interfejsów?

cocoa interface-builder objective-c
2021-11-17 17:05:19
1

Najlepsza odpowiedź

0

Istnieje kilka części dokumentacji, które się połączyły, które odnoszą się do rzeczy, i myślę, że się nimi, być może, zaniedbane.

Skopiowałem kilka wierszy poniżej:

Jeśli zdecydujesz się kontynuować korzystanie z NSTextField, rozdzielczość klawisza tab i/lub rozdzielczość klawiatury i powrócić do podziałów może być osiągnięte poprzez wdrożenie nowej metody delegowania:

  • (BOOL)element sterujący:(NSControl*)element zarządzania TextView:(NSTextView*)Element zarządzania TextView docomandbyselector:(SEL)element zarządzania zespołami;

Uwaga: Przy realizacji tej metody delegowania w swoim własnym obiekcie należy skonfigurować swój obiekt jako "delegat" dla tego pola NSTextField.

Wyróżnić pogrubioną czcionką kilka выносков, które, jak mi się wydaje, może być pominięte.

Ta metoda jest w zasięgu NSControlTextEditingDelegate protokół w NSControl.h. Jako taki, powinien być realizowany w klasie, który realizuje NSControlTextEditingDelegate (tj. NSTextFieldDelegate)

Jednym z najczęstszych sposobów, aby to zrobić-zrobić tak, aby ViewController, "utrzymujący" pole NSText, był NSTextFieldDelegate.

Oto bardzo prosty przykład zastosowania przykład kodu z Apple, który związany:

ViewController.h

#import <Cocoa/Cocoa.h>

@interface ViewController : NSViewController <NSTextFieldDelegate>


@end

ViewController.m

#import "ViewController.h"

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // Do any additional setup after loading the view.
}


- (void)setRepresentedObject:(id)representedObject {
    [super setRepresentedObject:representedObject];

    // Update the view, if already loaded.
}

- (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector {
    BOOL result = NO;
     
        if (commandSelector == @selector(insertNewline:))
        {
            // new line action:
            // always insert a line-break character and don’t cause the receiver to end editing
            [textView insertNewlineIgnoringFieldEditor:self];
            result = YES;
        }
        else if (commandSelector == @selector(insertTab:))
        {
            // tab action:
            // always insert a tab character and don’t cause the receiver to end editing
            [textView insertTabIgnoringFieldEditor:self];
            result = YES;
        }
     
    return result;
}


@end

Następnie zaznacz pełnomocnik twojego NSTextField w ViewController

Set_Text_Field_Delegate

Nie ma potrzeby, aby dodać niestandardowy podklasy.

Alternatywnie, prawdopodobnie mógłby zrobić podklasa niestandardowego pola tekstowego własnym delegatem. Coś w tym rodzaju:

#import "MyTextFieldSubclass.h"

@interface MyTextFieldSubclass() <NSTextFieldDelegate>
@end

@implementation MyTextFieldSubclass

- (instancetype)init {
    self = [super init];
    if (self) {
        self.delegate = self;
    }
    return self;
}

- (instancetype)initWithCoder:(NSCoder *)coder {
    self = [super initWithCoder:coder];
    if (self) {
        self.delegate = self;
    }
    return self;
}

- (instancetype)initWithFrame:(NSRect)frameRect {
    self = [super initWithFrame:frameRect];
    if (self) {
        self.delegate = self;
    }
    return self;
}

- (void)drawRect:(NSRect)dirtyRect {
    [super drawRect:dirtyRect];
    
    // Drawing code here.
}

- (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector {
    BOOL result = NO;

       if (commandSelector == @selector(insertNewline:))
       {
          // new line action:
          // always insert a line-break character and don’t cause the receiver to end editing
          [textView insertNewlineIgnoringFieldEditor:self];
          result = YES;
       }
       else if (commandSelector == @selector(insertTab:))
       {
          // tab action:
          // always insert a tab character and don’t cause the receiver to end editing
          [textView insertTabIgnoringFieldEditor:self];
          result = YES;
       }

       return result;
}

@end
2021-11-18 01:22:32

W końcu zdałem sobie sprawę, to, korzystając z szablonu ViewController, który dałeś. Ja zauważam to jak odpowiedź i dziękuję. Być może, warto byłoby uwzględnić, że do tego, aby obiekt kontrolera widoku dostępne jako obiektu docelowego pełnomocnika, należy przeciągnąć kontroler widoku z palety biblioteki w lewa kolumna okna, a następnie zmienić jego klasa w inspektorze. (Czyli załóżmy, że ja nic nie wiem o IB, do którego przystępując do tego projektu, byłem blisko.) Ponadto, nie włączył viewDidLoad lub setRepresentedObject w jego realizację, ale wygląda na to, że to działa. Problem?
rpatters1

@rpatters1 Cieszę się, że odpowiedź pomógł. Podczas tworzenia nowej aplikacji macOS w Xcode jest tworzony klasa ViewController domyślny, który użyłem w powyższym przykładzie. viewDidLoad i setRepresentedObject automatycznie dodawane do tej klasy domyślnie (dlatego zostawiłem je tutaj), choć, jak pan zauważył, to nie powinno zmieniać funkcjonalność w ogóle.
R4N

Pracuję nad wtyczką do aplikacji hosta, który zapewnia кроссплатформенную wsparcie okien dialogowych. Tak więc, w moim projekcie w ogóle nie było kontrolera widoku, zanim go dodał.
rpatters1

W innych językach

Ta strona jest w innych językach

Русский
..................................................................................................................
Italiano
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................