Why doesn't this code draw white text? - objective-c

This code doesn't draw white text, why?
NSMutableParagraphStyle* style = [[NSMutableParagraphStyle alloc] init];
[style setAlignment:NSCenterTextAlignment];
NSFont *font = [NSFont fontWithName:#"System" size:13];
NSDictionary *attrs = [NSDictionary dictionaryWithObjectsAndKeys:style, NSParagraphStyleAttributeName, font, NSFontAttributeName, [NSColor whiteColor], NSForegroundColorAttributeName, nil];
[button.title drawInRect:textRect withAttributes:attrs];

(Assuming the [cocoa] tag doesn't mean cocoa touch)
It's because NSButton is likely overriding the choice you've made to draw it's text in when it's -drawRect: gets called again. You can apply the attributes you've given in that dictionary to an NSAttributedString and call setAttributedTitle: to keep your style choices around.
If you need more fine-grain control over text rendering, either edit and move your logic into -drawRect: if it isn't already there, or provide an NSTextField or NSTextView as appropriate.
The main problem with the code you've provided is that #"System" isn't a font name.

Related

Using NSBackgroundStyleLowered on an NSButtonCell?

I use this snippet of code...
[[textField cell] setBackgroundStyle:NSBackgroundStyleLowered];
...to give a piece of text a shadow, and it works. When I try to do the same thing with a button:
[[refreshButton cell] setBackgroundStyle:NSBackgroundStyleLowered];
the code doesn't work. The button is a Momentary Change button with a white transparent circular arrow. Any ideas why this couldn't be working? It seems like it would work, since it is still a cell.
NSCell subclasses have different drawing behaviors. So a settable background style doesn't mean that the style is actually used in the concrete subclass.
NSButtonCells use the interiorBackgroundStyle property before drawing the title. This property doesn't expose a setter, so you'd have to subclass NSButtonCell and set the cell class in Interface Builder accordingly.
To achieve the lowered background style, override interiorBackgroundStyle in your subclass:
- (NSBackgroundStyle)interiorBackgroundStyle
{
return NSBackgroundStyleLowered;
}
If you need more control over the drawing, you could also override NSButtonCell's drawInteriorWithFrame:inView:.
A hacky approach (that doesn't require subclassing) would be to modify the attributed title string to achieve a similar effect:
NSShadow* shadow = [[NSShadow alloc] init];
[shadow setShadowOffset:NSMakeSize(0,-1)];
[shadow setShadowColor:[NSColor whiteColor]];
[shadow setShadowBlurRadius:0];
NSAttributedString* title = [button.cell attributedTitle];
NSMutableDictionary* attributes = [[title attributesAtIndex:0 longestEffectiveRange:NULL inRange:NSMakeRange(0, title.length)] mutableCopy];
[attributes setObject:shadow forKey:NSShadowAttributeName];
NSAttributedString* string = [[NSAttributedString alloc] initWithString:[button.cell title] attributes:attributes];
[button.cell setAttributedTitle:string];

NSTextView with shadow

I'm trying to add a nice looking shadow to a NSTextViews string, I have this Code so far:
NSShadow *textShadow = [[NSShadow alloc] init];
textShadow.shadowColor = [[NSColor blackColor]
colorWithAlphaComponent:0.3];
textShadow.shadowOffset = NSMakeSize(5.0, -5.0);
textShadow.shadowBlurRadius = 3;
NSDictionary *d = #{NSShadowAttributeName : textShadow,
NSFontAttributeName : [NSFont fontWithName:#"Arial Black" size:36.0],
NSStrokeWidthAttributeName : [NSNumber numberWithFloat:-3.0],
NSStrokeColorAttributeName : [NSColor whiteColor]};
[tv setTypingAttributes:d];
all in all this brings up a pretty looking Drop shadow on the right and the bottom of the string in the NSTextView but because the internal drawing mechanism of the textview seems to draw the "fill" of the Characters first and then the stroke around it, the Shadow lays above the fill of the text in the upper left of the Chars, which looks very bad as you can see here(would post an Image but not enough reputation right now 8-/ )
Is there a better way to add the shadow or a way to "raise" the fill color of the String so it lays above the shadow or is this kind of a Bug in the Foundation framework?
Thanks and greetings,
Alex.

iOS 5: Text Color for UIBarButtonSystemItemAdd

I'm able to change the text color of UIBarButtonItem using this code snippet (iOS 5+):
NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
[attributes setValue:[UIColor blackColor] forKey:UITextAttributeTextColor];
[[UIBarButtonItem appearance] setTitleTextAttributes:attributes forState:UIControlStateNormal];
Unfortunately this does not affect UIBarButtonSystemItemAdd.
Is there a way to change the text color of the UIBarButtonSystemItemAdd ?
Use setTintColor. For example:
[downloadButtonItem setTintColor:[UIColor colorWithRed:247.0/255.0 green:247.0/255.0 blue:247.0/255.0 alpha:1.0]];
I know no way to achieve this -- system UIBarButtonItem instances use images instead of text, so changing their color cannot be done by changing their title text color. You most likely have to create your own bar button item.

NSTextField add line spacing

I use NSTextField not NSTextView to receive the user input, but I need to custom the font and textColor and line spacing. I use the code below, it's ok for font and color but I don't know how to set a line spacing.
[self.titleField setTextColor:textColor];
[self.titleField setFont:bold14];
And I also use a NSAttributedString to solve the problem:
NSFont *bold14 = [NSFont boldSystemFontOfSize:14.0];
NSColor *textColor = [NSColor redColor];
NSMutableParagraphStyle *textParagraph = [[NSMutableParagraphStyle alloc] init];
[textParagraph setLineSpacing:10.0];
NSDictionary *attrDic = [NSDictionary dictionaryWithObjectsAndKeys:bold14, NSFontAttributeName, textColor, NSForegroundColorAttributeName, textParagraph, NSParagraphStyleAttributeName, nil];
NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:title attributes:attrDic];
[self.titleField setAllowsEditingTextAttributes:YES];
[self.titleField setAttributedStringValue:attrString];
the code above is ok to show a attributed string, but when I delete the string in the textfield and start to input, the words come without any attribute.
How can I input a string in NSTextField with custom font, color and line spacing?
It's best to stay with NSTextField's attribute setting methods instead of an NSAttributedString because then it can send the settings to the field editor. Every text field has an NSTextView (most of the time) "Field Editor"; and the field editor is what is doing the editing.
Your NSAttributedString isn't sticking because you're only telling the textfield to temporarily display that one string. When the field editor pops up the text field (cell) passes on its own attributes like textField.font and textField.textColor but never the NSAttributedString's attributes.
It would be best to use an NSTextView to be able to use -setDefaultParagraphStyle because you're editing multiple lines anyways, from what I see. If you can't, because of performance problems or something else, then:
Subclass NSTextFieldCell, because that's what does all the NSTextField work, and override
- (NSText *)setUpFieldEditorAttributes:(NSText *)textObj
(declared in NSCell) to set up attributes for your field editor the way you want it, so you can send it a line height value through -setDefaultParagraphStyle (and font etc.) yourself. (textObj is the field editor to be set up).

How to control the text color of an NSTextField when it is displaying a placeholder marker?

When the NSTextField (Label) is bound to a controller selection with bindings, and I have specified placeholder values for the Multiple Values Marker, No Selection Marker, etc it draws the text with a gray color that does not show up well on a dark background.
Is there a way to change the text color it uses to display the placeholder text?
Use an attributed string specifying the color you want, like this:
NSDictionary *blueDict = [NSDictionary dictionaryWithObject: [NSColor blueColor]
forKey: NSForegroundColorAttributeName];
NSAttributedString *blueString = [[[NSAttributedString alloc] initWithString: #"test"
attributes: blueDict] autorelease];
Then you can either set the placeholder attributed string directly:
[[field cell] setPlaceholderAttributedString: blueString];
or do it through a binding, for example:
[field2 bind: #"value" toObject: [NSUserDefaults standardUserDefaults]
withKeyPath: #"foo"
options: [NSDictionary dictionaryWithObject: blueString forKey: NSNullPlaceholderBindingOption]];
you can try to make your own "palceholder". I mean your can show a label over your textfield with any text patameters you want.