I am displaying buttons in NSMatrix.
My requirement is:
to change color of button title and
place an image at beginning of title, when certain condition is satisfied.
To do so, I used following code:
// setting attributed text
NSAttributedString *selectedCellAttribute;
NSFont *selectedCellFont = [NSFont fontWithName:#"Lucida Grande" size:11];
NSColor *selectedCellColor = [NSColor redColor];
NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[style setAlignment:NSCenterTextAlignment];
// setting image
NSTextAttachment *imageAttachment = [[NSTextAttachment alloc] init];
NSCell *cell = [imageAttachment attachmentCell];
[cell setImage:[NSImage imageNamed:#"caution_small.png"]];
NSDictionary *selectedCellDictionary = [NSDictionary dictionaryWithObjectsAndKeys:imageAttachment,NSAttachmentAttributeName,selectedCellFont,NSFontAttributeName,selectedCellColor,NSForegroundColorAttributeName,style,NSParagraphStyleAttributeName,nil];
// recognizing cell
NSButtonCell *associatedCell = [associatesMatrix cellAtRow:0 column:2];
selectedCellAttribute = [[NSAttributedString alloc] initWithString:[associatedCell title] attributes:selectedCellDictionary];
[associatedCell setAttributedTitle:selectedCellAttribute];
Although above code is showing change in color of title, it is showing no image placed in beginning of title :(
Can anyone suggest me where I may be wrong or some other method to implement my requirements?
EDIT:
At line:
NSCell *cell = [imageAttachment attachmentCell];
it is giving this warning when compiled:
type 'id <NSTextAttachmentCell>' does not conform to 'NSCopying" protocol.
Thanks,
Miraaj
You've set the attachment for the entire string. What you need to do is prefix the string with NSAttachmentCharacter, and set the attachment only for that section of the string.
You may want to put a space between the NSAttachmentCharacter and your actual text. Only the NSAttachmentCharacter should have the attachment attribute.
Related
I'm loading a simple HTML into NSTextView. I have already set the font attributes for NSTextView but the loading of HTML ignore these fonts and defaults always to 'Times-Roman 12 size'. Currently I'm enumerating through the attributes and setting the font size. But it seems expensive to do this just for changing the size. Is this the only way to do it? Is there a better way?
HTML:
<p>This is just a <b>title</b></p>
Loading HTML into NSTextView & subsequent change of fontsize:
NSData *valueInDataFormat = [bodyContent dataUsingEncoding:NSUTF8StringEncoding];
NSAttributedString *textToBeInserted = [[NSAttributedString alloc] initWithHTML:valueInDataFormat documentAttributes:nil];
NSDictionary *rtfTextAttributes = [self defaultTextAttributesFor:RTFText];
//inserttext mimic what user do; so it takes the typingattributes
//ref: http://www.cocoabuilder.com/archive/cocoa/113938-setting-default-font-of-an-nstextview.html#114071
[entryContent setString:#""];
[entryContent setTypingAttributes:rtfTextAttributes];
[entryContent insertText:textToBeInserted];
//now change font size
NSTextStorage *content = [entryContent textStorage];
[content beginEditing];
NSRange totalRange = NSMakeRange (0, content.length);
[content enumerateAttributesInRange: totalRange
options: 0
usingBlock: ^(NSDictionary *attributes, NSRange range, BOOL *stop) {
NSLog (#"range: %# attributes: %#",
NSStringFromRange(range), attributes);
NSFont *font = [attributes objectForKey:NSFontAttributeName];
if (font){
[content removeAttribute:NSFontAttributeName range:range];
font = [[NSFontManager sharedFontManager] convertFont:font toSize:[font pointSize] + 3];
[content addAttribute:NSFontAttributeName value:font range:range];
}
}];
[content endEditing];
[entryContent didChangeText];
Came across this problem recently, in the end I found it was possible to use a <style> block at the front of the HTML content and set the font-family to the system default. This works well and allows the HTML to describe all the bold and italic attributes whilst using the system font.
NSString* bodyContent = #"<p>This is just a <b>title</b></p>";
NSMutableString *htmlContent = [NSMutableString string];
[html appendString: #"<style>body { font-family: "];
[html appendString: [[NSFont systemFontOfSize: 12] fontName]];
[html appendString: #"; }</style>"];
[html appendString: bodyContent];
NSData *htmlData = [htmlContent dataUsingEncoding:NSUTF8StringEncoding];
NSAttributedString *html = [[NSAttributedString alloc] initWithHTML: htmlDescriptionData baseURL: NULL documentAttributes: NULL];
There might be a more elegant solution to this, but I have not found it yet.
You can use a WebPreferences object to control the font used when creating an attributed string from HTML.
The method -initWithHTML:options:documentAttributes: takes an options dictionary. One of the recognized keys for that dictionary is NSWebPreferencesDocumentOption. The value is a WebPreferences instance to be used when interpreting the HTML.
A WebPreferences instance has several font family settings. The one which is used when no other font attributes have been specified in the HTML is -standardFontFamily. If the HTML specifies a font class (such as "sans-serif") but no specific font, then the settings for that font class (such as -sansSerifFontFamily) is used.
WebPreferences also has settings for the font size.
For example:
WebPreferences *webPreferences = [[WebPreferences alloc] initWithIdentifier:#"com.company.app.something"];
webPreferences.standardFontFamily = [someFont familyName]; // or a hard-coded family name like #"Helvetica Neue"
webPreferences.defaultFontSize = [NSFont systemFontSize];
...
[[NSAttributedString alloc] initWithHTML:htmlData
options:#{NSWebPreferencesDocumentOption : webPreferences}
documentAttributes:NULL];
There's a caveat: the system font is of a family which is hidden from WebPreferences/NSAttributedString. On Mavericks, its name is ".Lucida Grande UI"; on Yosemite, its name is ".Helvetica Neue UI". For some reason, these can't be used when converting HTML to an attributed string using a WebPreferences object. My best guess is that it's because they aren't listed in [[NSFontManager sharedFontManager] availableFontFamilies]. When you try to use such a font family, the system defaults to Times (yuck!).
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'm sure I'm just using it incorrectly, but what I'm doing is I have a NSTextField with a attributed string with a few characters of text in a different font at the end of it. When the user clicks the text field, the text at the end should disappear, and when the user finishes editing their text and removes focus from the text field, the text gets added back to the end of the string they entered.
It's working fine when then user tabs out of the box, or clicks somewhere on the window to remove focus from the textfield. The only time it doesn't work is if they hit the "return" key in the text box. The text still gets added to the end of their string in this case, but it's in the same font as the rest of the string.
Here is the relevant portion of my code. I've verified that both methods are being called in the same sequence both when I tab out of a field and when I hit enter in the field.
- (void) selectText:(id)sender
{
[titleText setStringValue: [NSString stringWithFormat:#"%#", userEditableText]];
}
- (void) textDidEndEditing:(NSNotification *)notification
{
userEditableText = [textField stringValue];
NSString* fullText = [NSString stringWithFormat:#"%# (%#)", userEditableText, nonUserEditableText];
NSRange range1;
range1.location = 0;
range1.length = [userEditableText length] - ([nonUserEditableText length] + 2);
NSRange range2;
range2.location = range1.length;
range2.length = ([[nonUserEditableText length] length] + 2);
NSRange range3;
range3.location = 0;
range3.length = [fullText length];
NSFont *font = [NSFont fontWithName:#"Arial" size:14.0];
NSMutableDictionary* stringAttributes = [[NSMutableDictionary alloc] init];
NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:fullText attributes:stringAttributes];
NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[paragraphStyle setLineBreakMode:NSLineBreakByTruncatingMiddle];
[attrString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:range1];
[attrString addAttribute:NSFontAttributeName value:font range:range2];
[textField setAttributedStringValue:attrString];
}
Not sure exactly what I did, but I changed around a bunch of code in several classes and now everything is working properly. Wish I knew what I did...
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)
I'm using this category (is that right?) http://www.nightproductions.net/references/dsclickableurltextfield_reference.html#setAttributedStringValue
to implement clickable textfields. I've imported the header file in my controller class and set it's attributed string value like this
NSAttributedString* str = [[NSAttributedString alloc] initWithString:#"http://www.yahoo.com"];
[url setAttributedStringValue:(NSAttributedString *)str];
[str release];
The text field is not selectable and not editable.
The text field value is set but it's not clickable and it's not a link.
Thanks in advance.
I have found another easy way to show links in NSTextField. You can use HTML. Here is a short example:
-(NSAttributedString *)stringFromHTML:(NSString *)html withFont:(NSFont *)font
{
if (!font) font = [NSFont systemFontOfSize:0.0]; // Default font
html = [NSString stringWithFormat:#"<span style=\"font-family:'%#'; font-size:%dpx;\">%#</span>", [font fontName], (int)[font pointSize], html];
NSData *data = [html dataUsingEncoding:NSUTF8StringEncoding];
NSAttributedString* string = [[NSAttributedString alloc] initWithHTML:data documentAttributes:nil];
return string;
}
Now you can call the method for text field:
// #property IBOutlet NSTextField *tf;
[tf setAllowsEditingTextAttributes: YES];
[tf setSelectable:YES];
NSString *credits = #"Visit our webpage";
[tf setAttributedStringValue:[self stringFromHTML:credits withFont:[tf font]]];