Как использовать NSToolBar в Xcode 6 и Storyboard?

Я пытался создать приложение Cocoa, которое использует Swift и Storyboard в Xcode 6, но как я могу использовать NSToolbar там?

В Xcode 5 и xib вы можете добавить NSToolbar из библиотеки объектов в любые .xib файлы, а затем нажать на добавленную панель инструментов, чтобы развернуть его и перетащить соединение из любых элементов в файл AppDelegate.h, Таким образом вы можете создать соединение IBAction или IBOutlet. Я подтвердил, что это также можно сделать, если вы используете Swift и non-storyboard в Xcode 6. Однако похоже, что это не так в среде Xcode 6 и Storyboard.

Сначала я создал проект, который использует Storyboard в Xcode 6, но затем я не смог добавить NSToolbar из библиотеки объектов в контроллер просмотра в Storyboard. Поэтому я добавил его в Window Window Window Window в Storyboard. Однако таким образом я не могу создать эти соединения из любых элементов расширенной панели инструментов, чтобы либо AppDelegate.swift, либо ViewController.swift.

Итак, мой вопрос:

  • Возможно ли создать приложение раскадровки, которое использует NSToolbar?
  • Если это возможно, добавляет ли NSToolbar в контроллер окна правильный способ использования NSToolbar в раскадровке?
  • Наконец, как я могу создать там @IBOutlet и @IBAction?

UPDATE

Я обнаружил, что принятый ответ @GeorgeVillasboas работает только для @IBAction. Я все еще ищу, как создать соединение @IBOutlet...

Ответ 1

У меня была такая же проблема. Решение работает как для проектов Objective-C, так и для Swift.

Работа с раскадными файлами в OSX, он создает экземпляр NSWindow и segues для другого NSViewController в качестве его содержимого Window Content Segue, как вы описали.

На вашем ViewController создайте стандартный IBAction для получения действия при нажатии на панель инструментов. Чтобы подключить его к NSToolbar, просто управляйте перетаскиванием (или leftClick-drag) с вашего NSToolbarItem на объект FirstResponder, как показано на рисунке ниже.

Wiring up a NSToolbar on XCode 6

Откроется список доступных ОГРОМНЫХ. Ваш IBAction будет в этом списке. Просто выберите его, и вы хорошо пойдете.

Надеюсь, это поможет!

Ответ 2

Здесь ответ, который не зависит от подключений во время выполнения - ответ на @cdalvaro получает большую часть пути для некоторых приложений, но не заполнен, и для этого требуется, чтобы ViewController знал об искусственном NSWindowController, что не кажется правильным.

Как и @cdalvaro, первым шагом является создание собственного подкласса NSWindowController и установка WC Storyboard в этот класс. Затем вы можете создать все свои соединения в и из NSToolbar (оба @IBOutlet & @IBAction s) в новом WindowController. Пока все хорошо.

Последний шаг, который я еще нигде не видел, заключается в том, как обращаться к ViewController в WindowController - вы не можете создать для него @IBOutlet по тем же причинам, которые мы получили здесь в первом место - вы не можете создавать ссылки через сцены в Раскадке. Тем не менее, WindowController должен иметь ссылку на ViewController, и он делает... self.window!.contentViewController! as! ViewController

Здесь находится полный WindowController с флажком, который устанавливает значения в ViewController, без необходимости просмотра ViewController...

class MyWindowController: NSWindowController {

    var viewController: ViewController {
        get {
            return self.window!.contentViewController! as! ViewController
        }
    }

    @IBOutlet weak var aSwitch: NSButton!
    @IBAction func toolbarActionA(sender: AnyObject) {
        println("toolbarActionA")
        self.viewController.a = !self.viewController.a
        self.aSwitch.state = self.viewController.a ? NSOnState : NSOffState
    }
}

Ответ 3

Это помогло мне в решении IBOutlet, которое вы ищете: fooobar.com/questions/450148/...

Обновление (объяснение)

Я обнаружил этот поток, потому что пытался создать индикатор Circular Progress Indicator внутри панели инструментов, и я не знал, как его оживить от ViewController, так как IBOutlet был объявлен внутри пользовательского WindowController.

Наконец, я нашел сообщение, которое я добавил выше, в котором описано, как получить доступ к IBOutlets из других классов.

В сущности, я сделал следующее:

  • Создайте пользовательский подкласс NSWindowController (CustomWindowController) для Window Controller, чтобы я мог добавить IBOutlet для ProgressIndicator:

Пример кода:

@interface CustomWindowController : NSWindowController

@property (weak) IBOutlet NSProgressIndicator *progressIndicator;

@end
  • Затем в классе ViewController в методе, который я хочу использовать для обновления состояния индикатора выполнения, я создаю и создаю объект пользовательского Window Controller.

Пример кода:

CustomWindowController *customWindowController = self.view.window.windowController;`
  • Наконец, чтобы изменить состояние индикатора выполнения, нужно только вызвать метод из созданного пользовательского объекта.

Пример кода:

[customWindowController.progressIndicator startAnimation:sender];

или

[customWindowController.progressIndicator stopAnimation:sender];

Ответ 4

Это видео помогло мне создать панель инструментов без написания одной строки кода: https://www.youtube.com/watch?v=XSQocHG3IjA

Вы можете добавить элемент "Window Controller" из библиотеки объектов (если у вас его нет), подключиться к контроллеру просмотра (где вы хотите отобразить панель инструментов) и следить за видео! Для пользовательских кнопок панели инструментов добавьте элемент "Кнопка изображения" на панель инструментов, просто перетащив его из библиотеки объектов. Затем вы можете выбрать изображение для кнопки, установить размер и так далее...

Ответ 5

Вот общее решение для торговых точек и действий. он позволяет вам выполнять все те же функции, что и iboutlet для элемента панели инструментов, а также позволяет вам установить кнопку функции вместо создания ibaction. надеюсь, что это поможет: P

override func viewDidLayout() {
var x = self.view.window?.toolbar?.items[1].label
println(x)
if(self.view.window?.toolbar?.items[0].label! != "Check")
{
    toobarediting()
}
println("didlay")
}

func toobarediting() {
self.view.window?.toolbar?.insertItemWithItemIdentifier("Check", atIndex: 0)
}

func toolbarcheck(functiontoset: Selector) {
var y = self.view.window?.toolbar?.items[0] as NSToolbarItem
y.action = functiontoset
if(functiontoset != nil)
{
    y.enabled = true
}
}

Вот ссылка на мой вопрос, пытаясь получить более чистый ответ http://www.stackoverflow.com/questions/27371439/use-nstoolbar-outlet-xcode-6-and-storyboard/27374449 но это похоже на ответы, которые я получил до сих пор, это лучший вариант.

Ответ 6

Та же проблема IBOutlets также относится к KVO. Одной из особенностей NSSplitViewController является свойство canCollapse для каждого элемента разделенного представления, который поддерживает KVO, но это неприменимо в IB, как IBOutlets.

Единственным обходным решением, которое я могу видеть, является добавление NSObjectController к каждой сцене и при загрузке сцены, установите объект объектного контроллера на объект в другой сцене (уже загруженной), которую вы хотите ссылаться.