2013-03-11 4 views
0

Я использую версию BGHUDSegmentedCell для рисования сегментированного элемента в стиле HUD (NSSegmentedControl).Рисование «нажатого» состояния в пользовательском NSSegmentedCell

Однако я не вижу никакого способа нарисовать ячейку в «нажатом» состоянии, пока пользователь нажимает на сегмент (чтобы пользователь получал надлежащую обратную связь). По умолчанию NSSegmentedControl/Cell управляет этим, поэтому существует предположительно способ, хотя и является системным кодом, который знает, является ли он общедоступным.

подкласс переопределяет:

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

Есть ли способ в NSSegmentedCell, чтобы определить, что он рисует сегмент в «нажатом» состоянии, и таким образом отобразить его должным образом во время отслеживания?

ответ

0

Вы можете проверить, как это в segmentcell классе

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

Проверка для выбранного индекса сегмента и делать то, что необходимо.

Надеюсь, что это поможет !!!

+0

К сожалению, нет. selectedSegment остается неизменным до тех пор, пока после отпускания кнопки и завершения отслеживания - я хочу, чтобы иметь возможность нарисовать нажатый сегмент во включенном состоянии при нажатии кнопки. drawWithFrame вызывается, но я не могу найти способ определить, какой сегмент отслеживается. –

+0

Вы можете проверить отслеживание сегмента в этих трех делегатах rt: - (BOOL) startTrackingAt: (NSPoint) startPoint inView: (NSView *) controlView - (BOOL) continueTracking: (NSPoint) lastPoint at: (NSPoint) currentPoint inView :(NSView *) controlView - (void) stopTracking: (NSPoint) lastPoint at: (NSPoint) stopPoint inView: (NSView *) controlView mouseIsUp: (BOOL) флаг –

+0

добавьте его в качестве ответа, и я объясню, почему это не так использование startTrackingAt и др. не работает. –

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 - частный метод, поэтому вы даже не можете узнать, где находится ячейка, не используя (менее) частный метод.

Я предпочел бы документированный способ сделать это, но не реализовал весь контроль заново, я не вижу, как это сделать.

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;, вероятно, будет достаточно, чтобы определить, на какой сегмент нажатии мыши, а затем оказывать соответствующим образом.

+0

Предлагаемый метод startTrackingAt @ arun.s не работает, поскольку NSSegmentedControl использует другую и неизвестную зону отслеживания. –

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

В непрессованном состоянии, сегментированное управление рисовать градиент для имитации фона панели инструментов (или границы окна). Я просто не рисую при нажатии кнопки управления.

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 
} 
+0

Не удастся, если пользователь нажмет на один сегмент и перетащит на другой сегмент? Возможно, система будет редко перерисовывать второй сегмент в этой точке, но может быть, если есть какая-то другая причина для перерисовки? –

Смежные вопросы