I think you will have to write a subclass, and override drawKnob
, maybe drawKnobSlotInRect:
too depending on what you want to change.
How to change NSScroller color?
-
20-06-2023 - |
题
I'm trying to change the color of the scroller itself, it seems I need to overwrite something around drawKnob but I couldn't find any method which seemed appropriate.
One way I thought about was to inject a new style and get scroller to use it but again, I couldn't find anything about NSColor in NSScroller header.
Any idea?
解决方案 2
其他提示
No need to redraw from scratch. It's as simple as this:
import AppKit
class CyanideScroller: NSScroller {
private var _bkgrColour: NSColor = NSColor.black
private var _knobColour: NSColor = NSColor.white
private var isHorizontal = false
var bkgrColour: NSColor {
get { return _bkgrColour}
set { _bkgrColour = newValue}
}
var knobColour: NSColor {
get { return _knobColour}
set { _knobColour = newValue}
}
override var frame: CGRect {
didSet {
let size = frame.size
isHorizontal = size.width > size.height
}
}
override func draw(_ dirtyRect: NSRect) {
_bkgrColour.setFill()
dirtyRect.fill()
self.drawKnob()
}
override func drawKnob() {
_knobColour.setFill()
let dx, dy: CGFloat
if isHorizontal {
dx = 0; dy = 3
} else {
dx = 3; dy = 0
}
let frame = rect(for: .knob).insetBy(dx: dx, dy: dy)
NSBezierPath.init(roundedRect: frame, xRadius: 3, yRadius: 3).fill()
}
}
The CyanideScroller class is nice, I've just updated it a little bit. Above all I have made sure that the knob is drawn only if necessary. This is my class:
import AppKit
/**
A custom object that controls scrolling of a document view
within a scroll view or other type of container view.
*/
class CustomScroller: NSScroller {
/**
Depository of the horizontal Boolean value.
*/
private var _isHorizontal: Bool = false
/**
A Boolean value that indicates whether the scroller is horizontal.
*/
public var isHorizontal: Bool {
return _isHorizontal
}
/**
The background color.
*/
public var backgroundColor: NSColor = NSColor.black
/**
The knob color.
*/
public var knobColor: NSColor = NSColor.white
/**
A Boolean value that indicates whether the scroller draws its background.
*/
public var drawsBackground: Bool = true
override var frame: CGRect {
didSet {
let size = frame.size
_isHorizontal = size.width > size.height
}
}
override func draw(_ dirtyRect: NSRect) {
if drawsBackground {
backgroundColor.setFill()
dirtyRect.fill()
}
if (usableParts == .allScrollerParts) {
drawKnob()
}
}
/**
Draws the knob.
*/
override func drawKnob() {
knobColor.setFill()
let dx, dy: CGFloat
if _isHorizontal {
dx = 0
dy = 3
} else {
dx = 3
dy = 0
}
let frame = rect(for: .knob).insetBy(dx: dx, dy: dy)
let roundedPath = NSBezierPath(roundedRect: frame, xRadius: 3, yRadius: 3)
roundedPath.fill()
}
}
不隶属于 StackOverflow