Attributes not showing up in UITextView (iOS 8/Xcode 6.4) - ios

I'm trying to load an RTF file and display it's contents inside a UITextView using the following code:
- (void)viewDidLoad {
[super viewDidLoad];
self.textView.allowsEditingTextAttributes = YES;
NSURL *rtfpath = [[NSBundle mainBundle] URLForResource:#"rtfFile" withExtension:#"rtf"];
NSAttributedString *rtfText = [[NSAttributedString alloc] initWithFileURL:rtfpath options:#{NSDocumentTypeDocumentAttribute:NSRTFTextDocumentType} documentAttributes:nil error:nil];
self.textView.attributedText = rtfText;
}
The text loads fine, but none of the attributes (size, color, bold, font) show up and it just displays the text using a basic system font. This is a relatively large file that will be edited frequently so is there any I way I can display attributes (for example I want the section headings to be bold) without manually hard coding every line of text?
Also I've tried manually pasting the contents of my file into the attributed text field of the UITextView in the storyboard. It actually displays everything with attributes in the storyboard, but when I run the code all my attributes disappear again.

Related

Why is NSTextAttachment image not displayed?

I'm trying to add an image to an attributed string:
NSTextAttachment *locationIcon = [[NSTextAttachment alloc] init];
locationIcon.image = [UIImage imageNamed:#"location-pin-icon"];
NSAttributedString *iconString = [NSAttributedString attributedStringWithAttachment:locationIcon];
[string appendAttributedString:iconString];
NSAttributedString *locationNameString = [[NSAttributedString alloc] initWithString:#"some text" attributes:linkAttributes];
[string appendAttributedString:locationNameString];
Then I simply set myLabel.text = string; (where myLabel is a TTTAttributedLabel)
location-pin-icon is a valid image (I've checked it in debugging too). However, the location pin icon is not being displayed in the label (the following "some text" is displayed perfectly though, and linkAttributes is just a collection of system font with a custom blue color). I've also tried manually setting bounds to the text attachment, or leaving a space before the text, but nothing seems to work.
What am I doing wrong?
It was apparently due to implementation of TTTAttributedLabel. The library seems broken. When I've switched from it, the attachment started displaying correctly.

How can I add a custom view to an attributed string or text view?

I'm trying to get a custom view in an attributed string to be displayed on a textView. I am able to add an image with an NSTextAttachment, but it isn't what I want. I have a custom view that supports Gif's and Animated PNGs that I'd like to display between text.
Example:
text text text [customView] text [customView] text. <- In text view, preferably in attributed string
I would love some guidance as to where I should search specifically. So far I've seen related issues...
Subclass NSTextAttachment: How to subclass NSTextAttachment?
Use NSTextAttachmentContainer..?
NSTextAttachmentCell - Only OSX
Do manipulation in the text view
First, use NSAttributedString or NSMutableAttributedString to show your RichText in subviews (such as UITextView/UILabel)
Then, use NSTextAttachment to replace your image-script in text.
NSString *egText = #"hello [this_is_an_img_script]";
NSMutableAttributedString * destStr = [[NSMutableAttributedString alloc] initWithString:egText];
NSTextAttachment *attachment = [[NSTextAttachment alloc] initWithData:nil ofType:nil];
attachment.image = [UIImage imageNamed:[this_is_an_img_script]];
NSAttributedString *textAttachmentString = [NSAttributedString attributedStringWithAttachment:attachment]; //make your image to an attributedString
[destStr replaceCharactersInRange:range withAttributedString:textAttachmentString];
at last: [YourLabel(or YourTextView) setAttributedString:destStr];
BTW: if you use the YYkit for the RichText, you cannot use the YYAttachMentString to replace NSAttachMentString, these are different things, the UITextView(UILabel) cannot load the YYAttachMentString.
I'm looking for some way to show my gifs with the UITextView (because YYKit cannot load and preview netimage with a url, YYKit always show empty which should be a netImage, cripes!)

Adding images to a UITextView

It appears that this has been asked and not answered before, but the question is ancient and there have been many Xcode / iOS updates since then, so I am going to give this a shot.
I have a simple view controller laid out. There is a single View that contains a read-only Text View with some instructions on how to use the app. I would like to intersperse some images in the scrolling text view to refer to the buttons and other elements that I am referring to in the instructions.
Here is the view:
So for instance, when the instructions refer to the green start button, I would like to insert an image of that button inline with the rest of the text.
I am using Xcode 5.1.1 and of course storyboards. Thanks in advance for any suggestions.
You can use the NSAttributedString with NSTextAttachment to attach an image to the text
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:#"press to start"];
NSTextAttachment *imageAttachment = [NSTextAttachment new];
imageAttachment.image = [UIImage imageNamed:#"AnyImage.png"];
NSAttributedString *stringWithImage = [NSAttributedString attributedStringWithAttachment:imageAttachment];
[attributedString replaceCharactersInRange:NSMakeRange(5, 1) withAttributedString:stringWithImage];
self.textView.attributedText = attributedString;

Scrolling Performance issue with UItextView with large NSAttributedString

I am working on text editor for an app. I am using UITextView
See the sample code to load text view.
// Read text from file (around 300k - 400k words)
NSError *error = nil;
NSString *contentOfFile = [[NSString alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"17254" ofType:#"txt"]
encoding:NSUTF8StringEncoding
error:&error];
// Attributes for text
UIFont *font = [UIFont fontWithName:#"Baskerville" size:36.0f];
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.alignment = NSTextAlignmentJustified;
NSDictionary *attributes = [[NSDictionary alloc] initWithObjectsAndKeys:font, NSFontAttributeName,
[UIColor blackColor], NSForegroundColorAttributeName,
paragraphStyle, NSParagraphStyleAttributeName, nil];
// Create attributed string
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:contentOfFile attributes:attributes];
// Assign to text view
self.textView.attributedText = attributedString;
The size of text is around 400k words.
I am facing the following issues.
Scrolling of text becomes too slow as i scroll down and some time app crashes due to memory issue. What i think iOS is saving the rendered text image in its memory when textview is scrolled down, but when i scroll up to top it releases the memory.
If i tap "Select All" it takes too much time to select the text and after text selection the scrolling becomes poor and some times app crashes due to memory issue because its memory increases. I think iOS generates the image of complete text(as if its visible to user) in its memory and then selects the complete text and retain its image until selection is finished. After selection is finished memory retained by app drops.
The other way of displaying the large text is to use the multiple textviews and assign the text to visible textview only like UITableView, but this will increase the complexity as i have to recount the number of textviews required on each textChanged delegate call of layoutManager of UItextView.
Any body has idea how to display large attributed text in UITextView with better performance.
Any guess how iPages app is working, because it display text when the area is in visible range.
You should not load entire text directly. You should load the text which is twice as much as the textview capacity.
Now track the scroll event and modify the string dynamically.

Localizing attributed UITextView from storyboard

I am using the storyboard and have a view where I have subclassed some UITextViews.
My problem is that I am using ibtool --generate-strings-file to extract strings from the storyboard for localization and afterwards use ibtool -write on another storyboard file to apply the translated strings.
When I use ibtool any UITextViews that have attributed text is ignored by the ibtool --generate-strings-file command and omitted from the resulting strings file.
Is it possible to extract attributed text from a storyboard for localization?
on Xcode 6.1, the best way is to copy the attributed text of a text view into a “BASE” RTF text ( using TextEdit for example or directly from XCode > New File > ressources > RTF ).
Going through the TextEdit way, you need to import your text into your project. Obviously, if you have done it through Xcode, nothing to import.
then just you use the utilies panel to find the “localize..." button which will do it's deed for you.
to import the correct version just do ( in viewWillAppear for ex. ),
NSURL *url = [[NSBundle mainBundle] URLForResource:[fileName stringByDeletingPathExtension] withExtension:[fileName pathExtension]];
NSError *error;
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithFileURL:url
options:#{NSDocumentTypeDocumentAttribute:NSRTFTextDocumentType}
documentAttributes:nil
error:&error];
[_originalMessage setAttributedText:attributedString];
Update for Swift 4:
var attrString: NSAttributedString?
let fileUrl: URL = Bundle.main.url(forResource: "mytextfile", withExtension: ".rtf")!
do {
attrString = try NSAttributedString(url: fileUrl, options: [.documentType:NSAttributedString.DocumentType.rtf], documentAttributes: nil)
} catch {
// Somebody do something!!
}
I ended up concluding that it couldn't be done using ibtool in the present version.
Instead I let the Textview be a plain text view and, using my subclass, parsed its text property so I could make a NSMutableAttributedString and set the needed properties.
That enabled me to use ibtool to extract the strings and still have an attributed textview.
It wouldn't make sense to localize attributed text from the storyboard as you would need to know where to apply the attributes after the translation. The word order might have changed and where you would have specified some blue bold text for instance might no longer make sense.
You can of course still do it via code where you can split up your string in multiple ones and localize them individually. Then you can specify setAttributes:range: so that you know that the right attributes will always be applied on the right range of the string.
Here's a workaround which I find quite useful: just create a ViewController with the translated TextView. In details (here I just translate the attributed text into english):
1) Crete a new Controller with "New File" -> "UIViewController with Xib". Name it "AttributedTranslated" and fill it with just a TextView with the attributed text being translated, using Interface Builder.
2) In your main controller .m file, write down the following method:
- (BOOL)isEng {
return [[[NSLocale preferredLanguages] objectAtIndex:0] isEqualToString:#"en"];
}
3) Define an "AttributedTranslated" object and a View in your .h file
IBOutlet UIView *attrView;
AttributedTranslated *attr;
4) On the xib file (or storyboard) of your main controller, create a View containing just the attributed textView (in the original language) and link it to "attrView".
5) On you viewDidLoad do something like the following:
if ([self isEng]) {
desc = [[Description alloc] init];
[attrView addSubview:attr.view];
}
Maybe it's not the best way to do it, but it does allow one to translate the attributed text in Interface Builder, easily!

Resources