2017-07-29 59 views
1

大家討論瞭如何在右鍵點擊時擺脫藍色輪廓......但我。NSOutlineView如何在右鍵點擊時顯示藍色輪廓

而是,我試圖顯示藍色輪廓。

當我右鍵單擊我的大綱視圖行時,我沒有得到任何大綱。菜單出現了,但輪廓不是。

你可以看到藍色的輪廓是不是在下面這張圖可見:

enter image description here



下面就是我想要的目的。

Blue outline


更新

我這是怎麼實現的NSMenu。我將NSOutlineView分類並制定了一個新協議來覆蓋NSOutlineViewDelegate

這個想法是讓NSOutlineView爲每個項目詢問NSMenu使其變得簡單,因此我們可以爲每個項目實施不同的菜單。它可以工作,但藍色輪廓視圖在右鍵單擊時不顯示。

KRMenuOutlineView.swift

import Cocoa 

@objc protocol KRMenuOutlineViewDelegate: NSOutlineViewDelegate { 
    // This method will ask NSMenu for each item in outline view 
    func outlineView(_ outlineView: KRMenuOutlineView, menuFor item: Any, event: NSEvent) -> NSMenu? 
} 

class KRMenuOutlineView: NSOutlineView { 

    override var delegate: NSOutlineViewDelegate? { 
     didSet { 
      if let newValue = delegate { 
       /* 
       * Swift doesn't support overriding inherited properties with different type 
       * like Objective C Does, therefore we need internal delegate. 
       */ 
       internalDelegate = unsafeBitCast(newValue, to: KRMenuOutlineViewDelegate.self) 
      } else { 
       internalDelegate = nil 
      } 
     } 
    } 

    private var internalDelegate: KRMenuOutlineViewDelegate? 

    override func menu(for event: NSEvent) -> NSMenu? { 
     let point = self.convert(event.locationInWindow, from: nil) 
     if let item = self.item(atRow: self.row(at: point)) { 
      return self.internalDelegate?.outlineView(self, menuFor: item, event: event) 
     } 
     return super.menu(for: event) 
    } 
} 

然後,我用它在我的視圖控制器是這樣的:

KRTreeViewController.swift

extension KRTreeViewController: KRMenuOutlineViewDelegate { 
    func outlineView(_ outlineView: KRMenuOutlineView, menuFor item: Any, event: NSEvent) -> NSMenu? { 
      let menu = NSMenu(title: "Contextual Menu") 
      menu.delegate = self 

      let key = String(utf16CodeUnits: [unichar(NSBackspaceCharacter)], count: 1) as String 
      let deleteMenuItem = menu.addItem(withTitle: "Delete", 
               action: #selector(didClickMenuItem(_:)), 
               keyEquivalent: key) 
      deleteMenuItem.representedObject = myItem 
      deleteMenuItem.target = self 

      return menu 
    } 

    @objc fileprivate func didClickMenuItem(_ menuItem: NSMenuItem) { 
     // ... 
    } 
} 
+0

我們不知道您是如何使藍色輪廓消失的。你是如何實現上下文菜單的?你有沒有做任何改變'NSOutlineView'的默認行爲? – Willeke

+0

@Willeke我更新了我的問題。 –

+0

嘗試在返回自己的菜單之前調用'super.menu(for:event)'。 – Willeke

回答

1

如何正確顯示上下文菜單:

如果您使用故事板創建了菜單: 首先,轉到故事板並將菜單添加到包含outlineView的viewController。 然後將其設爲@IBOutlet,以便稍後參考。

在像viewDidLoad()的方法,通過調用

outlineView.menu = myMenu 

其中MYMENU可以是你在Interface Builder或代碼創建了一個菜單添加到outlineView。

您可以立即運行應用程序,並應該看到單元格周圍的藍色輪廓。

現在的問題是,您不知道用戶點擊了哪個單元格。 要解決此問題,請將自己設置爲myMenu的委託並採用NSMenuDelegate協議。

func menuNeedsUpdate(_ menu: NSMenu) { 
    let row = self.outlineView.clickedRow 

    guard row != -1 else { return } 
    for item in menu.items { 
     item.representedObject = row 
    } 
} 

在這裏,你可以做任何你需要的。此實現將rowIndex設置爲每個菜單項的RepresentObject。請記住,這隻適用於靜態outlineViews(不會在後臺更改)和僅深入一級的菜單。

您還可以將單元格表示的索引或對象(如果outlineView不是靜態的)存儲在局部變量中。

+0

感謝您的回答,使用此解決方案,我們如何才能限制只顯示「NSOutlineView」中特定項目的菜單?我還更新了顯示代碼實現的問題。 –

+0

如果我**沒有使用故事板創建菜單,該怎麼辦?我已經在我的大綱視圖子類中評論了所有過度的東西,並且藍色輪廓仍然沒有顯示出來...... –

+0

@Nicolas Miari:您可以簡單地在代碼中創建菜單。例如,在'viewDidLoad()'中,創建你的菜單並調用'outlineView.menu = myMenu'。其餘應如上所述。 – mangerlahn