Какао NSTextField Drag & Drop требует подкласса ... Правда? - PullRequest
5 голосов
/ 09 января 2011

До сегодняшнего дня у меня никогда не было повода использовать что-либо кроме NSWindow в качестве NSDraggingDestination.При использовании окна в качестве единого целевого объекта перетаскивания NSWindow передает эти сообщения своему делегату, что позволяет обрабатывать отбрасывания без создания подкласса NSWindow.

docs скажем:

Хотя NSDraggingDestination объявлен как неформальный протокол, подклассы NSWindow и NSView, которые вы создаете для принятия протокола, должны реализовывать только те методы, которые уместны.(Классы NSWindow и NSView предоставляют частные реализации для всех методов.) Либо объект окна, либо его делегат могут реализовывать эти методы;однако, реализация делегата имеет приоритет, если есть реализации в обоих местах.

Сегодня у меня было окно с двумя NSTextFields на нем, и я хотел, чтобы у них было другое поведение отбрасывания, и я не сделалхотите, чтобы капли где-нибудь еще в окне.То, как я интерпретирую документы, кажется, что мне нужно либо создать подкласс NSTextField, либо создать несколько гигантских обработчиков спагетти-условия для делегата окна, который проверяет перетаскивание draggingLocation для каждого представления, чтобы выбрать различные варианты поведения области размещения длякаждое поле.

Подход к централизованному обработчику отбрасывания на основе делегатов NSWindow кажется обременительным в любом случае, когда у вас было несколько небольших видов назначений отбрасывания.Аналогично, подход с использованием подклассов кажется обременительным независимо от случая, потому что теперь код обработки отбрасывания живет в классе представления, поэтому, как только вы примете отбрасывание, вы должны найти какой-то способ перенаправить отброшенные данные обратно в модель.Документы bindings предупреждают вас о попытке связывания с помощью программной установки значения пользовательского интерфейса.Так что теперь вы застряли, работая над этим тоже.

Итак, мой вопрос: «Правда !? Это единственные легкодоступные варианты? Или я что-то упускаю прямо здесь?»

Спасибо.

1 Ответ

6 голосов
/ 11 января 2011

После еще нескольких исследований выясняется, что «Да, действительно, у вас есть два варианта: либо создать подкласс NSTextField, либо использовать NSWindowDelegate для обработки капель». Я пойду дальше и сделаю заявление, что лучший вариант из двух вариантов «Я хочу, чтобы в одном окне было несколько зон перетаскивания» - это использование метода NSWindowDelegate с проверками попаданий, поскольку вы избегаете проблемы иметь ваш код обработки дропа на стороне просмотра. Я закончил с этим draggingUpdated: метод в моем классе делегата окна:

- (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender
{
    NSPasteboard *pboard = [sender draggingPasteboard];
    NSDragOperation sourceDragMask = [sender draggingSourceOperationMask];

    if ([pboard.types containsObject: NSFilenamesPboardType] && (sourceDragMask & NSDragOperationCopy))
    {
        NSView* hitView = [sender.draggingDestinationWindow.contentView hitTest: sender.draggingLocation];
        if (hitView && (hitView == mSourceTextField || hitView == mDestTextField))
        {
            return NSDragOperationCopy;            
        }
    }

    return NSDragOperationNone;
}

Очевидно, что есть еще кое-что, но этот подход на основе hitTest: до сих пор работал для меня. Я подозреваю, что это было бы немного сложнее, если бы вы работали с элементом управления на основе нескольких NSCell, таким как NSTableView или NSOutlineView, но неудивительно, что у них есть свои собственные методы обработки перетаскивания.

Надеюсь, это поможет кому-то еще.

...