在自定义NSSegmentedCell中绘制“按下”状态

时间:2013-03-11 08:24:32

标签: objective-c cocoa subclass

我正在使用BGHUDSegmentedCell的一个版本来绘制HUD风格的分段控件(NSSegmentedControl)。

但是,当用户点击某个片段时,我无法看到以“按下”状态绘制单元格的任何方法(以便用户获得正确的跟踪反馈)。默认的NSSegmentedControl / Cell管理这个,所以可能有一种方法,虽然是系统代码,谁知道它是否是一种公共方式。

子类覆盖:

- (void)drawWithFrame:(NSRect)frame inView:(NSView *)view {
- (void)drawSegment:(NSInteger)segment inFrame:(NSRect)frame withView:(NSView *)view {

NSSegmentedCell中是否有任何方法可以确定它是否在“按下”状态下绘制一个片段,并在跟踪过程中正确显示它?

5 个答案:

答案 0 :(得分:2)

最好通过覆盖NSCell的鼠标跟踪方法来实现自己的向下/按下状态跟踪。

- (BOOL)startTrackingAt:(NSPoint)startPoint inView:(NSView *)controlView;
- (void)stopTracking:(NSPoint)lastPoint at:(NSPoint)stopPoint inView:(NSView *)controlView mouseIsUp:(BOOL)flag;
- (BOOL)continueTracking:(NSPoint)lastPoint at:(NSPoint)currentPoint inView:(NSView *)controlView;

-(CGFloat)widthForSegment:(NSInteger)segment;组合的那些可能足以确定按下鼠标的哪个部分,然后适当地渲染。

答案 1 :(得分:0)

您可以在segmentcell班级

中进行检查
NSLog(@"selectedSegment - > ",[self selectedSegment]);

检查所选的段索引并执行必要的操作。

希望这有助于!!!

答案 2 :(得分:0)

我发现了一种方法。它并不理想,但它在我的测试和我的情况下都有效,但它使用了私有的NSSegmentedCell方法:

- (NSInteger)_segmentHighlightState:(NSInteger)arg1;

对于未选中的单元格,此方法返回1,对于未选中的单元格,在跟踪期间按下时为3,对于所选单元格为4,对于选定单元格,在跟踪期间按下时为5。

因此测试位1(掩码为0x02)会产生所需的“按下”状态。遗憾的是,如果你想在Mac App Store上发货,这是没用的,但由于沙盒要求,因为Keyboard Maestro被排除在Mac App Store之外,所以我不再担心。

仍然值得为任何可能的更改辩护,使用以下代码:

- (BOOL) mySegmentIsPressed:(int)segment;
{
    NSInteger highlightState = 0;
    if ( [self respondsToSelector:@selector(_segmentHighlightState:)] ) {
        highlightState = [self _segmentHighlightState:segment];
    } else {
        highlightState = ([self selectedSegment] == segment) ? 4 : 1;
    }
    return (highlightState&2) != 0;
}

startTrackingAt方法@ arun.s建议不起作用,因为NSSegmentedControl使用不同的未知跟踪区域)此外,甚至rectForSegment:inFrame是一个私有方法,所以你甚至不能真正找到没有单元格的位置使用(较少)私有方法。

我宁愿采用有记录的方式来做到这一点,但如果没有重新实现整个控制,我不知道如何。

答案 3 :(得分:0)

最近进入此状态并发现可以检查当前鼠标事件以查看是否按下了目标片段。从drawSegment:inFrame:withView:内部调用:

func isSegmentPressed(segment: Int, frame: NSRect, controlView: NSView) -> Bool {
    if let event = NSApp.currentEvent, event.type == .leftMouseDown, isEnabled(forSegment: segment) {
        let location = controlView.convert(event.locationInWindow, from: nil)
        return frame.contains(location)
    }
    return false
}

答案 4 :(得分:-1)

以下是我实施新闻发布的方式。

- (void) drawSegment:(NSInteger)segment inFrame:(NSRect)frame withView:(NSView *)controlView
    {
        NSColor *startColor = [NSColor colorWithDeviceRed:0.690196 green:0.690196 blue:0.690196 alpha:1.0];
        NSColor *endColor = [NSColor colorWithDeviceRed:0.878431 green:0.878431 blue:0.878431 alpha:1.0];
        NSGradient *grad = [[NSGradient alloc] initWithStartingColor:startColor endingColor:endColor];

        if(![self isSelectedForSegment:segment]) {
            [grad drawInRect:frame angle:270];
        }
        [super drawSegment:segment inFrame:frame withView:controlView];
    }

在未按下状态下,分段控件绘制渐变以模仿工具栏(或窗口边框)的背景。我只是在按下控件时不画画。