问题
I have an NSTableView (view Based) who show info's from an NSarrayController. All connections are made from IB. Everything works fine, but blue selection color doesn't look ok with my design idea, so I want to change this color with my own color, but until now I failed.
class MyTable: NSTableView, NSTableViewDelegate {
override func drawBackgroundInClipRect(clipRect: NSRect) {
if self.isRowSelected( self.selectedRow ){
//NSColor.brownColor().colorWithAlphaComponent(0.9).setFill()
// NSBezierPath.fillRect(clipRect)
println("selected")
}
}
}
My real problem is that: I have no idea where should I start, what to subclass, NSTableView , NSTableCellView etc.
Recent I discovered a method to do that which say I should subclass NSTableRowView, and override drawSelectionInRect function. I've did that, but in IB i don't have an NSTableRowView Object.
Thanks.
回答1:
I did that in this way. First subclass NSTableRowView as you said:
class MyRowView: NSTableRowView {
override func drawRect(dirtyRect: NSRect) {
super.drawRect(dirtyRect)
if selected == true {
NSColor.greenColor().set()
NSRectFill(dirtyRect)
}
}
}
And then just add this method:
func tableView(tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView? {
let myCustomView = MyRowView()
return myCustomView
}
If I remember right, that should do it.
Edit: I just try my example and it works. In IB i set my tableview's delegate and datasource to ViewController and named my only column to "name." Here is my whole ViewController class:
class ViewController: NSViewController, NSTableViewDataSource, NSTableViewDelegate {
var persons = [Person]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
populate()
}
func populate() {
var first = Person(name: "John")
var second = Person(name: "Jesse Pinkman")
persons = [first, second]
}
func numberOfRowsInTableView(tableView: NSTableView) -> Int {
return persons.count
}
func tableView(tableView: NSTableView, viewForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSView? {
if tableColumn?.identifier == "name" {
let view = tableView.makeViewWithIdentifier(tableColumn!.identifier!, owner: self) as! NSTableCellView
view.textField?.stringValue = persons[row].name
return view
}
return nil
}
func tableView(tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView? {
let myCustomView = MyRowView()
return myCustomView
}
}
回答2:
Swift 4 version of @Prontto 's excellent answer.
class MyRowView: NSTableRowView {
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
if isSelected == true {
NSColor.green.set()
dirtyRect.fill()
}
}
}
.
// In your NSTableViewDelegate
func tableView(_ tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView? {
return MyRowView()
}
回答3:
The preferred method is to override drawSelection(in:) which the default implementation of draw(_:)
calls when it needs to draw the selection for a selected row. You don't have to check the selection state yourself.
override func drawSelection(in dirtyRect: NSRect) {
NSColor.green.setFill()
dirtyRect.fill()
}
However, if you override draw(in:)
as well and do not call the superclass implementation, you will have to call drawSelection(in:)
manually and determine the selection state yourself. Another benefit to overriding drawSelection(in:)
is that "the selection will automatically be alpha-blended if the selection is animating in or out.".
来源:https://stackoverflow.com/questions/29474067/how-to-change-selection-color-for-nstableview-which-use-nsarraycontoller-as-cont