aya*_*aio 10 cocoa nsslider swift
我有一个NSWindow和一个横向NSSlider.
当窗口背景颜色发生变化时,我想更改滑块右侧部分的颜色.
目前,当窗口背景较暗时,条形图的右侧部分不再可见.
注意:窗口背景实际上是一个渐变,我通过覆盖drawRect
窗口视图的子类来绘制.
我以为我可以通过子类化NSSliderCell
和覆盖某些方法来改变滑块条填充颜色,drawBarInside
但是我不明白它是如何工作的:我应该制作一个小方形图像并在旋钮后的矩形中重复绘制它?或者只是画一条彩色线条?我以前从未这样做过.
我看过这个问题很有意思,但它是关于画旋钮而我现在不需要它.
我也看过这个看起来非常有前途的那个,但是当我试图模仿这个代码时,我的滑块就消失了......
在他们使用的这个问题中drawWithFrame
,它看起来很有趣,但我不知道它是如何工作的.
我想用我自己的代码而不是使用库来做这件事.有人可以给我一个关于如何做到这一点的提示吗?:)
我在Swift中这样做但是如果需要我可以阅读/使用Objective-C.
Ati*_*ika 14
这是正确的,您必须将类子NSSliderCell
类化为重绘条形或旋钮.
NSRect
只是一个矩形容器,你必须在这个容器内绘制.我根据NSLevelIndicator
我的一个程序中的一个自定义做了一个例子.
首先,您需要计算旋钮的位置.您必须注意控制的最小值和最大值.接下来,您绘制一个 NSBezierPath
用于背景,另一个用于左侧部分.
#import "MyCustomSlider.h"
@implementation MyCustomSlider
- (void)drawBarInside:(NSRect)rect flipped:(BOOL)flipped {
// [super drawBarInside:rect flipped:flipped];
rect.size.height = 5.0;
// Bar radius
CGFloat barRadius = 2.5;
// Knob position depending on control min/max value and current control value.
CGFloat value = ([self doubleValue] - [self minValue]) / ([self maxValue] - [self minValue]);
// Final Left Part Width
CGFloat finalWidth = value * ([[self controlView] frame].size.width - 8);
// Left Part Rect
NSRect leftRect = rect;
leftRect.size.width = finalWidth;
NSLog(@"- Current Rect:%@ \n- Value:%f \n- Final Width:%f", NSStringFromRect(rect), value, finalWidth);
// Draw Left Part
NSBezierPath* bg = [NSBezierPath bezierPathWithRoundedRect: rect xRadius: barRadius yRadius: barRadius];
[NSColor.orangeColor setFill];
[bg fill];
// Draw Right Part
NSBezierPath* active = [NSBezierPath bezierPathWithRoundedRect: leftRect xRadius: barRadius yRadius: barRadius];
[NSColor.purpleColor setFill];
[active fill];
}
@end
Run Code Online (Sandbox Code Playgroud)
aya*_*aio 13
首先,我创建了一个滑块的图像并将其复制到我的项目中.
然后我在drawBarInside
方法中使用这个图像在正常的条形图rect
之前绘制,所以我们只看到剩余部分(我想保持蓝色部分完整).
这必须在以下子类中完成NSSliderCell
:
class CustomSliderCell: NSSliderCell {
let bar: NSImage
required init(coder aDecoder: NSCoder) {
self.bar = NSImage(named: "bar")!
super.init(coder: aDecoder)
}
override func drawBarInside(aRect: NSRect, flipped: Bool) {
var rect = aRect
rect.size = NSSize(width: rect.width, height: 3)
self.bar.drawInRect(rect)
super.drawBarInside(rect, flipped: flipped)
}
}
Run Code Online (Sandbox Code Playgroud)
亲:它有效.:)
Con:它删除了条形的圆角边缘,我还没有找到重绘它的方法.
更新:
我做了一个接受的答案的Swift版本,它运行得很好:
class CustomSliderCell: NSSliderCell {
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func drawBarInside(aRect: NSRect, flipped: Bool) {
var rect = aRect
rect.size.height = CGFloat(5)
let barRadius = CGFloat(2.5)
let value = CGFloat((self.doubleValue - self.minValue) / (self.maxValue - self.minValue))
let finalWidth = CGFloat(value * (self.controlView!.frame.size.width - 8))
var leftRect = rect
leftRect.size.width = finalWidth
let bg = NSBezierPath(roundedRect: rect, xRadius: barRadius, yRadius: barRadius)
NSColor.orangeColor().setFill()
bg.fill()
let active = NSBezierPath(roundedRect: leftRect, xRadius: barRadius, yRadius: barRadius)
NSColor.purpleColor().setFill()
active.fill()
}
}
Run Code Online (Sandbox Code Playgroud)
斯威夫特 5
class CustomSliderCell: NSSliderCell {
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func drawBar(inside aRect: NSRect, flipped: Bool) {
var rect = aRect
rect.size.height = CGFloat(5)
let barRadius = CGFloat(2.5)
let value = CGFloat((self.doubleValue - self.minValue) / (self.maxValue - self.minValue))
let finalWidth = CGFloat(value * (self.controlView!.frame.size.width - 8))
var leftRect = rect
leftRect.size.width = finalWidth
let bg = NSBezierPath(roundedRect: rect, xRadius: barRadius, yRadius: barRadius)
NSColor.orange.setFill()
bg.fill()
let active = NSBezierPath(roundedRect: leftRect, xRadius: barRadius, yRadius: barRadius)
NSColor.purple.setFill()
active.fill()
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4233 次 |
最近记录: |