NSTextField在NSTableCellView内部不调用委托 [英] NSTextField not calling delegate when inside an NSTableCellView
问题描述
我在应用程序中有一个相当的源代码列表(从对象库中拖出),用一个 NSTreeController
作为它的数据源。我将 DataCell 中的 NSTextField
设置为可编辑,但我想要为某些单元格关闭它。我想你会这样做的方式是使用一个委托为 NSTextField
,但没有一个委托方法我试图得到调用。有什么我错过了吗?我的代理在我的XIB中有一个插座,它恰好是所有者 NSOutlineView
的代理,同时实现 NSOutlineViewDelegate
此外,我不能使用旧的和
c $ c> -outlineView:shouldEditTableColumn:item:
NSOutlineViewDelegate
方法,因为它只适用于基于单元格的Outline视图'm假设这是case - 大纲视图文档似乎没有更新为狮子,虽然类似的 NSTableView
文档,并且那些方法不获取
更新
我在一个全新的测试项目中它绝对与我的任何自定义类无关。请按照以下步骤创建我的示例项目,并重现此问题。
- 在Xcode 4.1中,创建一个新的项目X Cocoa Application,没有选择特殊选项
- 创建两个新文件:
- 在MainMenu.xib中,将
源列表
拖到窗口上 - 两个
Object
放在dock上(窗口的左边),为一个指定SourceListDataSource
code> SourceListDelegate 。 $
- 连接Outline View的
dataSource
c> c>
- 打开其
价值
绑定,保留默认设置
委托插件到源列表委托对象
- 将其
行为
属性设置为可编辑
- 构建并运行,然后在大纲视图中的任一单元格上单击两次。
- 连接Outline View的
预期:字段不可编辑,并且有一个好的,我应该?
实际:此字段可编辑,不记录任何消息
这是框架中的错误,还是我应该用不同的方式实现?
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.
- In Xcode 4.1, create a new project, of type Mac OS X Cocoa Application, with no special options selected
- Create two new files, SourceListDataSource.m and SourceListDelegate.m, with the contents specified below
- In MainMenu.xib, drag a
Source List
onto the Window - Drag two
Object
s onto the dock (left side of the window), specifying theSourceListDataSource
class for one, and theSourceListDelegate
for the other - Connect the Outline View's
dataSource
anddelegate
outlets to those two objects - Select the Static Text
NSTextField
for the DataCell view inside the outline view's column - Turn on its
Value
binding, keeping the default settings - Connect its
delegate
outlet to the Source List Delegate object - Set its
Behavior
property to Editable - 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屋!