Change selection color on view-based NSTableView

前端 未结 13 1996
别跟我提以往
别跟我提以往 2020-12-07 19:11

Standard highlighting color in OS X applications is blue.

Is it possible to change it to another color, e.g. gray?

Note that I am using the new view-based

相关标签:
13条回答
  • 2020-12-07 19:15

    As already mentioned, set emphasized attribute to false, but do it in the custom NSTableRowView class to avoid side effects (like dancing color effect):

        override func drawRect(dirtyRect: NSRect) {
           super.drawRect(dirtyRect)
           self.emphasized = false
    
        }
    
    0 讨论(0)
  • 2020-12-07 19:18

    Here is James Chen's solution in Swift 3. I've also added the delegate method.

    class MyNSTableRowView: NSTableRowView {
    
        override func drawSelection(in dirtyRect: NSRect) {
            if self.selectionHighlightStyle != .none {
                let selectionRect = NSInsetRect(self.bounds, 2.5, 2.5)
                NSColor(calibratedWhite: 0.65, alpha: 1).setStroke()
                NSColor(calibratedWhite: 0.82, alpha: 1).setFill()
                let selectionPath = NSBezierPath.init(roundedRect: selectionRect, xRadius: 6, yRadius: 6)
                selectionPath.fill()
                selectionPath.stroke()
            }
        }
    }
    

    NSTableViewDelegate:

    func tableView(_ tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView? {
        return MyNSTableRowView()
    }
    
    0 讨论(0)
  • 2020-12-07 19:18

    This is Jean-Pierre's answer in Swift3:

    func tableViewSelectionDidChange(_ notification: Notification)
        { 
            index = tableView.selectedRow
            let rowView = tableView.rowView(atRow: index, makeIfNecessary: false)
            rowView?.isEmphasized = false
    ...
    

    It has the two limitations listed above -- first click doesn't work, second click does. And, there is a "dancing effect". I don't mind the first and actually like the second.

    0 讨论(0)
  • 2020-12-07 19:20

    Okay, So I do know that it already has an accepted answer, but for anyone like me working with an NSOutlineView and has .selectionHighlightStyle = .sourceList can use this code to make the selection grey. This method will not flicker when changing the selection and will also stay grey if the app is minimised.

    NSTableView/NSOutlineView Delegate:

    func outlineView(_ outlineView: NSOutlineView, rowViewForItem item: Any) -> NSTableRowView?
    {
         let row : CustomRowView = CustomRowView.init()
         row.identifier = "row"
    
         return row
    }
    

    And then create a new CustomRowView.swift file with this:

    class CustomRowView : NSTableRowView
    {
        override var isEmphasized: Bool {
            get { return self.isEmphasized }
            set(isEmp) { self.isEmphasized = false }
        }
    }
    

    This will keep the selection grey at all times.

    0 讨论(0)
  • 2020-12-07 19:23

    Some modifications to Jean-Pierre answer

    Use the following code in response to the NSTableViewDelegate protocol tableViewSelectionDidChange:

    Get the NSTableRowView for the selected row and call the method setEmphasized on it. When setEmphasized is set to YES you get the blue highlight, when NO you get the gray highlight.

    -(void)tableViewSelectionDidChange:(NSNotification *)aNotification {
    
     NSInteger selectedRow = [myTableView selectedRow];
     NSTableRowView *myRowView = [myTableView rowViewAtRow:selectedRow makeIfNecessary:NO];
    [myRowView setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleRegular];
    [myRowView setEmphasized:NO];
    }
    

    And to avoid dancing effect of blue then gray set

    [_tableView setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleNone];
    
    0 讨论(0)
  • 2020-12-07 19:23

    I've mixed all methods described before and got code that exactly do what I want.

    • Selection not change color of textfields inside;
    • Rows remember selection and color of one;
    • Any strange outer borders and other leftovers appear.

      class AudioCellView: NSTableRowView {
      
          override func draw(_ dirtyRect: NSRect) {
              super.draw(dirtyRect)
              self.wantsLayer = true
              self.layer?.backgroundColor = NSColor.white.cgColor
          }
      
          override var isEmphasized: Bool {
              set {}
              get {
                  return false
              }
          }
      
          override var selectionHighlightStyle: NSTableView.SelectionHighlightStyle {
              set {}
              get {
                  return .regular
              }
          }
      
          override func drawSelection(in dirtyRect: NSRect) {
              if self.selectionHighlightStyle != .none {
                  let selectionRect = NSInsetRect(self.bounds, 2.5, 2.5)
                  NSColor(calibratedWhite: 0.85, alpha: 0.6).setFill()
                  let selectionPath = NSBezierPath.init(rect: selectionRect)
                  selectionPath.fill()
              }
          }
      }
      
    0 讨论(0)
提交回复
热议问题