Implementare Delegato Metodo NSTextField

0

Domanda

Sto cercando di implementare un metodo di delegato in NSTextField come descritto in questo articolo da parte di Apple. Il mio obiettivo è per il NSTextField per accettare i ritorni a capo e schede. Ho letto altrove (tra cui l'articolo linkato) che NSTextView è una scelta migliore. Tuttavia, sto lavorando all'interno di un framework multipiattaforma che manca il supporto per NSTextViewe NSTextField fare il lavoro se riesco a farlo accettare i ritorni a capo.

Basata sull'articolo, ecco il mio codice:

@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

Inoltre, l'Identità di Ispezione del campo di testo, ho cambiato il nome della classe predefinita NSTextField il mio nome di classe. Tuttavia, quando ho eseguito il mio programma, il metodo delegato non viene chiamato. C'è qualcos'altro che devo fare per impostare questo in Interface Builder?

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

Migliore risposta

0

Ci sono alcune parti della documentazione legata pertinente che penso che potrebbe essere stato trascurato.

Ho copiato un paio di righe sotto:

Se si decide di continuare a utilizzare NSTextField, consentendo il tasto tab e/o consentendo l'invio e la restituzione delle chiavi per interruzioni di linea può essere raggiunto attraverso l'applicazione dei seguenti delegato metodo:

  • (BOOL)controllo:(NSControl*)controllo textView:(NSTextView*)textView doCommandBySelector:(SEL)commandSelector;

Nota: Quando si implementa questo delegato metodo in oggetto proprio l'oggetto come "delegato" per questo NSTextField.

Ho in grassetto alcune delle didascalie che penso che potrebbe essere stato perso.

Questo metodo è all'interno del NSControlTextEditingDelegate protocollo entro NSControl.h. Come tale dovrebbe essere implementata da una classe che implementa l' NSControlTextEditingDelegate (cioè NSTextFieldDelegate)

Un modo comune per fare questo è quello di avere il ViewController "holding" la NSTextField essere il NSTextFieldDelegate.

Ecco un esempio molto semplice utilizzando il codice di esempio da Apple è collegata:

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

Quindi impostare il vostro NSTextField delegato il ViewController

Set_Text_Field_Delegate

Non c'è bisogno di aggiungere un custom sottoclasse.

In alternativa si potrebbe probabilmente rendere il campo di testo personalizzato sottoclasse suo delegato. Qualcosa lungo queste linee:

#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

Ho fatto finalmente capire questo utilizzando il ViewController modello che hai dato. Mi segna questo come una risposta, e la ringrazio. Potrebbe essere utile includere che per fare il View Controller oggetto di un delegato di destinazione, è necessario trascinare un view controller dalla libreria palette per la colonna di sinistra della finestra e quindi cambiare la sua classe nella finestra di ispezione. (Che è, assume so assolutamente nulla di IB, che andando in questo progetto che mi è stato vicino.) Inoltre, non ho incluso viewDidLoad o setRepresentedObject nella mia implementazione, ma sembra funzionare. Problema?
rpatters1

@rpatters1 Contento che la risposta ha aiutato. Quando si crea un nuovo macOS app Xcode crea un default ViewController di classe, che è quello che ho usato nell'esempio qui. viewDidLoad e setRepresentedObject vengono aggiunti automaticamente a questa classe di default (che è il motivo per cui li ho lasciati qui) anche se non dovrebbe modificare la funzionalità a tutti, come avrete notato.
R4N

Sto lavorando ad un plugin per un host-app che fornisce supporto cross-platform per le finestre di dialogo. Quindi, il mio progetto non ebbe View Controller a tutti fino a quando non ho aggiunto.
rpatters1

In altre lingue

Questa pagina è in altre lingue

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