Как я могу создать интерфейс с основными данными и абстрактной сущностью?

StackOverflow https://stackoverflow.com/questions/1811454

Вопрос

У Apple есть симпатичный небольшой туториал по созданию простого интерфейса с подробными описаниями.Interface Builder даже автоматически сгенерирует его для вас из объекта Core Data.Тем не менее, я пытаюсь сделать что-то более сложное, чем простой пример, и некоторое время я изо всех сил пытался заставить это работать.

У меня есть приложение, основанное на документах Core Data.Модель включает в себя абстрактную сущность Page и несколько конкретных подразделов Page.Все Страницы имеют некоторые общие атрибуты (например, "имя"), и они определены в Page.Очевидно, что подразделы обладают уникальными для них атрибутами.

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

Вот что у меня есть прямо сейчас:

У меня есть основной файл nib, где отображается основной список, а также все поля, общие для Страницы.Для каждого типа страницы есть кончик с определенными полями.В главном файле nib есть основной NSArrayController, который заполняет NSTableView.В каждом из специфичных для страницы элементов также есть NSArrayController, так что я могу привязать поля сведений к атрибутам текущего выбора.Все мои NSArrayControllers настроены одинаково, и все они у меня привязаны к одному и тому же managedObjectContext и одним и тем же selectionIndexes.

Я использую метод Аарона Хиллегасса для обмена мнениями, который он описывает в своей книге Cocoa.Итак, я зарегистрировался для NSTableViewSelectionDidChangeNotifications, и когда я получаю одну из них, она вызывает метод SwitchView:

SwitchView просматривает выбранный в данный момент объект, проверяет, к какому типу Страницы он относится, и выполняет замену в соответствующем файле nib в соответствии с методом Хиллегасса.

Все работает нормально, если я добавляю страницы только одного типа, но как только я добавляю страницу второго типа, я получаю эту ошибку:

Значение настройки ошибки для ключевых индексов выбора пути объекта (из объекта привязки объекта:Страница, количество выбранных объектов:1):[ Ключ valueforundefined:]:объект NoColPage не соответствует кодированию значения ключа для стороны ключа.

Последняя часть ошибки имеет смысл:он застрял, пытаясь отобразить неправильный кончик, поэтому пытается привязаться к полям, которые не существуют для этого объекта.

Я добавил поле selectionIndexes в MyDocument, чтобы все мои NSArrayControllers могли привязываться к одному и тому же месту.Я мучился над этим несколько дней и никак не могу понять, в чем дело.Есть какие-нибудь идеи?

Если это поможет, вот пример проекта, который вы можете скачать.Я извлек из своего проекта только то, что имеет отношение к этой проблеме, в новое фиктивное приложение, которое я использовал для тестирования и обкатки.

PS:Инструмент Interface Builder для создания интерфейса с основными деталями из объекта Core Data работает не так, как я хочу, для абстрактных объектов.Он создает поля только для атрибутов в superentitity.

Редактировать: Я думаю, Джошуа что-то замышляет, но, к сожалению, это не работает - я продолжаю сталкиваться с одной и той же проблемой.Сначала мне было нелегко, потому что я не понимал этого -отвязать:ожидает строковую константу, а не путь к ключу.

Я перепробовал несколько вариантов:где я отслеживаю текущий контроллер массива отображаемого наконечника;где я отслеживаю текущий отображаемый тип страницы и только отменяю привязку / повторную привязку, когда пытаюсь отобразить другой тип страницы...

Вот соответствующий раздел кода.

-(void) displayViewController: (ManagingVC *) vc withClass:(NSString*) className {

//Try to end editing
NSWindow *w = [box window];
BOOL ended = [w makeFirstResponder:w];
if (!ended) {
    NSBeep();
    return;
}

//The Managing View Controller's NSArrayController
NSArrayController* vcAc = [vc arrCont];

//if the page we're trying to switch to is NOT the same type as the current page we're displaying
//if it is, do nothing.
if (![currPageDisplayed isEqual:className]) {

    //unbind the old view controller
    ManagingVC *oldvc = [viewControllers objectForKey:className];
    NSArrayController* oldsac = [oldvc arrCont];
    [oldsac unbind:@"selectionIndexes"];

    //bind the new view controller
    [vcAc bind:@"selectionIndexes" toObject:self withKeyPath:@"selectionIndexes" options:nil];
    currPageDisplayed = className;

    NSView *v = [vc view];

    //display the new view in an NSBox in the main nib
    [box setContentView:v];
}

}

Это было полезно?

Решение 2

Потратив слишком много времени на синхронизацию контроллера массива каждого наконечника, я отказался от этого подхода.Единственное, что у меня сработало, - это программное управление тем, какие элементы графического интерфейса отображаются в главном интерфейсе, и их привязками.Это означает устранение других выступов.На самом деле это не очень надежное решение, если вы работаете не только с парой текстовых полей, но у меня оно работает прямо сейчас.

Я все еще следую совету Джошуа отменить привязку перед переключением представления, но прямо сейчас я привязываю текстовые поля только к ArrayController.selection.whateverKey

Другие советы

Проблема в том, что вы оставляете контроллеры массива ваших nibs привязанными к выбранному документу, что заставляет их пытаться (при изменении выбора) представить выбранный элемент.

Попробуй это:

  1. Снимите крепления с наконечников.
  2. Перед добавлением нового представления соедините его привязки в коде.
  3. Перед удалением старого представления отключите его привязки в коде.

Это должно сделать всех счастливыми.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top