Circular NSSlider with a stop (not continuous)

I'm not sure how it is better to designate it as a title, but I need to make an NSSlider that functions like a normal volume control. At this point, it will spin around as many times as I hold the mouse and move it around the control. I need it to stop at positions "0" and "100", I canโ€™t jump from 0 to 100 when I drag it in another way. I hope I will explain this clearly. Does anyone know how to do this or have any suggestions?

+4
source share
3 answers

Old question, but we still go:

(1) Set the slider to 100 ticks

(2) Select "Only stop with marks"

(3) In Interface Builder, set SBCustomSliderCell for the custom cell SBCustomSliderCell

Use the following code:

 @interface SBCustomSliderCell() @property CGFloat lastSliderValue; @end @implementation SBCustomSliderCell - (void)awakeFromNib { self.lastSliderValue = -1; } - (double)closestTickMarkValueToValue:(double)value { double proposedValue = [super closestTickMarkValueToValue:value]; if (self.lastSliderValue == -1) { self.lastSliderValue = proposedValue; return proposedValue; } double MAX_JUMP = 50; double tickDifference = ABS(self.lastSliderValue - proposedValue); BOOL isTurningUp = proposedValue > self.lastSliderValue; if (tickDifference > MAX_JUMP) { proposedValue = isTurningUp ? 0.0 : self.maxValue; } NSLog(@"value: %.2f gap: %.2f", proposedValue, tickDifference); self.lastSliderValue = proposedValue; return proposedValue; } - (NSRect)rectOfTickMarkAtIndex:(NSInteger)index { return NSZeroRect; } @end 
+2
source

I think you will need to subclass NSSliderCell and override startTrackingAt:inView: continueTracking:at:inView: and stopTracking:at:inView:mouseIsUp:

The continueTracking:at:inView: documentation says:

This method is called in trackMouse: inRect: ofView: untilMouseUp :. The default implementation returns YES if the cell is configured to continuously send activity messages to the target group when the user clicks or drags the mouse. Subclasses can override this method to provide more sophisticated tracking.

0
source

Here's how to do it in Swift

This answer is based on Mark "SBSLiderCell" answer above, but adapted for Swift.

Since it is a subclass of NSSliderCell, be sure to set your own class in Interface Builder for the cell, not NSSlider supervision.

Set the number of mark marks to the desired level of detail (for example, 100) and check the box "Only stop marks".

 class PraxSliderCell : NSSliderCell { var lastSliderValue: Double = -1 override func closestTickMarkValueToValue(value: Double) -> Double { var proposedValue = super.closestTickMarkValueToValue(value) if lastSliderValue == -1 { lastSliderValue = proposedValue } else { let tickDifference = abs(lastSliderValue - proposedValue) let isTurningUp = proposedValue > lastSliderValue if tickDifference > Double(numberOfTickMarks / 2) { proposedValue = isTurningUp ? 0.0 : maxValue } print (NSString(format: "value: %.2f gap: %.2f", proposedValue, tickDifference)) lastSliderValue = proposedValue } return proposedValue } override func rectOfTickMarkAtIndex(index: Int) -> NSRect { return NSZeroRect } } 
0
source

Source: https://habr.com/ru/post/1308503/


All Articles