🐰
NSSplitViewController傘下の任意のViewControllerを型情報付きで安全に触れるようにするアクセサ
extension NSSplitViewController {
struct SplitItemInfo<T: NSViewController> {
let itemIndex: Int
let item: NSSplitViewItem
let viewController: T
}
func firstItemForViewControllerClass(_ class: AnyClass) -> NSSplitViewItem? {
splitViewItems.first { item in
type(of: item.viewController) == `class`
}
}
func firstPane<T: NSViewController>() -> SplitItemInfo<T>? {
if let item = firstItemForViewControllerClass(T.self),
let index = splitViewItems.firstIndex(of: item),
let vc = item.viewController as? T
{
return SplitItemInfo<T>(itemIndex: index, item: item, viewController: vc)
}
return nil
}
}
class SplitViewController: NSSplitViewController {
// 任意のアクセサを適宜用意(以下例)
/// サイドバー
var primarySidebarItemInfo: SplitItemInfo<SidebarViewController>? {
firstPane()
}
/// コンテンツ領域
var contentViewItemInfo: SplitItemInfo<ContentViewController>? {
firstPane()
}
/// インスペクタ
var inspectorViewItemInfo: SplitItemInfo<InspectorViewController>? {
firstPane()
}
}
使う時
let splitViewController: SplitViewController = …
// サイドバーにアクセス
if let info = splitViewController.primarySidebarItemInfo() {
let vc = info.viewController // SidebarViewController
let item = info.item // NSSplitViewItem
let index = info.index // Int (おそらく0になる)
}
// インスペクタにアクセス
if let info = splitViewController.inspectorViewItemInfo() {
let vc = info.viewController // InspectorViewController
let item = info.item // NSSplitViewItem
let index = info.index // Int (構成次第だが、おそらく2になる)
}
Discussion