выбор и редактирование нового объекта в NSTableView

Я пытаюсь выбрать и изменить свойство имени недавно добавленного объекта.

В OSX у меня есть контроллер массива, который отображает его содержимое в виде таблицы. У меня есть значения столбца таблицы, связанные (с использованием привязок) через свойства AC. Кроме того, я установил содержимое табличного представления и привязки selectionIndexes, чтобы они указывали на AC.

Мой подкласс AC имеет IBOutlet для табличного представления (называемого tableView) и содержит управляемые объекты из модели данных.

В моем AC я переопределяю метод add:.

- (void)add:(id)sender {
    [super add:sender];
    [[self managedObjectContext] processPendingChanges]; // no effect
    [tableView reloadData]; // no effect
    [tableView scrollRowToVisible:[[self arrangedObjects] count]-1];
}

Недавно добавленный объект отображается в табличном представлении в выбранном состоянии (у меня настроен AC в IB для выбора вновь вставленных объектов). Но табличное представление прокручивается до предпоследней строки, помещая новую строку сразу за пределы видимого представления.

Когда я попробую это,

[tableView scrollRowToVisible:[tableView selectedRow]];

или это,

[tableView scrollRowToVisible:[self selectionIndex]];

становится еще хуже: кажется, что selectionIndex не обновляется правильно.

- (void)add:(id)sender {
    [super add:sender];
    NSLog(@"selectionIndex = %lu", [self selectionIndex]);
    NSLog(@"number of objects in AC = %lu", [[self arrangedObjects] count]);
}

Регистрация selectionIndex показывает, что он всегда показывает предыдущий индекс выбора. Регистрация количества объектов в АС всегда на единицу меньше.

Я слишком рано пытаюсь манипулировать представлением таблицы? Любые идеи, какой метод лучше подходит для переопределения?


По части редактирования..

Следующий оператор мешает вышеприведенному методу scrollRowToVisible:, так как последний аргумент также выбирает строку.

[tableView editColumn:0 row:0 withEvent:nil select:YES];

Во всяком случае, указанное поле (в целях тестирования первая строка таблицы), кажется, переходит в режим редактирования всего на мгновение, но затем немедленно завершает редактирование.

Любая помощь будет принята с благодарностью.


person Fnord23    schedule 12.03.2012    source источник
comment
нет ли способа исправить это с помощью привязок? NSArrayController имеет привязку для автоматического выбора новых вставок. Нельзя ли привязать NSTableView, чтобы автоматически начать редактирование ячейки?   -  person Fnord23    schedule 12.03.2012


Ответы (2)


Одно решение, которое я придумал:

- (void)rearrangeObjects {
    [super rearrangeObjects];
    [tableView editColumn:0 row:[self selectionIndex] withEvent:nil select:YES];
}

Последний аргумент select:YES не прокручивает таблицу до строки и не выбирает строку. Следующая строка также прокручивает представление таблицы.

[tableView editColumn:0 row:[self selectionIndex] withEvent:nil select:NO];

select:YES выделяет текст в редактируемом текстовом поле.

Тем не менее, мне интересно, правильно ли я об этом говорю. Это решение требует, чтобы каждый контроллер массива имел выход к табличному представлению, отображающему его данные. Это кажется излишним, поскольку табличное представление (и его столбцы) уже привязано к AC.

Пытаясь реализовать шаблон проектирования MVC, разве ответственность за редактирование ячейки не должна быть делегирована табличному представлению?

person Fnord23    schedule 13.03.2012
comment
Кроме того, отмена (одной или нескольких новых вставок) ведет себя эратично. Таблица теряет выбор новых строк, из-за чего таблица прокручивается вверх. В результате пользователь не может видеть изменения, которые он отменяет. Это довольно раздражает, когда таблица содержит тысячи записей. - person Fnord23; 13.03.2012

Проблема в том, что контроллер массива не сразу добавляет новый объект. документация для -[NSArrayController add:] говорит:

Начиная с Mac OS X версии 10.4, результат этого метода откладывается до следующей итерации цикла выполнения, чтобы механизм представления ошибок (см. разделы об ошибках и восстановлении после ошибок) мог предоставлять обратную связь в виде листа.

Я не знаю ни одного элегантного способа обойти это. Вы можете попробовать обойти метод add:, добавив объект непосредственно в NSMutableArray, к которому привязан контроллер массива. В качестве альтернативы вы можете попробовать использовать performSelector:withObject:afterDelay: с небольшой задержкой, например, 0,1 секунды, после чего объект должен был быть добавлен.

person Tom Dalling    schedule 12.03.2012
comment
спасибо, Том, твой ответ вдохновил меня на решение проблемы. - person Fnord23; 13.03.2012