我已经实现了一个自定义的NSSliderCell,它使用了一个与默认旋钮大小非常不同的旋钮(这是用于交互式展示-我不能使用任何默认的Mac OS X控件)。
虽然滑块出现并且行为正确(旋钮从一端到另一端等),但当你仔细观察时,你会发现一个奇怪的行为:移动鼠标,比如说,20像素,将导致旋钮移动30像素。这意味着在鼠标到达终点之前,旋钮可能会到达滑块的末端(并且滑块将具有最大值)。
这看起来很奇怪,违背了所有的期望。我想知道我必须做些什么来确保旋钮跟随鼠标而不会移动得更快。
好吧,一如既往,解决方案是最简单的。
下面是最简单的代码,你需要有一个非常自定义的滑动条:#import "CSSSliderCell.h"
#define KNOB_WIDTH 20
#define KNOB_HEIGHT 126
#define SLIDER_WIDTH 13
@implementation CSSSliderCell
- (void)drawKnob:(NSRect)rect
{
// knobImage is an NSImage
[knobImage drawInRect:rect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
}
- (void)drawBarInside:(NSRect)cellFrame flipped:(BOOL)flipped
{
NSRect slideRect = cellFrame;
NSColor *backColor = [NSColor redColor];
if ([(NSSlider*) [self controlView] isVertical] == YES)
{
slideRect.size.width = SLIDER_WIDTH;
slideRect.origin.x += (cellFrame.size.width - SLIDER_WIDTH) * 0.5;
} else {
slideRect.size.height = SLIDER_WIDTH;
slideRect.origin.y += (cellFrame.size.height - SLIDER_WIDTH) * 0.5;
}
NSBezierPath *bezierPath = [NSBezierPath bezierPathWithRoundedRect:slideRect xRadius:SLIDER_WIDTH * 0.5 yRadius:SLIDER_WIDTH * 0.5];
[backColor setFill];
[bezierPath fill];
}
- (NSRect)knobRectFlipped:(BOOL)flipped{
CGFloat value = ([self doubleValue] - [self minValue])/ ([self maxValue] - [self minValue]);
NSRect defaultRect = [super knobRectFlipped:flipped];
NSRect myRect = NSMakeRect(0, 0, 0, 0);
if ([(NSSlider*) [self controlView] isVertical] == YES)
{
myRect.size.width = KNOB_WIDTH;
myRect.size.height = KNOB_HEIGHT;
if (!flipped) {
myRect.origin.y = value * ([[self controlView] frame].size.height - KNOB_HEIGHT);
} else {
myRect.origin.y = (1.0 - value) * ([[self controlView] frame].size.height - KNOB_HEIGHT);
}
myRect.origin.x = defaultRect.origin.x;
} else {
myRect.size.width = KNOB_HEIGHT;
myRect.size.height = KNOB_WIDTH;
myRect.origin.x = value * ([[self controlView] frame].size.width - KNOB_HEIGHT);
myRect.origin.y = defaultRect.origin.y;
}
return myRect;
}
- (BOOL)_usesCustomTrackImage
{
return YES;
}
@end
这可能有问题,但到目前为止,无论在水平方向还是垂直方向,它都工作得很好。
你的代码对我帮助很大。谢谢你!
但是,旋钮的位置(myRect.origin)不正确。我修改了代码(还删除了硬编码的宏)。
- (NSRect)knobRectFlipped:(BOOL)flipped {
float KNOB_WIDTH = [knobImage size].width;
float KNOB_HEIGHT = [knobImage size].height;
CGFloat value = ([self doubleValue] - [self minValue])/ ([self maxValue] - [self minValue]);
NSRect defaultRect = [super knobRectFlipped:flipped];
NSRect myRect = NSMakeRect(0, 0, 0, 0);
if ([(NSSlider*) [self controlView] isVertical] == YES)
{
//...
} else {
myRect.size.width = KNOB_WIDTH;
myRect.size.height = KNOB_HEIGHT;
myRect.origin.x = value * ([[self controlView] frame].size.width - KNOB_WIDTH);
myRect.origin.y = defaultRect.origin.y + defaultRect.size.height/2.0 - myRect.size.height/2.0; // Fixed the position
}
return myRect;
};