Created
October 2, 2013 08:35
-
-
Save andreyvit/6790726 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <Cocoa/Cocoa.h> | |
// NSTextField has alignmentRectInsets = {.left=.right=3, .top=.bottom=0}, so | |
// when autolayout aligns NSTextField to its container's side margin (e.g. to x=0), | |
// the actual x position is -3, and the label gets clipped. | |
// | |
// ATUnclippedTextField compensates for that by overriding drawRect to extend | |
// the clipping rect by alignmentRectInsets. | |
// | |
// Note that visual artifacts may occur in certain case; make sure that no other views | |
// are within a 3px area to both sides of the label. We take care of NSClipView, | |
// any other view interactions are up to you. | |
// | |
// Requires OS X 10.7. | |
// | |
@interface ATUnclippedTextField : NSTextField | |
@end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "ATUnclippedTextField.h" | |
static NSView *ATFindViewAncestorByClass(NSView *view, Class ancestorClass) { | |
NSView *contentView = view.window.contentView; | |
while (view != nil) { | |
if ([view isKindOfClass:ancestorClass]) | |
return view; | |
if (view == contentView) | |
break; | |
view = view.superview; | |
} | |
return nil; | |
} | |
@implementation ATUnclippedTextField | |
// has no effect (for an unknown reason), but we set our own clipping rect anyway, so it cannot hurt either | |
- (BOOL)wantsDefaultClipping { | |
return NO; | |
} | |
- (void)drawRect:(NSRect)dirtyRect { | |
[NSGraphicsContext saveGraphicsState]; | |
NSRect clipRect = self.bounds; | |
// compensate for alignment rect insets by extending the clip rect | |
NSEdgeInsets insets = self.alignmentRectInsets; | |
clipRect.origin.x -= insets.left; | |
clipRect.size.width += insets.left + insets.right; | |
// force-clip by NSClipView to avoid the 3px overhang spilling out of NSScrollView | |
NSView *clippingAncestor = ATFindViewAncestorByClass(self, [NSClipView class]); | |
if (clippingAncestor) { | |
NSRect ancestorRect = [self convertRect:clippingAncestor.bounds fromView:clippingAncestor]; | |
clipRect = NSIntersectionRect(clipRect, ancestorRect); | |
} | |
[[NSBezierPath bezierPathWithRect:clipRect] setClip]; | |
[super drawRect:dirtyRect]; | |
[NSGraphicsContext restoreGraphicsState]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment