よくあるアプリのPreferencesウィンドウみたいなのを作ります。
ツールバーがタブの役割をしていて、タブを選択すると画面が切り替わります
作り方
既存のツールバーをいじってもなかなかうまくいかなかったのですが、NSTabViewControllerなるものを使えば簡単にできます。
TabViewControllerをStoryboardに追加
TabViewControllerをStoryboardに追加します。
そして、WindowControllerと関連づいているViewControllerを削除し、WindowControllerのwindow contentに追加したTabViewControllerを割り当てます。
TabViewControllerの設定ですが、StyleをToolbarに変更します。
TabViewControllerのChildViewControllerをいじる
適当にいじります。今回は適当なラベルを追加しました。
今んとこViewControllerの構成は以下のようになっています。
ToolbarItemをいじる
上記まででタブでの画面切り替え自体は出来ますが、タブのアイコンがない状態ですのでシステムのアイコンをつけてみます。
(システムのアイコンについての詳細は、System-Provided Imagesを参照してみてください。)
- NSTabViewControllerのサブクラスを作成。
- InterfaceBulder上でNSTabViewControlleを手順1で作ったクラスに変更
- InterfaceBulder上でTabViewControllerの下にNSTabViewItemがありますのでこれを手順1のサブクラスのOutletに追加。
4. NSTabViewControllerのサブクラスのコード内で、手順3で作ったオブジェクトのアイコンを設定。
class TabViewController: NSTabViewController {
@IBOutlet weak var generalItem: NSTabViewItem!
@IBOutlet weak var accountItem: NSTabViewItem!
override func viewDidLoad() {
super.viewDidLoad()
// アイコン設定
accountItem.image = NSImage(named: NSImageNameUserAccounts)
generalItem.image = NSImage(named: NSImageNamePreferencesGeneral)
}
}
iOSのTabBarControllerみたいな感じでできました。
(追記)タブ選択時に、Windowサイズを変更する
それぞれのタブのViewのサイズが異なる場合、タブ選択時にサイズを変更してあげる必要があります。
一番簡単なのは、AutoLayoutで各Viewのサイズを固定してしまうことです。
しかしこのやり方では、アニメーションがつかなかったので、以下のように実装しました。
やり方
TabViewをTabViewControllerのDelegateに設定する。
TabViewControllerにデリゲートメソッド
tabView(tabView: NSTabView, willSelectTabViewItem tabViewItem: NSTabViewItem?)
を追加し実装する。
上記のデリゲートメソッドはタブを選択した時に呼ばれます。この時にWindowサイズを変更するコードを実装します。
ソースコード
class TabViewController: NSTabViewController {
@IBOutlet weak var generalItem: NSTabViewItem!
@IBOutlet weak var accountItem: NSTabViewItem!
enum TabViewIdentifier: String {
case GeneralIdentifier = "General"
case AccountIdentifier = "Account"
var tabViewType: TabViewType {
switch self {
case GeneralIdentifier:
return TabViewType.General
case AccountIdentifier:
return TabViewType.Account
}
}
}
enum TabViewType: Int {
case General
case Account
var windowSize: CGSize {
switch self {
case .General:
return CGSizeMake(450, 160) //適当
case .Account:
return CGSizeMake(450, 280) //適当
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
accountItem.image = NSImage(named: NSImageNameUserAccounts)
generalItem.image = NSImage(named: NSImageNamePreferencesGeneral)
}
// タブを選択した時に呼ばれる
override func tabView(tabView: NSTabView, willSelectTabViewItem tabViewItem: NSTabViewItem?) {
guard let window = self.view.window else { return }
guard let identifier = tabViewItem?.identifier as? String else { return }
guard let tabViewIdentifier = TabViewIdentifier(rawValue: identifier) else { return }
let type = tabViewIdentifier.tabViewType
let contentSize = type.windowSize
let newWindowSize = window.frameRectForContentRect(CGRectMake(0, 0, contentSize.width, contentSize.height)).size
var frame = window.frame
frame.origin.y += frame.size.height
frame.origin.y -= newWindowSize.height
frame.size = newWindowSize
// サイズ変更
self.view.window?.setFrame(frame, display: false, animate: true)
}
}