1

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

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

子类覆盖:

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

NSSegmentedCell 中是否有任何方法可以确定它正在绘制处于“按下”状态的段并在跟踪期间适当地显示它?

4

5 回答 5

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;可能足以确定鼠标被按下的部分,然后适当地渲染。

于 2013-06-02T10:14:07.497 回答
1

最近遇到了这个问题,发现可以检查当前的鼠标事件以查看是否按下了目标段。从内部调用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
}
于 2017-09-04T01:12:12.570 回答
0

你可以在segmentcell课堂上这样检查

NSLog(@"selectedSegment - > ",[self selectedSegment]);

检查选定的段索引并做必要的事情。

希望这可以帮助 !!!

于 2013-03-11T11:55:53.333 回答
0

I found a way. It's not ideal, but it does work in my testing and for my case, but it uses the private NSSegmentedCell method:

- (NSInteger)_segmentHighlightState:(NSInteger)arg1;

This method returns 1 for unselected cells, 3 for unselected cells while they are pressed during tracking, 4 for selected cells, and 5 for selected cell while pressed during tracking.

So testing bit 1 (mask with 0x02) gives the desired "is pressed" state. Sadly this is useless if you want to ship on the Mac App Store, but since Keyboard Maestro is excluded from the Mac App Store because of the sandboxing requirement, that no longer concerns me.

It is still worth defending against any possible changes, with code like this:

- (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;
}

The startTrackingAt method @arun.s suggested doesn't work because NSSegmentedControl uses a different and unknown tracking area )and besides, even rectForSegment:inFrame is a private method so you can't even really find out where the cell is without using a (less) private method.

I'd rather a documented way to do this, but short of implementing the entire control afresh, I don't see how.

于 2013-03-13T07:13:53.880 回答
-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];
    }

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

于 2013-06-02T13:28:17.013 回答