5

我正在使用自定义 NSSliderCell 创建自定义 NSSlider。除了旋钮之外,一切都很好。当我将它拖到旋钮被剪裁的最大值时,我只能看到旋钮图像的 50%。

在分配我的自定义 NSSliderCell 时,我将旋钮厚度设置为我用作旋钮的图像的宽度。我假设(我猜错了)它会考虑到这一点并阻止它剪裁?

任何想法我做错了什么?仅当旋钮被剪裁到 50% 时,滑块才会达到 maxValue,因此它不会在不添加任何值的情况下移动。

- (void)drawKnob:(NSRect)knobRect {
 NSImage * knob = _knobOff;
 knobRectVar = knobRect;

 [[self controlView] lockFocus];
 [knob
  compositeToPoint:
  NSMakePoint(knobRect.origin.x+4,knobRect.origin.y+knobRect.size.height+20)
  operation:NSCompositeSourceOver];
 [[self controlView] unlockFocus];
}

- (void)drawBarInside:(NSRect)rect flipped:(BOOL)flipped {
 rect.size.height = 8;

 [[self controlView] lockFocus];
 NSImage *leftCurve = [NSImage imageNamed:@"customSliderLeft"];
 [leftCurve drawInRect:NSMakeRect(5, 25, 8, 8) fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1];

    NSRect leftRect = rect;
    leftRect.origin.x=13;
    leftRect.origin.y=25;
    leftRect.size.width = knobRectVar.origin.x + (knobRectVar.size.width/2);
    [leftBarImage setSize:leftRect.size];
    [leftBarImage drawInRect:leftRect fromRect: NSZeroRect operation: NSCompositeSourceOver fraction:1];
 [[self controlView] unlockFocus];

}
4

4 回答 4

3

NSSLider 期望每个控件大小的旋钮图像都有一个特殊的大小:

NSRegularControlSize:   21x21
NSSmallControlSize:     15x15
NSMiniControlSize:      12x12

不幸的是,您的旋钮图像的高度不得超过此参数之一。但它的宽度可能会更长。如果是,您可以像这样计算旋钮的 x 位置:

CGFloat newOriginX = knobRect.origin.x *
        (_barRect.size.width - (_knobImage.size.width - knobRect.size.width)) / _barRect.size.width;

其中 _barRect 是您的条形背景的 cellFrame 来自:

- (void)drawBarInside:(NSRect)cellFrame flipped:(BOOL)flipped;

我为自定义 NSSlider 创建了一个简单的解决方案。按照此链接 https://github.com/Doshipak/LADSlider

于 2013-10-05T10:40:28.143 回答
3

您可以覆盖[NSSliderCell knobRectFlipped:][NSSliderCell drawKnob:]. 这是我的解决方案:

- (void)drawKnob:(NSRect)rect
{
  NSImage *drawImage = [self knobImage];

  NSRect drawRect = [self knobRectFlipped:[self.controlView isFlipped]];

  CGFloat fraction = 1.0;

  [drawImage drawInRect:drawRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:fraction respectFlipped:YES hints:nil];
}

- (NSRect)knobRectFlipped:(BOOL)flipped
{
  NSImage *drawImage = [self knobImage];

  NSRect drawRect = [super knobRectFlipped:flipped];

  drawRect.size = drawImage.size;

  NSRect bounds = self.controlView.bounds;
  bounds = NSInsetRect(bounds, ceil(drawRect.size.width / 2), 0);
  CGFloat val = MIN(self.maxValue, MAX(self.minValue, self.doubleValue));
  val = (val - self.minValue) / (self.maxValue - self.minValue);
  CGFloat x = val * NSWidth(bounds) + NSMinX(bounds);

  drawRect = NSOffsetRect(drawRect, x - NSMidX(drawRect) + 1, 0);
  return drawRect;
}
于 2014-06-05T18:45:51.057 回答
0

知道已经有一段时间了,但我自己遇到了这个问题,并找到了一个快速而肮脏的解决方法。

我无法解决这个问题的最初原因,但似乎 NSSlider 期待一个二次句柄图像。例如,我发现的最简单的方法是将滑块的范围设置为 0.0f - 110.0f。

然后,如果值 > 100.0f,则检查分配的 valueChanged 目标方法,如果是,则将其设置回该值。我在右侧创建了一个背景图像,其中包含一些仅 alpha 像素的像素,因此您的背景不会比实际的推子范围更宽。

快速而肮脏,但不需要很多代码并且工作得很好。希望这可以帮助其他遇到同样问题的人。

于 2012-10-04T20:53:46.090 回答
-2

您不需要从单元格绘图方法中锁定和解锁对 controlView 的关注。这些方法仅由您的 controlView 的 -drawRect: 方法调用,该方法在视图焦点锁定的情况下调用。

为什么要在 -drawKnob 中合成旋钮图像的 Y 坐标上添加 20 个点?

于 2011-01-26T18:58:06.093 回答