Implementar el Método de Delegado en NSTextField

0

Pregunta

Estoy tratando de implementar un método de delegado en NSTextField como se describe en este artículo de Apple. Mi objetivo es que el NSTextField para aceptar retornos de carro y pestañas. He leído en otro lugar (incluyendo el artículo enlazado) que NSTextView es una mejor opción. Sin embargo, estoy trabajando en una multiplataforma marco que carece de soporte para NSTextViewy NSTextField va a hacer el trabajo si puedo llegar a aceptar retornos de carro.

Basado en el artículo, aquí está mi código:

@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

Además, en la Identidad del Inspector del campo de texto, he cambiado el nombre de la clase de la predeterminada NSTextField a mi el nombre de la clase. Sin embargo, cuando ejecuto mi programa, el delegado método nunca se llama. ¿Hay algo más que tengo que hacer para configurar esto en el Interface Builder?

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

Mejor respuesta

0

Hay un par de partes de la documentación vinculada que es pertinente que creo que puede haber sido descuidado.

He copiado algunas de las líneas más abajo:

Si usted decide seguir utilizando NSTextField, permitiendo la tecla tab y/o permitiendo entrar y volver claves para los saltos de línea se puede lograr mediante la aplicación de los siguientes delegado método:

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

Nota: Cuando la aplicación de este delegado método en su propio objeto debe establecer su objeto como el "delegado" para este NSTextField.

He resaltado algunas de las llamadas que creo que podría haber sido pasada por alto.

Este método está dentro de la NSControlTextEditingDelegate protocolo dentro de NSControl.h. Como tal debe ser implementado por una clase que implementa la NSControlTextEditingDelegate (es decir, NSTextFieldDelegate)

Una manera común de hacer esto es tener el ViewController "explotación" de la NSTextField ser el NSTextFieldDelegate.

He aquí un ejemplo muy sencillo utilizar el código de ejemplo de Apple, vinculado:

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

A continuación, establezca su NSTextField del delegado para el ViewController

Set_Text_Field_Delegate

No hay necesidad de agregar una subclase personalizada.

Alternativamente, usted probablemente podría hacer que el campo de texto personalizado subclase su propio delegado. Algo a lo largo de estas líneas:

#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

Me hizo finalmente la figura de este cabo utilizando el ViewController patrón le dio. Voy a marcar esto como una respuesta, y muchas gracias. Podría ser útil incluir a los que con el fin de hacer que el Controlador de Vista del objeto como un delegado de destino, usted tiene que arrastrar un controlador de vista de la biblioteca de la paleta a la columna de la izquierda de la ventana y, a continuación, cambiar su clase en el inspector. (Es decir, asumir sé absolutamente nada acerca de IB, que va en este proyecto en el que estaba cerca.) Además, yo no incluyen viewDidLoad o setRepresentedObject en mi aplicación, sin embargo, parece que funciona. Problema?
rpatters1

@rpatters1 Contento de la respuesta ayudado. A la hora de crear un nuevo macOS aplicación en Xcode crea por defecto un ViewController clase que es lo que he usado en el ejemplo aquí. viewDidLoad y setRepresentedObject se agregan automáticamente a este defecto de la clase (que es la razón por la que me dejó aquí) aunque no se debe cambiar la funcionalidad en todos los como usted ha dicho.
R4N

Estoy trabajando en un plugin para un host de la aplicación que proporciona una cruz-plataforma de apoyo para los cuadros de diálogo. Por lo tanto, mi proyecto no tenía Controlador de Vista hasta que lo he añadido.
rpatters1

En otros idiomas

Esta página está en otros idiomas

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