2015-03-24 58 views
0

我有一個程序,其中有一個NSTableView填充了要上傳的文件。一旦文件被髮送,帶有文件名的文本單元就會得到一個放入其中的超鏈接(數組數據被賦予一個具有NSLinkAttributeName屬性的NSMutableString)。我如何讓用戶點擊此鏈接在默認瀏覽器中打開網頁?創建並響應NSTableView文本單元格內的超鏈接

回答

2

經過多次搜索和嘗試多種方法後,這就是我想出的解決方案。

創建擴展NSTableViewCell自定義類:

class TableViewCellCursor: NSTableCellView { 

internal var active = false 

//MARK: - View Life Cycle 

override func awakeFromNib() { 
    superview?.awakeFromNib() 
    self.createTrackingArea() 
} 

//MARK: - IBActions 

override func mouseEntered(theEvent: NSEvent) { 
    if (NSCursor.currentCursor() == NSCursor.arrowCursor() && active) { 
     NSCursor.pointingHandCursor().set() 
    } 
} 

override func mouseExited(theEvent: NSEvent) { 
    if (NSCursor.currentCursor() == NSCursor.pointingHandCursor() && active) { 
     NSCursor.arrowCursor().set() 
    } 
} 

//Informs the receiver that the mouse cursor has moved into a cursor rectangle. 
override func cursorUpdate(event: NSEvent) { 
    if (active) { 
     NSCursor.pointingHandCursor().set() 
    } 
} 

//MARK: - Util 

func createTrackingArea() { 
    var focusTrackingAreaOptions:NSTrackingAreaOptions = NSTrackingAreaOptions.ActiveInActiveApp 
    focusTrackingAreaOptions |= NSTrackingAreaOptions.MouseEnteredAndExited 
    focusTrackingAreaOptions |= NSTrackingAreaOptions.AssumeInside 
    focusTrackingAreaOptions |= NSTrackingAreaOptions.InVisibleRect 

    var focusTrackingArea:NSTrackingArea = NSTrackingArea(rect: NSZeroRect, 
                 options: focusTrackingAreaOptions, 
                 owner: self, userInfo: nil) 
    self.addTrackingArea(focusTrackingArea) 
} 
} 

檢查第一個響應狀態NSTableView的選擇發生變化時。這是必要的,因爲表的選擇是可以改變的,即使它不是firstResponder:

func tableViewSelectionDidChange(aNotification: NSNotification) { 
    if (self.firstResponder == filesToTransferTable) { 
     changeSelectedRowTextColorTo(NSColor.whiteColor(), unselectedColor: NSColor.blueColor()) 
    } else { 
     changeSelectedRowTextColorTo(NSColor.blackColor(), unselectedColor: NSColor.blueColor()) 
    } 
} 

func changeSelectedRowTextColorTo(selectedColor: NSColor, unselectedColor: NSColor) { 
    let selectedRows = filesToTransferTable.selectedRowIndexes 
    for (index, tableEntry) in enumerate (tableData) { 
     if tableData[index]["FileName"] is NSMutableAttributedString { 
      var name = tableData[index]["FileName"] as! NSMutableAttributedString 
      var range = NSMakeRange(0, NSString(string:name.string).length) 
      name.beginEditing() 
      name.removeAttribute(NSForegroundColorAttributeName, range: range) 

      if (selectedRows.containsIndex(index)) { 
       name.addAttribute(NSForegroundColorAttributeName, value:selectedColor, range:range) 
      } else { 
       name.addAttribute(NSForegroundColorAttributeName, value:unselectedColor, range:range) 
      } 

      name.endEditing() 
      tableData[index]["FileName"] = name 
     } 
     filesToTransferTable.reloadDataForRowIndexes(NSIndexSet(index: index), columnIndexes: NSIndexSet(index:0)) 
    } 
} 

添加志願檢查時FirstResponder變化:

//This is somewhere in your code where you initialize things 
//KVO for first responder behavior regarding tableView and updating attributedStrings' colors 
self.addObserver(self, forKeyPath: "firstResponder", options: NSKeyValueObservingOptions.Old | NSKeyValueObservingOptions.New, context: nil) 

override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutablePointer<Void>) { 
      if (change[NSKeyValueChangeNewKey] is NSTableView) { 
       changeSelectedRowTextColorTo(NSColor.whiteColor(), unselectedColor: NSColor.blueColor()) 
      } else if (change[NSKeyValueChangeOldKey] is NSTableView) { 
       changeSelectedRowTextColorTo(NSColor.blackColor(), unselectedColor: NSColor.blueColor()) 
      } 
     } 

最後,檢查是否在主窗口(應用程序本身)是焦點(如果不這樣做,那麼它的顏色會不恰當地在窗口失去焦點變化):

//Put these in the same place as the KVO code 
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "windowDidBecomeKey:", 
        name: NSWindowDidBecomeKeyNotification , object: self) 

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "windowDidResignKey:", 
        name: NSWindowDidResignKeyNotification , object: self) 


    func windowDidBecomeKey(notification: NSNotification) { 
     if (self.firstResponder == filesToTransferTable) { 
      changeSelectedRowTextColorTo(NSColor.whiteColor(), unselectedColor: NSColor.blueColor()) 
     } else { 
      changeSelectedRowTextColorTo(NSColor.blackColor(), unselectedColor: NSColor.blueColor()) 
     } 
    } 

    func windowDidResignKey(notification: NSNotification) { 
     if (self.firstResponder == filesToTransferTable) { 
      changeSelectedRowTextColorTo(NSColor.blackColor(), unselectedColor: NSColor.blueColor()) 
     } 
    } 
0

文本字段自動支持單擊嵌入式鏈接,但前提是它們至少可以選擇(如果不可編輯)。所以,設置你的文本字段是可選的。

+0

抱歉,NSTableView的的細胞是文本單元,而不是文本視圖。我已經將超文本鏈接設置爲「可選」,但我仍然無法點擊鏈接打開它。我必須使用不同於Text Cell的單元嗎?謝謝! – 2015-03-31 23:01:21

+0

文本單元格是否配置爲允許富文本?這對於使用屬性文本也是必要的。 – 2015-03-31 23:34:28

+0

是的,單元格被配置爲允許富文本,是可選的,並且該動作設置爲「僅在發送時輸入」。現在我一直在使用NSTable的tableViewSelectionDidChange,但這感覺更像是一種黑客,而不是實際上給予我想要的行爲。 – 2015-04-07 21:25:51