如何创建一个在编辑模式下显示自定义视图而不是NSTextField的NSTextFieldCell? [英] How to create a NSTextFieldCell, that in edit mode displays a custom view instead of NSTextField?

查看:139
本文介绍了如何创建一个在编辑模式下显示自定义视图而不是NSTextField的NSTextFieldCell?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个tableView,其中3列包含NSTextFieldCell.一切都充满了绑定.

I have a tableView, with 3 columns containing NSTextFieldCell. Everything is populated with bindings.

该列之一的单元格的文本是计算得出的,不能直接编辑. 对于此列,我希望当单元格进入编辑模式时显示按钮或自定义视图而不是textField .
换句话说,我想要一个 NSCell ,当它不被编辑时是一个 NSTextFieldCell ,而当一个 NSButtonCell (或自定义视图)时,被编辑.

The text of the cells of one of the column is computed and is not editable directly. For this column, I would like when the cell goes into edit mode, to display a button or a custom view instead of the textField.
Said in an other way, I want an NSCell that is a NSTextFieldCell when not being edited, and a NSButtonCell (or a custom view) when being edited.

有任何提示继续进行下去吗?

Any hint to move on to this?

这是我尝试过的,但没有成功:

Here is what I tried, without success:

  • 尝试#1 :

我将NSTextFieldCell子类化,并覆盖了fieldEditorForView:,如下所示=>问题是我返回的NSButton无法响应setDelegate:以及可能还有许多其他内容.

I subclassed a NSTextFieldCell and override fieldEditorForView: like shown below => problem is the NSButton I'm returning does not respond to setDelegate: and probably many other stuff.

- (NSTextView *)fieldEditorForView:(NSView *)aControlView {

    NSTableView *tableView = (NSTableView *) aControlView;

    // Manually computing column and row index for testing purposes
    NSButton* button = [[NSButton alloc] initWithFrame:[tableView frameOfCellAtColumn:2 row:2]];

    return (NSTextView *)button;
}

  • 尝试#2 :
    • Try #2:
    • 子类并覆盖drawWithFrame: inView: =>此方法仅在未处于编辑模式时才用于绘制单元格.

      Subclass NSTextFieldCell and override drawWithFrame: inView: => this method is only used to draw the cell when not in edit mode.

      • 尝试#3 :

      该线索具有一定的潜力,但我在这里显然缺少一些东西.
      在窗口的委托中实现windowWillReturnFieldEditor: toObject:,并返回一个自定义字段编辑器. 我似乎走了正确的路,但是我错过了一些东西.参数anObject绝不是我的自定义单元格(我仔细检查了一下,并在XIB中正确定义了该参数).

      This lead has some potential, but I'm obviously missing something here.
      Implement windowWillReturnFieldEditor: toObject: in my window's delegate, and return a custom field editor. I seem to be on the right track, but I missed something. The argument anObject is never my custom cell (I double checked and it's defined properly in the XIB).

      - (id)windowWillReturnFieldEditor:(NSWindow *)sender toObject:(id)anObject
      {
          if ([anObject isKindOfClass:[NSCellTextAndButtonAtEditTime class]])
          {
              NSLog(@"Going there");
      
              NSButton* button = [[NSButton alloc] initWithFrame:CGRectMake(0, 0, 300, 20)];
              button.title = @"test";
      
              return button;
          }
          return nil;
      }
      

      推荐答案

      在我看来,最好的方法是将NSTextView子类化,为您的自定义单元格创建一个新的自定义字段编辑器,然后在其中覆盖- (NSTextView *)fieldEditorForView:(NSView *)aControlView您的自定义单元来出售它.看起来对NSTextFieldCell的编辑器应该是NSTextView的期望几乎是强制性的,这可能是您尝试返回按钮的尝试失败的原因.我制作了一个显示按钮的简短示例,当您按下按钮时,它将文本字段单元格的值更新为当前时间并结束编辑.也许会有所帮助:

      It seems to me the best way to do this is to subclass NSTextView, making a new custom field editor for your custom cell, and then override - (NSTextView *)fieldEditorForView:(NSView *)aControlView in your custom cell to vend it. It looks like the expectation that an NSTextFieldCell's editor be an NSTextView is pretty much mandatory, which is probably why your attempt to return a button failed. I cooked up this brief example which displays a button, and when you press the button, it updates the value of the text field cell to the current time and ends editing. Maybe it'll be helpful:

      @interface SOMyEditor : NSTextView
      @end
      
      @interface SOMyEditor ()
      - (void)p_buttonPressed: (id)sender;
      @end
      
      @implementation SOMyEditor
      
      - (id)initWithFrame:(NSRect)frameRect textContainer:(NSTextContainer *)container;
      {
          if (self = [super initWithFrame: frameRect textContainer:container])
          {
              NSButton* button = [[[NSButton alloc] initWithFrame: NSMakeRect(0,0,frameRect.size.width, frameRect.size.height)] autorelease];
              button.title = @"Update Time!";
              button.target = self;
              button.action = @selector(p_buttonPressed:);
              button.autoresizingMask |= NSViewWidthSizable | NSViewHeightSizable;
              self.autoresizesSubviews = YES;
              [self addSubview: button];
          }
          return self;
      }
      
      - (void)p_buttonPressed: (id)sender
      {
          NSString* string = [[NSDate date] description];
          [self insertText: string];
          [self didChangeText];
          [self.window endEditingFor: self];
      }
      
      @end
      

      然后让您的自定义单元格类执行以下操作:

      Then have your custom cell class do something like this:

      @interface SOMyCustomTextFieldCell : NSTextFieldCell
      @end
      
      @interface SOMyCustomTextFieldCell ()
      @property (retain) NSTextView* fieldEditor;
      @end
      
      @implementation SOMyCustomTextFieldCell
      @synthesize fieldEditor = _fieldEditor;
      
      - (NSTextView *)fieldEditorForView:(NSView *)aControlView
      {
          if (nil == _fieldEditor)
          {
              _fieldEditor = [[SOMyEditor alloc] init];
              _fieldEditor.fieldEditor = YES;
          }
      
          return self.fieldEditor;    
      }
      
      - (void)dealloc
      {
          [_fieldEditor release];
          [super dealloc];
      }
      
      @end
      

      这里有一些技巧.首先,如前所述,只要单元格是NSTextFieldCell,编辑器就必须是NSTextView的子类.子类化NSTextView带来了很多样板行为(您知道,通常需要的所有行为,并且可以通过使用NSTextFieldCell进行编辑免费获得).如果您希望应用程序不像文本编辑器那样运行,那么您将不得不做一些工作来禁用NSTextView的正常行为.

      There are a couple of tricks here. First, as mentioned, as long as the cell is an NSTextFieldCell, the editor will have to be a subclass of NSTextView. Subclassing NSTextView brings with it a LOT of boilerplate behavior (you know, all the behaviors you normally want and get for free from using NSTextFieldCell for editing). If you want your app to NOT behave as if there's a text editor, you're going to end up doing some work to disable the normal behaviors of NSTextView.

      第二,当您覆盖- (NSTextView *)fieldEditorForView:(NSView *)aControlView时,重要的是它在多个调用中为同一单元格返回 same 字段编辑器.如果仅在每次对该方法的调用上创建一个新的NSTextView,它将无法正常工作.

      Secondly, when you override - (NSTextView *)fieldEditorForView:(NSView *)aControlView it's important that it return the same field editor for the same cell across multiple calls. If you just create a new NSTextView on every call to that method, it will not work right.

      希望这会有所帮助!

      这篇关于如何创建一个在编辑模式下显示自定义视图而不是NSTextField的NSTextFieldCell?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆