NSTextField在NSTableCellView内部不调用委托 [英] NSTextField not calling delegate when inside an NSTableCellView

查看:394
本文介绍了NSTextField在NSTableCellView内部不调用委托的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在应用程序中有一个相当的源代码列表(从对象库中拖出),用一个 NSTreeController 作为它的数据源。我将 DataCell 中的 NSTextField 设置为可编辑,但我想要为某些单元格关闭它。我想你会这样做的方式是使用一个委托为 NSTextField ,但没有一个委托方法我试图得到调用。有什么我错过了吗?我的代理在我的XIB中有一个插座,它恰好是所有者 NSOutlineView 的代理,同时实现 NSOutlineViewDelegate



此外,我不能使用旧的 c $ c> -outlineView:shouldEditTableColumn:item: NSOutlineViewDelegate 方法,因为它只适用于基于单元格的Outline视图'm假设这是case - 大纲视图文档似乎没有更新为狮子,虽然类似的 NSTableView 文档,并且那些方法不获取



更新



我在一个全新的测试项目中它绝对与我的任何自定义类无关。请按照以下步骤创建我的示例项目,并重现此问题。


  1. 在Xcode 4.1中,创建一个新的项目X Cocoa Application,没有选择特殊选项

  2. 创建两个新文件: SourceListDataSource.m 和 SourceListDelegate.m

  3. 在MainMenu.xib中,将源列表拖到窗口上

  4. 两个 Object 放在dock上(窗口的左边),为一个指定 SourceListDataSource code> SourceListDelegate 。 $
  5. 连接Outline View的 dataSource c> c> c> c>大纲视图的列

  6. 打开其价值绑定,保留默认设置

  7. 委托插件到源列表委托对象

  8. 将其行为属性设置为可编辑

  9. 构建并运行,然后在大纲视图中的任一单元格上单击两次。

预期:字段不可编辑,并且有一个好的,我应该?

实际:此字段可编辑,不记录任何消息



这是框架中的错误,还是我应该用不同的方式实现?






SourceListDataSource。 m



  #import< Cocoa / Cocoa.h> 

@interface SourceListDataSource:NSObject< NSOutlineViewDataSource>

@property(retain)NSArray * items;

@end

@implementation SourceListDataSource

@synthesize items;

- (id)init
{
self = [super init];
if(self){
items = [[NSArray arrayWithObjects:@Alo,@Homora,nil] retain];
}

return self;
}

- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)indexItem:(id)item {
if(!item){
return [self.items objectAtIndex:index];
}

return nil;
}

- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item {
return!item? self.items.count:0;
}

- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item {
return NO;
}

- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item {
return item;
}

@end



SourceListDelegate.m



  #import< Foundation / Foundation.h> 

@interface SourceListDelegate:NSObject< NSOutlineViewDelegate,NSTextFieldDelegate> @end

@implementation SourceListDelegate

- (NSTableRowView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item {
return [outlineView makeViewWithIdentifier:@DataCellowner:self];
}

- (BOOL)控件:(NSControl *)控件textShouldBeginEditing:(NSText *)fieldEditor {
NSLog(@well,should I?
return NO;
}

@end


解决方案>

子类 NSTableCellView ,带有文本字段的插口,并在 awakeFromNib 中设置文本字段委托。在这之后, control:textShouldBeginEditing:被调用。我不知道为什么,但() 如果你在xib中设置委托,委托方法不调用 - 我有同样的经验。



或者,您可以放弃委托,有条件地使用绑定设置Editable,设置为模型的布尔属性,或者使用一个值变换器,该变换器作用于模型实例并返回布尔值。使用文本字段的可编辑绑定。


I have a fairly vanilla Source List (dragged out from the Object Library) in my app, with an NSTreeController as its data source. I set the NSTextField inside the DataCell to be editable, but I want to be able to turn that off for some cells. The way I figured you would do this, is with a delegate for the NSTextField, but none of the delegate methods I've tried get called. Is there something I'm missing? I have the delegate set with an outlet in my XIB, and it happens to be the delegate to the owner NSOutlineView, as well, implementing both the NSOutlineViewDelegate and NSTextFieldDelegate protocols.

Also, I can't use the old –outlineView:shouldEditTableColumn:item: NSOutlineViewDelegate method either, since that only works with cell-based Outline Views (I'm assuming this is the case - the Outline View documentation doesn't appear to have been updated for Lion, though the analogous NSTableView documentation has, and those methods don't get called either).

Update

I reproduced this in a brand new test project, so it's definitely not related to any of my custom classes. Follow the steps below to create my sample project, and reproduce this problem.

  1. In Xcode 4.1, create a new project, of type Mac OS X Cocoa Application, with no special options selected
  2. Create two new files, SourceListDataSource.m and SourceListDelegate.m, with the contents specified below
  3. In MainMenu.xib, drag a Source List onto the Window
  4. Drag two Objects onto the dock (left side of the window), specifying the SourceListDataSource class for one, and the SourceListDelegate for the other
  5. Connect the Outline View's dataSource and delegate outlets to those two objects
  6. Select the Static Text NSTextField for the DataCell view inside the outline view's column
  7. Turn on its Value binding, keeping the default settings
  8. Connect its delegate outlet to the Source List Delegate object
  9. Set its Behavior property to Editable
  10. Build and Run, then click twice on either cell in the outline view.

Expected: The field is not editable, and there is a "well, should I?" message in the log

Actual: The field is editable, and no messages are logged

Is this a bug in the framework, or am I supposed to achieve this a different way?


SourceListDataSource.m

#import <Cocoa/Cocoa.h>

@interface SourceListDataSource : NSObject <NSOutlineViewDataSource>

@property (retain) NSArray *items;

@end

@implementation SourceListDataSource

@synthesize items;

- (id)init
{
    self = [super init];
    if (self) {
        items = [[NSArray arrayWithObjects:@"Alo", @"Homora", nil] retain];
    }

    return self;
}

- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item {
    if (!item) {
        return [self.items objectAtIndex:index];
    }

    return nil;
}

- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item {
    return !item ? self.items.count : 0;
}

- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item {
    return NO;
}

- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item {
    return item;
}

@end

SourceListDelegate.m

#import <Foundation/Foundation.h>

@interface SourceListDelegate : NSObject <NSOutlineViewDelegate, NSTextFieldDelegate> @end

@implementation SourceListDelegate

- (NSTableRowView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item {
    return [outlineView makeViewWithIdentifier:@"DataCell" owner:self];
}

- (BOOL)control:(NSControl *)control textShouldBeginEditing:(NSText *)fieldEditor {
    NSLog(@"well, should I?");
    return NO;
}

@end

解决方案

Subclass NSTableCellView, with an outlet for the text field, and set the text field delegate in awakeFromNib. After doing that, control:textShouldBeginEditing: gets called. I'm not sure why, but (edit:) if you set the delegate in the xib, the delegate methods aren't called – I had the same experience as you.

Alternatively, you can forego the delegate and conditionally set Editable using a binding, either to a boolean property of the model, or using a value transformer which acts on a model instance and returns a boolean. Use the Editable binding of the text field.

这篇关于NSTextField在NSTableCellView内部不调用委托的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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