выполнитьSegueWithIdentifier из подкласса NSView?

У меня есть окно документа, содержащее несколько подклассов NSView, переключаемых между ними с помощью элемента управления вкладками. Каждый из подклассов и ViewController окна поддерживают различные действия пользователя, доступ к которым осуществляется через пункты меню, привязанные к первому респонденту.

Я хочу выполнить переход из одного из этих представлений в ответ на пункт меню. Однако NSView не поддерживает performSegueWithIdentifier, похоже, это что-то, что является частью NSViewController.

Может ли кто-нибудь предложить способ обойти это? Я видел предложения передать VC в представления, но я не понимаю, как это сделать. Или, возможно, есть лучший способ?


person Maury Markowitz    schedule 04.04.2016    source источник
comment
Поскольку @IBActions подключены к Первому ответчику, вы не могли бы зафиксировать действие в контроллере представления и выполнить действие в зависимости от активного представления.   -  person vadian    schedule 04.04.2016
comment
Да, но действие зависит от информации, приватной для представления, в частности от выбора в NSTableView. Я мог бы разоблачить это, но это кажется неправильным.   -  person Maury Markowitz    schedule 04.04.2016
comment
Обычно вы управляете рабочим процессом из контроллера, так как у вас есть доступ к представлениям. Альтернативой является использование шаблона протокола/делегата для отправки данных обратно в контроллер.   -  person vadian    schedule 04.04.2016
comment
Если вы хотите понять, почему вы не делаете этого в данном случае, попробуйте создать макет раскадровки с дюжиной представлений в контроллере вкладок, каждое из которых имеет собственный VC и представление. Вы придете к заключению, как и я, что любая потенциальная трудоемкость изменения объектной модели намного дешевле, чем попытка отредактировать получившийся беспорядок.   -  person Maury Markowitz    schedule 04.04.2016


Ответы (2)


view.containingController.performSegue()

примечание: вы должны добавить в свои представления ContainerController.

Я бы добавил viewController в цепочку респондентов, а затем сделал содержащийController вычисляемым свойством в расширении!

например добавить vc в качестве ответчика:

override func awakeFromNib() {
    super.awakeFromNib()
    self.nextResponder = self.view
    for subview in self.view.subviews {
        subview.nextResponder = self
    }
}

например содержащийконтроллер в расширении

extension NSView {

    var containingController: NSViewController? { 
        get {
            while(self.nextResponder != nil) {
                if(self.nextResponder is NSViewController) {
                    return self.nextResponder
                }                
            }
            return nil
        }
    }
}
person Daij-Djan    schedule 04.04.2016
comment
Расширение заметки написано из памяти.. может быть ошибка или синтаксическая ошибка, но вы должны понять идею - person Daij-Djan; 04.04.2016
comment
Примечание: на самом деле не так. делегат был бы чище ИМО - person Daij-Djan; 04.04.2016
comment
Я все равно принимаю это, потому что для реализации и решения проблемы потребовались секунды. Да, я знаю, что злоупотребляю системой, но иногда это менее доступно только для чтения, чем правильно. Это один пример. - person Maury Markowitz; 04.04.2016

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

Я бы порекомендовал вам добавить делегата (соответствующего вашему собственному протоколу, назовем его MyViewDelegate) в ваш NSView с помощью метода, подобного viewRequiresToPerformTransition(view: YourViewSubclass). Затем вы реализуете этот метод (в более общем случае вы соответствуете протоколу MyViewDelegate) в своем контроллере представления и внутри его реализации выполняете любой переход, который хотите.

person FreeNickname    schedule 04.04.2016
comment
Я согласен на 100% с FreeNickname. Моя просто веселее :D - person Daij-Djan; 04.04.2016
comment
Хорошо, я понял, но как установить делегата в представлении? Я не хочу делать это во время бодрствования VC, потому что представления будут обновляться только тогда, когда они станут видимыми в представлении вкладок. - person Maury Markowitz; 04.04.2016
comment
@MauryMarkowitz, если ваш контроллер представления содержится внутри UITabBarViewController, вы можете, например, установить делегата в viewWillAppear (вложенного VC). Или в части кода, отвечающей за отображение представления, если оно изначально скрыто. - person FreeNickname; 04.04.2016
comment
Ну, это все в OSX, но я понимаю, что вы имеете в виду. В теме! - person Maury Markowitz; 04.04.2016
comment
@MauryMarkowitz, о, да, извините) Я в основном занимаюсь разработкой для iOS, поэтому на мгновение забыл, что вопрос касается OS X) Удачи! :) - person FreeNickname; 04.04.2016