Objective c 自定义圆形滑块
我试图实现一个自定义的圆形滑块,它使用图像来绘制刻度盘和旋钮。为此,我对Objective c 自定义圆形滑块,objective-c,macos,cocoa,Objective C,Macos,Cocoa,我试图实现一个自定义的圆形滑块,它使用图像来绘制刻度盘和旋钮。为此,我对NSSliderCell进行了子类化,并覆盖了trabrinside和drawKnob方法。 现在,如果我将滑块类型保留为默认值(水平),将调用我的绘图函数,并绘制图像,而不是默认的条形图和旋钮(当然,这看起来完全错误,因为图像是为圆形滑块制作的,但它们确实存在)。但一旦我将滑块类型更改为圆形(在IB中或通过在我的滑块单元格中设置self.sliderType=NSCircularSlider;),这两种方法就不会被调用,也
NSSliderCell
进行了子类化,并覆盖了trabrinside
和drawKnob
方法。
现在,如果我将滑块类型保留为默认值(水平),将调用我的绘图函数,并绘制图像,而不是默认的条形图和旋钮(当然,这看起来完全错误,因为图像是为圆形滑块制作的,但它们确实存在)。但一旦我将滑块类型更改为圆形(在IB中或通过在我的滑块单元格中设置self.sliderType=NSCircularSlider;
),这两种方法就不会被调用,也不会绘制图像(只创建标准刻度盘)。
我是不是忘了什么,或者圆形滑块根本就不能定制
这是我的密码:
DialSliderCell
是NSSliderCell
的子类,在名为DialSlider
的类中启动和设置,该类是NSSlider
的子类(该类当时不做任何其他事情)
我所能想到的是,您没有覆盖所有指定的初始值设定项 从文件中 指定的初始化者。当子类化NSCell时,必须实现所有 指定的初始值设定人。这些方法是:init, initWithCoder:、initTextCell:、initImageCell:
其他3种方法中可能有一种被称为圆形滑块。我通过覆盖
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];
}
你好,沃伦。实际上我是,但为了简单起见,我选择不在这里包含它们。无论如何,正如我所说的,
DialSliderCell
是在DialSlider
中手动创建的,所以我很确定使用的是哪个init方法:)但是如果我在IB中设置滑块单元格的类,那么它使用的是initWithCoder
,这对我的问题没有影响。当滑块从XIB中未归档时,它取消了视图和单元格的归档。这意味着要使其使用正确的单元类,您需要双击XIB中的视图,以便它选择NSSliderCell并设置其自定义类,而不仅仅是NSSlider视图的自定义类。你在这么做吗?请给复制此代码的人一个简短的提示:这仅在使用ARC时才正确。否则,当您将图像放入dialImage/knobImage实例variables.Correct时,您需要保留从-imageNamed:获得的图像。代码是在ARC环境中编写的,因此没有保留/发布。太好了,谢谢。我注意到图像绘制颠倒,因此您需要使用drawInRect:fromRect:operation:fraction:reservitflipped:hints:
以正确的方向显示图像。此外,如果您将应用提交到应用商店,则无法设置_trackRect,因为设置该属性显然被视为使用私有API。
- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
[self drawInteriorWithFrame:cellFrame inView:controlView];
}