自定义循环NSSlider

时间:2012-01-04 08:06:19

标签: objective-c macos cocoa

我正在尝试实现一个自定义的圆形滑块,它使用图像来绘制表盘和旋钮。为此,我已将NSSliderCell子类化,并覆盖了drawBarInsidedrawKnob方法。 现在,如果我将滑块类型保留为默认(水平),则会调用我的绘图函数并绘制图像而不是默认的条形和旋钮(当然,由于图像是针对圆形滑块制作的,因此它看起来完全错误,但它们是那里)。但是,只要我将滑块类型更改为圆形(在IB中或通过在我的滑块单元格中设置self.sliderType = NSCircularSlider;),就不会调用这两种方法,也不会绘制我的图像(仅创建标准刻度盘)。 我在这里忘记了什么,或者根本不能定制圆形滑块?

这是我的代码: DialSliderCellNSSliderCell的子类,在名为DialSlider的类中启动并设置,该类是NSSlider的子类(此类在此时不执行任何其他操作)。 / p>

@implementation DialSliderCell

- (id)init {
    self = [super init];
    if (self) {
        dialImage = [NSImage imageNamed:@"dial"];
        knobImage = [NSImage imageNamed:@"dialKnob"];
        self.sliderType = NSCircularSlider;
    }
    NSLog(@"init");
    return self;
}

- (void)drawKnob:(NSRect)knobRect {
    knobRect.size = knobImage.size;
    [knobImage drawInRect:knobRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
    NSLog(@"drawKnob");
}

- (void)drawBarInside:(NSRect)aRect flipped:(BOOL)flipped {
    [dialImage drawInRect:aRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
    NSLog(@"drawBarInside");
}

@end

2 个答案:

答案 0 :(得分:2)

我通过覆盖drawInteriorWithFrame方法解决了这个问题。解决方案基于原始方法。我刚删除了与圆形滑块无关的任何内容,删除了原始图形并添加了我自己的图形。几何几乎完全是原始的。

- (void) drawInteriorWithFrame: (NSRect)cellFrame inView: (NSView*)controlView
{
    cellFrame = [self drawingRectForBounds: cellFrame];
    _trackRect = cellFrame;

    NSPoint knobCenter;
    NSPoint point;
    float fraction, angle, radius;

    knobCenter = NSMakePoint(NSMidX(cellFrame), NSMidY(cellFrame));

    [dialImage drawInRect:cellFrame fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];

    int knobDiameter = knobImage.size.width;
    int knobRadius = knobDiameter / 2;
    fraction = ([self floatValue] - [self minValue]) / ([self maxValue] - [self minValue]);
    angle = (fraction * (2.0 * M_PI)) - (M_PI / 2.0);
    radius = (cellFrame.size.height / 2) - knobDiameter;
    point = NSMakePoint((radius * cos(angle)) + knobCenter.x,
                    (radius * sin(angle)) + knobCenter.y);

    NSRect dotRect;
    dotRect.origin.x = point.x - knobRadius;
    dotRect.origin.y = point.y - knobRadius;
    dotRect.size = knobImage.size;
    [knobImage drawInRect:dotRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
}

cellFrame矩形的大小设置为dialImage图片的大小。

请注意,上述方法似乎并未自动调用,因此我还必须覆盖drawWithFrame方法并调用drawInteriorWithFrame

- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
    [self drawInteriorWithFrame:cellFrame inView:controlView];
}

答案 1 :(得分:0)

我能想到的是,你没有压倒所有指定的初始化者

来自文档...

  

指定的初始化程序。在子类化NSCell时,您必须实现所有   指定的初始化者。那些方法是:init,   initWithCoder:,initTextCell:和initImageCell:。

可能另外3个中的一个被称为圆形滑块。