NSTextField не вызывает делегат, когда внутри NSTableCellView - PullRequest
6 голосов
/ 19 августа 2011

В моем приложении довольно странный список источников (вытащенный из библиотеки объектов) с NSTreeController в качестве источника данных. Я установил NSTextField внутри DataCell для редактирования, но я хочу иметь возможность отключить это для некоторых ячеек. Я подумал, что вы сделаете это, используя делегат для NSTextField, но ни один из методов делегата, которые я пробовал, вызывается. Я что-то упускаю? У меня есть делегат с выходом в моей XIB, и он также является делегатом владельца NSOutlineView, реализующего оба протокола NSOutlineViewDelegate и NSTextFieldDelegate.

Кроме того, я также не могу использовать старый метод –outlineView:shouldEditTableColumn:item: NSOutlineViewDelegate, поскольку он работает только с базовыми представлениями на основе ячеек ( Я предполагаю, что это так - документация по Outline View не Похоже, что он был обновлен для Lion, хотя аналогичная документация NSTableView имеет, и эти методы не вызываются либо ).

Обновление

Я воспроизвел это в новом тестовом проекте, так что он определенно не связан ни с одним из моих пользовательских классов. Следуйте приведенным ниже инструкциям, чтобы создать пример проекта и воспроизвести эту проблему.

  1. В Xcode 4.1 создайте новый проект типа Mac OS X Cocoa Application без специальных параметров
  2. Создайте два новых файла, SourceListDataSource.m и SourceListDelegate.m , с содержанием, указанным ниже
  3. В MainMenu.xib перетащите Source List в окно
  4. Перетащите два Object s на док-станцию ​​(левая сторона окна), указав класс SourceListDataSource для одного и SourceListDelegate для другого
  5. Подключите выходы Outline View dataSource и delegate к этим двум объектам
  6. Выберите статический текст NSTextField для представления DataCell внутри столбца представления структуры
  7. Включите привязку Value, сохраняя настройки по умолчанию
  8. Подключите его delegate выход к объекту делегата списка источников
  9. Установите для свойства Behavior значение Editable
  10. Построить и запустить, затем дважды щелкнуть по любой ячейке в виде структуры.

Ожидается : поле недоступно для редактирования, и есть "хорошо, я должен?" сообщение в журнале

Actual : поле доступно для редактирования, и сообщения не регистрируются

Это ошибка в фреймворке, или я должен добиться этого по-другому?


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

Ответы [ 2 ]

3 голосов
/ 19 августа 2011

Подкласс NSTableCellView, с выходом для текстового поля и установите делегат текстового поля в awakeFromNib. После этого вызывается control:textShouldBeginEditing:. Я не уверен, почему, но (edit :) если вы установите делегата в xib, методы делегата не будут называться - у меня был такой же опыт, как у вас.

В качестве альтернативы вы можете отказаться от делегата и условно установить Editable, используя привязку либо к логическому свойству модели, либо с помощью преобразователя значения, который действует на экземпляр модели и возвращает логическое значение. Используйте Редактируемая привязка текстового поля.

0 голосов
/ 22 января 2013

Я тоже столкнулся с этой проблемой.Поскольку я не хотел терять привязки, я сделал следующее:

Привязка editable TextField к objectValue и настроил пользовательский подкласс NSValueTransformer.

...