Skip to content

Instantly share code, notes, and snippets.

@michal-tomlein
Created August 14, 2015 09:35
Show Gist options
  • Save michal-tomlein/39171668c580ac0d497d to your computer and use it in GitHub Desktop.
Save michal-tomlein/39171668c580ac0d497d to your computer and use it in GitHub Desktop.
An NSSegmentedControl subclass with support for conditional segment selection via a delegate.
//
// MTSegmentedControl.h
//
// Created by Michal Tomlein on 14/08/15.
// Copyright (c) 2015 Michal Tomlein. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@class MTSegmentedControl;
@protocol MTSegmentedControlDelegate <NSObject>
- (BOOL)segmentedControl:(MTSegmentedControl *)control shouldSelectSegment:(NSInteger)segment;
@end
@interface MTSegmentedControl : NSSegmentedControl
@property (nonatomic, weak) id <MTSegmentedControlDelegate> delegate;
@end
//
// MTSegmentedControl.m
//
// Created by Michal Tomlein on 14/08/15.
// Copyright (c) 2015 Michal Tomlein. All rights reserved.
//
#import "MTSegmentedControl.h"
@interface MTSegmentedCell : NSSegmentedCell {
CGFloat _segmentContentInset;
NSMutableDictionary *_segmentOffsets;
}
@end
@implementation MTSegmentedCell
- (void)drawSegment:(NSInteger)segment inFrame:(NSRect)frame withView:(NSView *)controlView
{
if (segment) {
if (!_segmentOffsets)
_segmentOffsets = [[NSMutableDictionary alloc] initWithCapacity:self.segmentCount];
_segmentOffsets[@(segment)] = @(frame.origin.x - _segmentContentInset + 1.0);
} else {
_segmentContentInset = frame.origin.x;
}
[super drawSegment:segment inFrame:frame withView:controlView];
}
- (void)stopTracking:(NSPoint)lastPoint at:(NSPoint)stopPoint inView:(id)controlView mouseIsUp:(BOOL)flag
{
if ([controlView isKindOfClass:[MTSegmentedControl class]]) {
id <MTSegmentedControlDelegate> delegate = [controlView delegate];
if (delegate) {
NSInteger segment = self.segmentCount - 1;
while (segment >= 0) {
if (stopPoint.x < [_segmentOffsets[@(segment)] doubleValue]) {
segment--;
} else {
break;
}
}
if (segment >= 0 && ![delegate segmentedControl:controlView shouldSelectSegment:segment]) {
return;
}
}
}
[super stopTracking:lastPoint at:stopPoint inView:controlView mouseIsUp:flag];
}
@end
@implementation MTSegmentedControl
+ (Class)cellClass
{
return [MTSegmentedCell class];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment