【问题标题】:Detect paste on NSTextField检测 NSTextField 上的粘贴
【发布时间】:2013-07-26 12:50:42
【问题描述】:

我正在尝试处理 NSTextField 上的粘贴操作。

我找到了similar article,但找到了NSTextView。我通过覆盖NSTextField 并输入:

尝试了类似的代码
- (BOOL)readSelectionFromPasteboard:(NSPasteboard *)pboard
{
    return [super readSelectionFromPasteboard: pboard];
}

但这个方法似乎永远不会被调用。

关于如何在 NSTextField 上检测过去有什么建议吗?

【问题讨论】:

    标签: macos cocoa nstextfield


    【解决方案1】:

    您可以使用NSTextFieldDelegate 委托方法- (BOOL) control:(NSControl*) control textView:(NSTextView*) textView doCommandBySelector:(SEL) commandSelector 并注意paste: 选择器。

    【讨论】:

      【解决方案2】:
      1. 覆盖 becomeFirstResponderNSTextField 方法

      2. 使用object_setClass 覆盖“字段编辑器”的类(即处理所有NSTextField 实例的文本输入的NSTextViewsee here

      #import <AppKit/AppKit.h>
      #import <objc/runtime.h>
      
      @interface MyTextField : NSTextField
      @end
      
      @implementation MyTextField
      
      - (BOOL)becomeFirstResponder
      {
        if ([super becomeFirstResponder]) {
          object_setClass(self.currentEditor, MyFieldEditor.class);
          return YES;
        }
        return NO;
      }
      
      @end
      
      1. 创建您的MyFieldEditor 类并覆盖其paste: 方法
      @interface MyFieldEditor : NSTextView
      @end
      
      @implementation MyFieldEditor
      
      - (void)paste:(id)sender
      {
        // Get the pasted text.
        NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
        NSString *text = [pasteboard stringForType:NSPasteboardTypeString];
        NSLog(@"Pasted: %@", text);
      
        // Set the pasted text. (optional)  
        [pasteboard clearContents];
        [pasteboard setString:@"Hello world" forType:NSPasteboardTypeString];
      
        // Perform the paste action. (optional)
        [super paste:sender];
      }
      
      @end
      

      全部完成!现在您可以拦截每个粘贴操作。

      【讨论】:

        【解决方案3】:

        结合此处找到的 2 个答案,我能够找到一种解决方法,但有必要将 NSTextFieldNSTextFieldCellNSTextView 子类化。

        斯威夫特 5

        1.

        子类NSTextView,这里是截取实际粘贴的地方,可以替换内容。

        final class TextView: NSTextView {
            override func paste(_ sender: Any?) {
                var content = NSPasteboard.general.string(forType: .string) ?? ""
        
                // modify content
        
                NSPasteboard.general.clearContents()
                NSPasteboard.general.setString(content, forType: .string)
                super.paste(sender)
            }
        }
        

        2.

        子类NSTextFieldCell 并用您自己的NSTextView 覆盖fieldEditorFor。将NSTextView 的属性isFieldEditor 设置为true 很重要。

        final class TextFieldCell: NSTextFieldCell {
            private let textView = TextView()
            
            required init(coder: NSCoder) {
                super.init(coder: coder)
            }
        
            override init(textCell: String) {
                super.init(textCell: textCell)
                textView.isFieldEditor = true
            }
            
            override func fieldEditor(for: NSView) -> NSTextView? {
                textView
            }
        }
        

        3.

        子类NSTextField 并分配给静态属性cellClass 你自己的NSTextFieldCell。如果您只是将自己的NSTextFieldCell 分配给所有NSTextField,则可以避免最后一步,即NSTextField.cellClass = yourCellClass

        final class TextField: NSTextField {
            required init?(coder: NSCoder) {
                nil
            }
        
            init() {
                TextField.cellClass = TextFieldCell.self
                super.init(frame: .zero)
            }
        }
        
        

        【讨论】:

          【解决方案4】:

          覆盖 NSTextFieldCell 并放置。

           ///////////////////////////////////////////
           //BPastTextFieldCell.h
           //
           @interface BPastTextView : NSTextView <NSTextViewDelegate>
           @end
          
           @class BPastTextFieldCell ;
           @interface BPastTextFieldCell : NSTextFieldCell
          
           @end
          
          
          
          
            //////////////////////////////////////////
            //
            //BPastTextFieldCell.m 
            //
          
            #import "BPastTextFieldCell.h"
          
            @implementation BPastTextFieldCell
          
            - (NSTextView *)fieldEditorForView:(NSView *)controlView{
               BPastTextView *textView = [[BPastTextView alloc] init];
                return textView;
            }
            @end
          
          
          
          
            @implementation BPastTextView
          
            - (void)keyDown:(NSEvent *)theEvent {
          
                bool bHandled = false;
                if ([theEvent modifierFlags] & NSEventModifierFlagCommand)
                {
                    NSResponder * responder = [[self window] firstResponder];
                    if ((responder != nil) && [responder isKindOfClass[NSTextView class]])
                    {
                        NSTextView * textView = (NSTextView *)responder;
                        NSRange range = [textView selectedRange];
                        bool bHasSelectedTexts = (range.length > 0);
                        unsigned short keyCode = [theEvent keyCode];
          
                        if (keyCode == 6)  //command + Z
                        {
                            if ([[textView undoManager] canUndo])
                            {
                                [[textView undoManager] undo];
                                bHandled = true;
                            }
                        }
                        else if (keyCode == 7 && bHasSelectedTexts) // command + X
                        {
                            [textView cut:self];
                            bHandled = true;
                        }
                        else if (keyCode== 8 && bHasSelectedTexts)  // command + C
                        {
                            [textView copy:self];
                            bHandled = true;
                        }
                        else if (keyCode == 9)   // command + V
                        {
                            [textView paste:self];
                            bHandled = true;
                        }
                    }
                }
                if(bHandled)
                    return;
          
                [super keyDown:theEvent];
          
            }
          
            @end
          

          【讨论】:

            【解决方案5】:

            nstextfield 没有复制和粘贴功能。这些只能在 nstextview 中找到。问题是,当编辑文本字段时,它会在编辑过程中打开一个名为 fieldeditor 的文本视图。

            在这里查看我的答案:

            NSTextField: exposing its Copy and Paste methods

            【讨论】:

              【解决方案6】:

              这是我用来检测 UITextField 中的粘贴:

              // Set this class to be the delegate of the UITextField. Now when a user will paste a text in that textField, this delegate will be called.
              -(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
              
                  // Here we check if the replacement text is equal to the string we are currently holding in the paste board
                  if ([string isEqualToString:[UIPasteboard generalPasteboard].string]) {
              
                      // code to execute in case user is using paste
              
                  } else {
              
                      // code to execute other wise
                  }
              
                  return YES;
              }
              

              【讨论】:

              • 鼻祖专门询问了NSTextField。 UITextField ≠ NSTextField。
              猜你喜欢
              • 1970-01-01
              • 2010-12-08
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-11-05
              • 1970-01-01
              相关资源
              最近更新 更多