I understand that NSApp's beginSheet:modalForWindow is deprecated for OS X 10.10. So I need a replacement for it. The thing is that I only want to show a window sheet with a progress wheel and no okay or cancel buttons while some work is under way with performSelectorOnMainThread:withObject:waitUntilDone. Anyway, I have written the following lines of code for Objective-C and Swift.
- (void)Backgroundwork :(NSWindow *)window :(NSString *)labelMsg {
NSRect sheetRect = NSMakeRect(0,0,400,114);
NSWindow *progSheet = [[NSWindow alloc] initWithContentRect:sheetRect styleMask:NSTitledWindowMask backing:NSBackingStoreBuffered defer:YES];
NSView *contentView = [[NSView alloc] initWithFrame:sheetRect];
NSProgressIndicator *progInd = [[NSProgressIndicator alloc] initWithFrame:NSMakeRect(190,74,20,20)];
[progInd setStyle:NSProgressIndicatorSpinningStyle];
NSTextField *messageLabel = [[NSTextField alloc] initWithFrame:NSMakeRect(20,20,240,46)];
messageLabel.stringValue = labelMsg;
[messageLabel setBezeled:NO];
[messageLabel setDrawsBackground:NO];
[messageLabel setEditable:NO];
[messageLabel setSelectable:NO];
[contentView addSubview:messageLabel];
[contentView addSubview:progInd];
[progSheet setContentView:contentView];
[window beginSheet:progSheet completionHandler:^(NSModalResponse returnCode) {
// some work
}];
}
func Backgroundwork(window:NSWindow,labelMsg:String) -> Void {
let sheetRect:NSRect = NSMakeRect(0,0,400,114)
let progSheet:NSWindow = NSWindow.init(contentRect:sheetRect, styleMask:NSTitledWindowMask,backing:NSBackingStoreType.Buffered,`defer`:true)
let contentView:NSView = NSView.init(frame:sheetRect)
let progInd:NSProgressIndicator = NSProgressIndicator.init(frame:NSMakeRect(190,74,20,20))
progInd.style = NSProgressIndicatorStyle.SpinningStyle
let msgLabel:NSTextField = NSTextField.init(frame:NSMakeRect(20,20,240,46))
msgLabel.stringValue = labelMsg;
msgLabel.bezeled = false
msgLabel.drawsBackground = false
msgLabel.editable = false
msgLabel.selectable = false
contentView.addSubview(msgLabel)
contentView.addSubview(progInd)
progSheet.contentView = contentView
window.beginSheet(progSheet) {(NSModalResponse) -> Void in
// some work
}
}
If I'm correct, NSWindow's beginSheet:completionHandler requires response buttons. So the application never enters the beginSheet bloc in the code above. Right? Or can I still use beginSheet:completionHandler without response (okay,cancel) buttons? Or do I have to use something else other than beginSheet like a modal window that I have to open and close?
Thanks.
Update 1
Maybe, making it a modal window with NSModalSession is the best alternative?
let session:NSModalSession = NSApp.beginModalSessionForWindow(progSheet)
This approach seems to conform to OS X 10.10.
Related
My NSPanel in IB has "release when closed" unchecked.
"Visible at Launch" is also unchecked.
I fade the NSPanel in with the following (activated by dragToButton) and it works fine
- (IBAction)dragToFile:(id)sender
{
DragImageView *accessory = [[[DragImageView alloc] initWithFrame:NSMakeRect(0,0,71,63)] autorelease];
[accessory setMainContentFolder:self.mainInstallFolder];
[self.dragToFile setFloatingPanel:YES];
[self.dragToFile makeKeyWindow];
[dragImage setMainContentFolder:self.mainInstallFolder];
NSRect frame = dragToFile.frame;
NSRect mainFrame = self.window.frame;
frame.origin.x = mainFrame.origin.x + 550;
frame.origin.y = mainFrame.origin.y + 360;
[dragToFile setFrame:frame display:NO];
//set fade anim params
NSDictionary *fadeInDict = [NSDictionary dictionaryWithObjectsAndKeys:
dragToFile, NSViewAnimationTargetKey,
NSViewAnimationFadeInEffect, NSViewAnimationEffectKey,
nil];
//create fade instance
NSViewAnimation *fadeIn = [[NSViewAnimation alloc] initWithViewAnimations:[NSArray arrayWithObjects: fadeInDict, nil]];
[fadeIn startAnimation];
[fadeIn release];
But if I close the window on the window's toolbar it triggers the following from a windowWillClose notification
- (void) dragToFileWindowDidClose:(id)sender
{
[dragToFile setAlphaValue:0.0]; //make nspanel 0 alpha so it can fade in again
[dragtoButton setState:NSOffState];
}
The window closes but completely disappears and doesn't come back on the next dragToButton click.
The NSPanel has the following property
#property (retain) IBOutlet NSPanel *dragToFile;
So I'm pretty sure that the window is getting released, but I dont know why because I deselected that option.
Try using [dragToFile setReleasedWhenClosed:NO]; manually, first.
Thanks for your suggestions. I solved it.
Instead of [self.dragToFile makeKeyWindow];
[self.dragToFile makeKeyAndOrderFront:dragToFile];
Not sure why this works and the other doesn't, but it works flawlessly now.
Thanks.
I did a little demo to isolate a problem I faced in a Project.
When I start the Application, the Cells of the NSOutlineView are too narrow for the text:
Then I resize the window with the mouse, making it even narrower than the contents of the NSOutlineView:
When I now enlarge the window again, the problem is cured. From now on the outline works as expected:
This is the main method of my AppDelegate:
- (void)applicationDidFinishLaunching:(NSNotification *)notification {
NSRect frame = NSMakeRect(0., 0., 400., 300.);
NSUInteger styleMask = NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask;
_mainWindow = [[NSWindow alloc] initWithContentRect:frame styleMask:styleMask backing:NSBackingStoreBuffered defer:NO];
_mainWindow.title = #"Outline";
NSScrollView *leftScrollView = [[NSScrollView alloc] init];
leftScrollView.hasVerticalScroller = YES;
leftScrollView.hasHorizontalScroller = NO;
leftScrollView.drawsBackground = NO;
leftScrollView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
_mainWindow.contentView = leftScrollView;
NSOutlineView *outlineView = [[NSOutlineView alloc] init];
NSTableColumn *outlineColumn = [[NSTableColumn alloc] initWithIdentifier:#"Menu Item"];
[outlineView addTableColumn:outlineColumn];
outlineView.outlineTableColumn = outlineColumn;
outlineView.selectionHighlightStyle = NSTableViewSelectionHighlightStyleSourceList;
outlineView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
outlineView.headerView = nil;
_outlineDataSourceAndDelegate = [[MROutlineDataSourceAndDelegate alloc] init];
outlineView.dataSource = _outlineDataSourceAndDelegate;
outlineView.delegate = _outlineDataSourceAndDelegate;
leftScrollView.documentView = outlineView;
[_mainWindow makeKeyAndOrderFront:NSApp];
}
Can anyone please explain that odd behavior?
I don't know whether that is the most elegant solution, but at least it works. I added the following single line after creating the NSTableColumn:
outlineColumn.width = SIDEBAR_WIDTH_DEFAULT;
That's it. Took me almost a day to figure out :(
The answer above was not clean enough for me, so I continued playing around. Now I am pleased: I added a listener to the scroll view that resizes the width of the outline view to be the same as the scroll view. No more need to set the width of the outline column in advance. This is important, if the width is not known in advance.
In my application there is a subclass of NSWindowController. In - (void)awakeFromNib I create an instance of a NSView subclass to create a bottom placed button bar:
self.buttonBar = [[CNButtonBar alloc] initWithSize:NSMakeSize(tableViewRect.size.width-1, 25)];
This CNButtonBar thing has a method to add buttons to itself. I create two of it:
[buttonBar addButtonWithTitle:nil
image:[NSImage imageNamed:NSImageNameAddTemplate]
target:self
action:#selector(btnAccountAddAction:)
alignment:CNBarButtonAlignLeft];
[buttonBar addButtonWithTitle:nil
image:[NSImage imageNamed:NSImageNameRemoveTemplate]
target:self
action:#selector(btnAccountRemoveAction:)
alignment:CNBarButtonAlignLeft];
These two action methods are defined in the same instance of NSViewController where I send the two addButtonWithTitle:... messages.
The methods, used to set the action are defined as followed:
- (void)btnAccountAddAction:(id)sender
{
....
}
- (void)btnAccountRemoveAction:(id)sender
{
....
}
But, it doesn't work. Each time if I click one of these two buttons my application crashes throwing an exception like this one:
-[__NSArrayM btnAccountAddAction:]: unrecognized selector sent to instance 0x1001454e0
Examined this exception is absolutely correct. NSArray doesn't have such a method I want to call. But, from time to time the object that throws this exception is changing. Some times there is a __NSData object, some times a __NSDictionary and so on. It seems that the receiver is anything but my NSWindowController subclass. But the given instance ID 0x1001454e0 is the same my NSWindowController has.
It makes me want to tear my hair out! What's going wrong here...?
Thanks.
UPDATE
I have to say, that both, the CNButtonBar and CNButtonBarButton are completely drawn by code. The complete method of addButtonWithTitle:image:target:action:alignment: is here (remember, this happens in CNButtonBar, a subclass of NSView (should I use NSViewController instead of it?), CNButtonBarButton is a subclass of NSButton):
- (void)addButtonWithTitle:(NSString*)title image:(NSImage*)image target:(id)target action:(SEL)action alignment:(CNBarButtonAlign)align
{
if (self.buttons == nil)
self.buttons = [[NSMutableArray alloc] init];
CNButtonBarButton *button = [[CNButtonBarButton alloc] init];
[self.buttons addObject:button];
button.title = title;
button.image = image;
button.target = target;
button.action = action;
button.align = align;
NSRect buttonRect;
NSSize titleSize = NSMakeSize(0, 0);
if (button.title.length > 0) {
NSMutableParagraphStyle* textStyle = [[NSMutableParagraphStyle defaultParagraphStyle] mutableCopy];
[textStyle setAlignment: NSCenterTextAlignment];
NSColor *textColor = [[NSColor blackColor] colorWithAlphaComponent:0.9];
NSShadow* textShadow = [[NSShadow alloc] init];
[textShadow setShadowColor: [NSColor whiteColor]];
[textShadow setShadowOffset: NSMakeSize(0, -1)];
[textShadow setShadowBlurRadius: 0];
button.titleTextAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
[NSFont fontWithName:#"Helvetica Neue" size:11.0], NSFontAttributeName,
textShadow, NSShadowAttributeName,
textColor, NSForegroundColorAttributeName,
textStyle, NSParagraphStyleAttributeName,
nil];
titleSize = [title sizeWithAttributes:button.titleTextAttributes];
buttonRect = NSMakeRect(0, 0, roundf(titleSize.width) + kTextInset * 2, NSHeight(self.frame) - 1);
}
if (button.image != nil) {
NSSize imageSize = [image size];
if (button.title.length == 0) {
buttonRect = NSMakeRect(0, 0, imageSize.width + kImageInset * 2, NSHeight(self.frame) - 1);
} else {
buttonRect = NSMakeRect(0, 0,
(imageSize.width + kImageInset * 2) + (roundf(titleSize.width) + kTextInset),
NSHeight(self.frame) - 1);
}
}
switch (self.align) {
case CNButtonBarAlignNormal: {
switch (button.align) {
case CNButtonBarButtonAlignLeft: {
button.frame = NSMakeRect(offsetLeft, 0, NSWidth(buttonRect), NSHeight(buttonRect));
offsetLeft += 1 * [self.buttons indexOfObject:button] + NSWidth(button.frame);
break;
}
case CNButtonBarButtonAlignRight: {
button.frame = NSMakeRect(offsetRight - NSWidth(buttonRect), 0, NSWidth(buttonRect), NSHeight(buttonRect));
offsetRight -= 1 * [self.buttons indexOfObject:button] + NSWidth(button.frame);
break;
}
}
break;
}
case CNButtonBarAlignCentered: {
break;
}
}
[self addSubview:button];
}
UPDATE 2
The problem is solved. After some debugging I found out that it must be a problem of ARCs auto retain/release stuff. And I'm right. But the problem was my NSViewController subclass. It was leaking because of making an instance as a local variable (without a strong pointer). Thanks to Sean D., that pointed me to the right way. (-;
Looks like one of two things is happening. The first possibility is that your CNButtonBar object is getting released while the buttons are still around. If the buttons are still there, they'll try to send those selectors to whatever happens to occupy the memory the CNButtonBar used to be in. I'd say make sure it isn't autoreleasing itself anywhere, and that you're not accidentally autoreleasing it in the window controller's -awakeFromNib method. (If you're anything like me, that's the most likely culprit.)
The second possibility is that your -addButtonWithTitle:image:target:action:alignment: method is setting the buttons' actions but not their targets. Make sure your implementation of that method calls -setTarget: as well as -setAction: on the button.
I've got a custom window popping up when an NSStatusItem is clicked. The code is based on MAAtachedwindow. Everything is working great but I can't figure out a way to dismiss the window when the user clicks on something else like another status bar item, or another app.
Here's my code for creating the window:
statusItem = [[[NSStatusBar systemStatusBar] statusItemWithLength:width] retain];
//setup custom status menu view
CGFloat height = [[NSStatusBar systemStatusBar] thickness];
NSRect viewFrame = NSMakeRect(0.0f, 0.0f, width, height);
statusMenuView = [[[_ISStatusMenuView alloc] initWithFrame:viewFrame] retain];
statusMenuView.offset = aOffset;
statusItem.view = statusMenuView;
//setup the window to show when clicked
NSRect contentRect = NSZeroRect;
contentRect.size = aView.frame.size;
statusMenuWindow = [[[NSWindow alloc] initWithContentRect:contentRect
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered
defer:NO] retain];
[statusMenuWindow setLevel:NSPopUpMenuWindowLevel];
[statusMenuWindow setBackgroundColor:[NSColor clearColor]];
[statusMenuWindow setMovableByWindowBackground:NO];
[statusMenuWindow setExcludedFromWindowsMenu:YES];
[statusMenuWindow setOpaque:NO];
[statusMenuWindow setHasShadow:NO];
[statusMenuWindow useOptimizedDrawing:YES];
[[statusMenuWindow contentView] addSubview:aView];
[statusMenuWindow setDelegate:self];
statusMenuView.statusMenuWindow = statusMenuWindow;
And here is how I'm showing the window:
- (void)centerView{
NSRect menuFrame = self.window.frame;
NSRect windowFrame = self.statusMenuWindow.frame;
NSPoint menuPoint = NSMakePoint(NSMidX(menuFrame), NSMinY(menuFrame));
menuPoint.x -= windowFrame.size.width*0.5f;
menuPoint.y -= windowFrame.size.height+self.offset;
[self.statusMenuWindow setFrameOrigin:menuPoint];
[self.statusMenuWindow makeKeyAndOrderFront:self];
}
I was hoping the windowDidResignKey delegate method would do the trick but it doesn't go off with this configuration. The delegate is working because windowDidMove does run.
- (void)windowDidResignKey:(NSNotification *)notification{
NSLog(#"windowDidResignKey");
[statusMenuView hideView];
}
- (void)windowDidResignMain:(NSNotification *)notification{
NSLog(#"windowDidResignMain");
}
- (void)windowDidMove:(NSNotification *)notification{
NSLog(#"windowDidMove");
}
So to recap, how can I hide my custom window when the user clicks on anything else, the way the standard status bar menus work?
Edit
After looking at the Popup example the only thing I was missing was I had to subclass NSPanel and make it so it could become the key window.
#interface Panel : NSPanel
#end
#implementation Panel
- (BOOL)canBecomeKeyWindow{
return YES;
}
#end
You need to make sure your window can become the key window, and call your window's orderOut: method when it resigns key. You should be using a custom NSWindowController, if you are not already, in which case you would just call its "close" method to dismiss your window.
Instead of posting a bunch of code, I would suggest you just look at this excellent, recently-posted example of attaching a window to a status item:
Shpakovski Popup Window Example
In my desktop Mac OS X app, I'd like to programatically create a NSTextField "label" which has the same behavior and properties as a typical label created in Interface Builder.
I usually use (and very much like) IB, but in this case it must be done programatically.
Try as I might, I can't seem to find the combination of method calls that will programatically produce the same label-y behavior as a "Label" dragged from the IB View Library palette.
Can anyone provide or point out some example code of how to do this programatically? Thx.
A label is actually an instance of NSTextField, a subclass of NSView. So, since it is a NSView, it has to be added to another view.
Here's a working code:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
NSTextField *textField;
textField = [[NSTextField alloc] initWithFrame:NSMakeRect(10, 10, 200, 17)];
[textField setStringValue:#"My Label"];
[textField setBezeled:NO];
[textField setDrawsBackground:NO];
[textField setEditable:NO];
[textField setSelectable:NO];
[view addSubview:textField];
}
macOS 10.12 and Later
Starting with macOS 10.12 (Sierra), there are three new NSTextField constructors:
NSTextField(labelWithString:), which the header file comment says “Creates a non-wrapping, non-editable, non-selectable text field that displays text in the default system font.”
NSTextField(wrappingLabelWithString:), which the header file comment says “Creates a wrapping, non-editable, selectable text field that displays text in the default system font.”
NSTextField(labelWithAttributedString:), which the header file comment says “Creates a non-editable, non-selectable text field that displays attributed text. The line break mode of this field is determined by the attributed string's NSParagraphStyle attribute.”
I tested the ones that take a plain (non-attributed string), and they create text fields that are similar to, but not precisely the same as, the text fields created in a storyboard or xib.
The important difference is that both constructors create a text field with textBackgroundColor (normally pure white) as its background color, while the storyboard text field uses controlColor (normally about 90% white).
Unimportantly, both constructors also set their fonts by calling NSFont.systemFont(ofSize: 0) (which produces a different NSFont object than my code below, but they wrap the same underlying Core Text font).
The wrappingLabelWithString: constructor sets the field's isSelectable to true. (This is documented in the header file.)
macOS 10.11 and Earlier
I compared four NSTextField instances: one created by dragging a “Label” to a storyboard, another created by dragging a “Wrapping Label” to a storyboard, and two in code. Then I carefully modified properties of the code-created labels until all their properties were exactly the same as the storyboard-created labels. These two methods are the result:
extension NSTextField {
/// Return an `NSTextField` configured exactly like one created by dragging a “Label” into a storyboard.
class func newLabel() -> NSTextField {
let label = NSTextField()
label.isEditable = false
label.isSelectable = false
label.textColor = .labelColor
label.backgroundColor = .controlColor
label.drawsBackground = false
label.isBezeled = false
label.alignment = .natural
label.font = NSFont.systemFont(ofSize: NSFont.systemFontSize(for: label.controlSize))
label.lineBreakMode = .byClipping
label.cell?.isScrollable = true
label.cell?.wraps = false
return label
}
/// Return an `NSTextField` configured exactly like one created by dragging a “Wrapping Label” into a storyboard.
class func newWrappingLabel() -> NSTextField {
let label = newLabel()
label.lineBreakMode = .byWordWrapping
label.cell?.isScrollable = false
label.cell?.wraps = true
return label
}
}
If you use one of these methods, don't forget to set your field's frame, or turn off its translatesAutoresizingMaskIntoConstraints and add constraints.
Here is the code I used to compare the different text fields, in case you want to check:
import Cocoa
class ViewController: NSViewController {
#IBOutlet var label: NSTextField!
#IBOutlet var multilineLabel: NSTextField!
override func loadView() {
super.loadView()
}
override func viewDidLoad() {
super.viewDidLoad()
let codeLabel = NSTextField.newLabel()
let codeMultilineLabel = NSTextField.newWrappingLabel()
let labels = [label!, codeLabel, multilineLabel!, codeMultilineLabel]
for keyPath in [
"editable",
"selectable",
"allowsEditingTextAttributes",
"importsGraphics",
"textColor",
"preferredMaxLayoutWidth",
"backgroundColor",
"drawsBackground",
"bezeled",
"bezelStyle",
"bordered",
"enabled",
"alignment",
"font",
"lineBreakMode",
"usesSingleLineMode",
"formatter",
"baseWritingDirection",
"allowsExpansionToolTips",
"controlSize",
"highlighted",
"continuous",
"cell.opaque",
"cell.controlTint",
"cell.backgroundStyle",
"cell.interiorBackgroundStyle",
"cell.scrollable",
"cell.truncatesLastVisibleLine",
"cell.wraps",
"cell.userInterfaceLayoutDirection"
] {
Swift.print(keyPath + " " + labels.map({ ($0.value(forKeyPath: keyPath) as? NSObject)?.description ?? "nil" }).joined(separator: " "))
}
}
}
This can be tricky to get right. I don't have the recipe for an exact replica handy, but when I've been stuck in a similar situation, here's what I do:
Create a UI element in IB.
Add an outlet to it from my controller class.
Break in gdb in awakeFromNib or whatever.
From the gdb prompt, "p *whateverOutlet" ... this will show you the C struct contents of the label NSTextField that IB set up.
By looking at all the myriad values in there, you can get a lot of guesses about what you're neglecting to set. Usually it ends up being some magic combination of bezel and border settings, that gets you where you want to be.
You could try using nib2objc to get all the properties that IB sets
Disassembled AppKit in Objective-C:
BOOL TMPSierraOrLater() {
static BOOL result = NO;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
result = [NSProcessInfo.processInfo isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){ 10, 12, 0 }];
});
return result;
}
#implementation NSTextField (TMP)
+ (instancetype)TMP_labelWithString:(NSString *)stringValue {
if (TMPSierraOrLater()) {
return [self labelWithString:stringValue];
}
NSParameterAssert(stringValue);
NSTextField *label = [NSTextField TMP_newBaseLabelWithoutTitle];
label.lineBreakMode = NSLineBreakByClipping;
label.selectable = NO;
[label setContentHuggingPriority:(NSLayoutPriorityDefaultLow + 1) forOrientation:NSLayoutConstraintOrientationHorizontal];
[label setContentHuggingPriority:NSLayoutPriorityDefaultHigh forOrientation:NSLayoutConstraintOrientationVertical];
[label setContentCompressionResistancePriority:NSLayoutPriorityDefaultHigh forOrientation:NSLayoutConstraintOrientationHorizontal];
[label setContentCompressionResistancePriority:NSLayoutPriorityDefaultHigh forOrientation:NSLayoutConstraintOrientationVertical];
label.stringValue = stringValue;
[label sizeToFit];
return label;
}
+ (instancetype)TMP_wrappingLabelWithString:(NSString *)stringValue {
if (TMPSierraOrLater()) {
return [self wrappingLabelWithString:stringValue];
}
NSParameterAssert(stringValue);
NSTextField *label = [NSTextField TMP_newBaseLabelWithoutTitle];
label.lineBreakMode = NSLineBreakByWordWrapping;
label.selectable = YES;
[label setContentHuggingPriority:NSLayoutPriorityDefaultLow forOrientation:NSLayoutConstraintOrientationHorizontal];
[label setContentHuggingPriority:NSLayoutPriorityDefaultHigh forOrientation:NSLayoutConstraintOrientationVertical];
[label setContentCompressionResistancePriority:NSLayoutPriorityDefaultLow forOrientation:NSLayoutConstraintOrientationHorizontal];
[label setContentCompressionResistancePriority:NSLayoutPriorityDefaultHigh forOrientation:NSLayoutConstraintOrientationVertical];
label.stringValue = stringValue;
label.preferredMaxLayoutWidth = 0;
[label sizeToFit];
return label;
}
+ (instancetype)TMP_labelWithAttributedString:(NSAttributedString *)attributedStringValue {
if (CRKSierraOrLater()) {
return [self labelWithAttributedString:attributedStringValue];
}
NSParameterAssert(attributedStringValue);
NSTextField *label = [NSTextField TMP_newBaseLabelWithoutTitle];
[label setContentHuggingPriority:NSLayoutPriorityDefaultLow forOrientation:NSLayoutConstraintOrientationHorizontal];
[label setContentHuggingPriority:NSLayoutPriorityDefaultHigh forOrientation:NSLayoutConstraintOrientationVertical];
[label setContentCompressionResistancePriority:NSLayoutPriorityDefaultLow forOrientation:NSLayoutConstraintOrientationHorizontal];
[label setContentCompressionResistancePriority:NSLayoutPriorityDefaultHigh forOrientation:NSLayoutConstraintOrientationVertical];
label.attributedStringValue = attributedStringValue;
[label sizeToFit];
return label;
}
#pragma mark - Private API
+ (instancetype)TMP_newBaseLabelWithoutTitle {
NSTextField *label = [[self alloc] initWithFrame:CGRectZero];
label.textColor = NSColor.labelColor;
label.font = [NSFont systemFontOfSize:0.0];
label.alignment = NSTextAlignmentNatural;
label.baseWritingDirection = NSWritingDirectionNatural;
label.userInterfaceLayoutDirection = NSApp.userInterfaceLayoutDirection;
label.enabled = YES;
label.bezeled = NO;
label.bordered = NO;
label.drawsBackground = NO;
label.continuous = NO;
label.editable = NO;
return label;
}
#end
Specifically, you will want to setBordered:NO, and set the bezel style to whatever that bezel style is which I forgot. Also setEditable:NO, and optionally setSelectable:NO. That should suffice.