I use standard NSButton with custom background. With black title color there is white shadow - how can I remove it?
Image:
http://i.piccy.info/i7/f4ae52b56aad922f0129e4b6bd8688da/4-57-36/57765457/Snymok_ekrana_2013_03_19_v_04_13_58.png
Solved!
NSAttributedString documentation says that default value of NSShadowAttributeName is nil, but in this case the button title is drawn with white shadow. Transparent shadow solved problem:
NSShadow *shadow = [[NSShadow alloc] init];
[shadow setShadowColor:[NSColor colorWithDeviceWhite:1.0 alpha:0.0]];
NSDictionary *attrsDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
shadow, NSShadowAttributeName, nil];
NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:_customTitle attributes:attrsDictionary];
[mybutton setAttributedTitle:attrString];
Related
I'd like to replicate the recessed text style of Messages/iMessage, or, the text "white-shadow" style on a light gray background.
As you can see, the texts are with "white-shadow" even on the light gray background. The bold texts do have subpixel rendering while the gray texts don't (by design?).
I've tried -setBackgroundStyle:NSBackgroundStyleRaised . However it was generating shadows darker than the background. -setBackgroundStyle:NSBackgroundStyleLowered was worse that it even overrode my font colour setting.
So, what is the right way to do this? Any tricks or just have to subclass NSTextFields?
Solution 1:
The most simplest solution which I can think is to write two texts on each other (For example gray on top and white with difference 1px at bottom).
Solution 2:
And of course it can be done by subclassing NSTextFieldCell and adding shadow.
Just like this:
- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
NSShadow *shadow = [[NSShadow alloc] init];
[shadow setShadowOffset:NSMakeSize(0,-1)];
[shadow setShadowColor:[NSColor whiteColor]];
[shadow setShadowBlurRadius:0];
NSMutableParagraphStyle *paragStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[paragStyle setAlignment:[self alignment]];
NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:
[self font],NSFontAttributeName,
shadow,NSShadowAttributeName,
[self textColor],NSForegroundColorAttributeName,
paragStyle,NSParagraphStyleAttributeName,nil];
[shadow release];
[paragStyle release];
NSAttributedString *string = [[NSAttributedString alloc] initWithString:[self stringValue] attributes:attributes];
[self setAttributedStringValue:string];
[string release];
[[self attributedStringValue] drawInRect:cellFrame];
}
Result:
I have a panel nib with an outlet for one of its textfields, which is set in the nib to have centered alignment. When I display the panel, I would like this textfield to be bolded.
Since NSTextField is a subclass of NSControl, it can use the setAttributedStringValue method and take an attributed string. So I incorporated a bold font like this:
NSFont *fontBolded = [NSFont fontWithName:#"Baskerville Bold" size:12.0f];
NSDictionary *dictBoldAttr = [NSDictionary dictionaryWithObject:fontBolded forKey:NSFontAttributeName];
NSString *sHelloUser = NSLocalizedString(#"Hello User", #"Hello User");
NSAttributedString *attrsHelloUser = [[NSAttributedString alloc] initWithString: sHelloUser attributes:dictBoldAttr];
[self.fooController.tfPanelCenteredField setAttributedStringValue:attrsHelloUser];
[attrsHelloUser release];
The bolding shows up OK, but the field is now left-aligned.
I tried adding a setAlignment, but it had no effect:
[self.fooController.tfPanelCenteredField setAlignment:NSCenterTextAlignment];
So I tried adding a centered parapraph style to the attributed string’s attributes:
NSFont *fontBolded = [NSFont fontWithName:#"Baskerville Bold" size:12.0f];
NSMutableParagraphStyle *paragStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[paragStyle setAlignment:NSCenterTextAlignment];
NSDictionary *dictBoldAttr = [NSDictionary dictionaryWithObjectsAndKeys:paragStyle, NSParagraphStyleAttributeName, fontBolded, NSFontNameAttribute, nil];
NSString *sHelloUser = NSLocalizedString(#"Hello User", #"Hello User");
NSAttributedString *attrsHelloUser = [[NSAttributedString alloc] initWithString: sHelloUser attributes:dictBoldAttr];
[self.fooController.tfPanelCenteredField setAttributedStringValue:attrsHelloUser];
[attrsHelloUser release];
[paragStyle release];
Now the textfield is centered again, but the bolding is gone. It’s as though the attributed string can accept one and only one attribute setting. Am I missing something simple?
You have a typo in your code. NSFontNameAttribute should be NSFontAttributeName.
So your attributes dictionary is:
NSFont *fontBolded = [NSFont fontWithName:#"Baskerville Bold" size:12.0f];
NSMutableParagraphStyle *paragStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[paragStyle setAlignment:NSCenterTextAlignment];
NSDictionary *dictBoldAttr = [NSDictionary dictionaryWithObjectsAndKeys:
fontBolded, NSFontAttributeName,
paragStyle, NSParagraphStyleAttributeName,
nil];
I used
[button setAlignment:NSCenterTextAlignment];
to make the text display at the center of the button.
It worked.
But if I set button title attribute before the code, button 'setAlignment' will not work
- (void)setButtonTitle:(NSButton*)button fontName:(NSString*)fontName fontSize:(CGFloat)fontSize fontColor:(NSColor*)fontColor;
{
NSMutableAttributedString *attributedString =
[[NSMutableAttributedString alloc] initWithString:[button title]
attributes:[NSDictionary dictionaryWithObject:[NSFont fontWithName:fontName size:fontSize]
forKey:NSFontAttributeName]];
[attributedString addAttribute:NSForegroundColorAttributeName
value:fontColor
range:NSMakeRange(0, [[button title] length] )];
[button setAttributedTitle: attributedString];
[button setAlignment:NSCenterTextAlignment];//button title alignment always displayed as 'NSLeftTextAlignment' rather than 'NSCenterTextAlignment'.
}
title alignment always displayed as 'NSLeftTextAlignment' rather than 'NSCenterTextAlignment'.
Welcome any comment
Since you’re using an attributed string for the button title, the attributes in that string are responsible for setting the alignment.
To centre that attributed string, add an NSParagraphStyleAttributeName attribute with a centred alignment value:
NSMutableParagraphStyle *centredStyle = [[[NSParagraphStyle defaultParagraphStyle] mutableCopy] autorelease];
[centredStyle setAlignment:NSCenterTextAlignment];
NSDictionary *attrs = [NSDictionary dictionaryWithObjectsAndKeys:centredStyle,
NSParagraphStyleAttributeName,
[NSFont fontWithName:fontName size:fontSize],
NSFontAttributeName,
fontColor,
NSForegroundColorAttributeName,
nil];
NSMutableAttributedString *attributedString =
[[NSMutableAttributedString alloc] initWithString:[button title]
attributes:attrs];
[button setAttributedTitle: attributedString];
In the code above, I’ve created a single attrs dictionary holding all the attributes for the attributed string. From your code, it looks like the font colour should be applied to the whole string anyway.
I am making an app that is a standalone menu item and the basis for the code is sample code I found on a website. The sample code uses a number as the menu icon, but I want to change it to an image.
I want it to be like other apps where it shows icon.png when not clicked and icon-active.png when clicked.
The current code is this:
- (void)drawRect:(NSRect)rect {
// Draw background if appropriate.
if (clicked) {
[[NSColor selectedMenuItemColor] set];
NSRectFill(rect);
}
// Draw some text, just to show how it's done.
NSString *text = #"3"; // whatever you want
NSColor *textColor = [NSColor controlTextColor];
if (clicked) {
textColor = [NSColor selectedMenuItemTextColor];
}
NSFont *msgFont = [NSFont menuBarFontOfSize:15.0];
NSMutableParagraphStyle *paraStyle = [[NSMutableParagraphStyle alloc] init];
[paraStyle setParagraphStyle:[NSParagraphStyle defaultParagraphStyle]];
[paraStyle setAlignment:NSCenterTextAlignment];
[paraStyle setLineBreakMode:NSLineBreakByTruncatingTail];
NSMutableDictionary *msgAttrs = [NSMutableDictionary dictionaryWithObjectsAndKeys:
msgFont, NSFontAttributeName,
textColor, NSForegroundColorAttributeName,
paraStyle, NSParagraphStyleAttributeName,
nil];
[paraStyle release];
NSSize msgSize = [text sizeWithAttributes:msgAttrs];
NSRect msgRect = NSMakeRect(0, 0, msgSize.width, msgSize.height);
msgRect.origin.x = ([self frame].size.width - msgSize.width) / 2.0;
msgRect.origin.y = ([self frame].size.height - msgSize.height) / 2.0;
[text drawInRect:msgRect withAttributes:msgAttrs];
}
Also, I found a post describing a method on how to do this, but it did not work for me. The url to that is this: http://mattgemmell.com/2008/03/04/using-maattachedwindow-with-an-nsstatusitem/comment-page-1#comment-46501.
Thanks!
Use an NSImage and draw it where desired. For example:
NSString *name = clicked? #"icon-active" : #"icon";
NSImage *image = [NSImage imageNamed:name];
NSPoint p = [self bounds].origin;
[image drawAtPoint:p fromRect:NSZeroRect
operation:NSCompositeSourceOver fraction:1.0];
If this is for a status item and you just want an icon with no programmatic drawing, drop the view and set the status item's image and alternateImage. The former is what the status item uses normally; the status item switches to the alternate image (if it has one) when the user opens its menu.
i have an uibarbuttonitem, but i was initialize it using initwithcustomview. I want to change it backgrounds using an image, but i dont know how to do. I was using setBackground method, like this
NSArray *segmentText = [segmentTextMutable copy];
UIImage *image = [[[UIImage alloc] init] autorelease];
image = [UIImage imageNamed:#"bunga.jpg"];
_docSegmentedControl = [[UISegmentedControl alloc] initWithItems:segmentText];
_docSegmentedControl.autoresizingMask = UIViewAutoresizingFlexibleHeight;
_docSegmentedControl.segmentedControlStyle = UISegmentedControlStyleBezeled;
[_docSegmentedControl addTarget:self action:#selector(docSegmentAction:) forControlEvents:UIControlEventValueChanged];
[_docSegmentedControl setBackgroundColor:[UIColor colorWithPatternImage:image]];
but the uibarbuttonitem still not show the image, it's just change the segmented control background, not the barbutton.
Can somebody help me?
Perhaps you want to change the tint-color (#property(nonatomic, retain) UIColor *tintColor) because UISegmentedControl has no background-color (just because it inherits it from UIView does not mean it uses it though)