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!).
Related
I set the list of fontfamilies to a NSPopupButton. I don't know How to set the selected font preview to the NSTextView
have tried like this
NSString *fontstyle = [popup_button titleOfSelectedItem];
NSFont *fontst = [NSFontManager:nil willIncludeFont:fontstyle];
[text_view setFont:fontstyle];
Finally I got it...
NSString *fontstyle = [popup_button titleOfSelectedItem];
NSString *fontsize = [pop_size titleOfSelectedItem];
CGFloat fntsize = [fontsize floatValue];
NSFont *regular = [NSFont fontWithName:fontstyle size:fntsize];
[text_view setFont:regular];
I am new to cocoa prgramming, and I am copying text using the code:
NSRange range = [textView selectedRange];
NSData* rtfData = [textView RTFFromRange: range];
NSAttributedString* aStr = [[NSAttributedString alloc]initWithRTF:rtfData documentAttributes:NULL];
NSString* str = [aStr string];
str contains the selected text, but how can I paste that text in a NSTextView whenever I click in a textview?
you have to set delegate of NSTextView to self, then you need to implement delegate method on which you want to perform this action.
And then you can use setString method of NSText(Super class of NSTextView) to set the text.
Edit - (Try with this first, if it set the text to textview)
NSRange range = [textView selectedRange];
NSData* rtfData = [textView RTFFromRange: range];
NSAttributedString* aStr = [[NSAttributedString alloc]initWithRTF:rtfData documentAttributes:NULL];
NSString* str = [aStr string];
[[textView setString:str];
for NSTextView you need :
[[textView textStorage] setAttributedString:[[NSAttributedString alloc] initWithString:str]];
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 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.
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]]];