Update the UITextView content dynamically in a specific range - ios

I need to update the words dynamically in UiTextView content while TTS is playing without refresh the page.
Problem: While tts playing for the each word delegate(willSpeakRangeOfSpeechString:(NSRange)characterRange utterance:(AVSpeechUtterance *)utterance) is calling.
so at that time i am updating the text color using NSMutableAttributedString.
In this process the content in the textview is unstable because for each word page is refreshing.
so i need to update the text in textview without refreshing the page.
I wrote the code like this.
NSMutableAttributedString *attrStr = [[NSMutableAttributedString
alloc] initWithString:_theContent ];
[attrStr addAttribute:NSFontAttributeName value:[UIFont
systemFontOfSize:self.fontSize] range:[self wholeArticleRange]];
[attrStr addAttribute:NSForegroundColorAttributeName value:[UIColor
redColor] range:theRange];
textview.attributedText = attrStr;
--In android we used spannable class to do this way. Is there any class in IOS like this?
Kindly give us solution ASAP
Thanks in advance.

You can access the text view's textStorage property, of type NSTextStorage, which is a subclass of NSMutableString. From there you can use any NSMutableString operation, including setting attributes on the various ranges, without sending an entirely new string to the text view (which will make it flicker).
Do not forget to call beginEditing and endEditing to group edits together if you have to make multiple calls, in order to improve performance.

I wrote the code like this. I am new to the IOS so if i am wrong kindly correct me.
(NSMutableDictionary *)attDict {
if (!_attDict) {
_attDict = [NSMutableDictionary dictionary];
UIFont *font = [UIFont systemFontOfSize:self.fontSize];
// UIFont *font = [UIFont fontWithName:#"TimesNewRomanPSMT" size:self.fontSize];
[_attDict setObject:font forKey:NSFontAttributeName];
[_attDict setObject:[UIColor blueColor] forKey:NSForegroundColorAttributeName];
}
return _attDict; }
[[displayingArticleView contentView].textStorage
setAttributes:self.attDict range:theRange] ;
Thanks

If you just want to replace any text in your UITextField with some other on the fly, You can use the string replacement method, Like
[textField.text stringByReplacingOccurrencesOfString:#"your string" withString:#"string to be replaced"];
This will Replace all occurrences of the target(string to be replaced) string with replacement.

Related

NSBackgroundColorAttributeName in textView doesn't respect range if highlighted word is first of a line

I'm implementing a "search in chat" feature and I want the searched word to be highlighted in messages. The problem, as described in title, is that if the word is the first of a line (long messages are clearly multi-line), the entire line is highlighted instead of the single word.
While debugging, I also tried to apply an underline instead of backgroundcolor, and the underline is correct. I can't figure out where's the problem.
My app's chat is based on JSQMessagesViewController so I was thinking that the problem could be there.
[attributedString addAttribute:NSBackgroundColorAttributeName
value:backColor
range:wordRange];
[attributedString addAttribute:NSUnderlineStyleAttributeName
value:#(NSUnderlineStyleSingle)
range:wordRange];
cell.textView.attributedText = attributedString;
I don't post the code that calculates range because range is correct; in fact, if I look at attributedString's preview in debug (where I assign it to cell.textView.attributedText) I can see that only the word is highlighted, and not all the string.
Here's an example:
Seems like a bug in the system framework, so probably best bet would be to add one more line of code, setting background color back to "unchanged", directly after the last character where background should be changed.
Good luck!
After taking a look at official documentation, I found that there are three methods which do similar action.
setAttributes:range:
addAttribute:value:range:
addAttributes:range:
So, possibly, other method, for example setAttributes:range:, may fix you problem.
[attributedString setAttributes:#{NSBackgroundColorAttributeName : backColor}
range:wordRange];
cell.textView.attributedText = attributedString;
Furthermore, there is a similar question on stackoverflow. Maybe this answer will help you.
NSDictionary *stringAttributes = [NSDictionary dictionaryWithObject:(id)backColor.CGColor
forKey:(id)kCTBackgroundColorAttributeName];
[attributedString addAttributes:stringAttributes
range:wordRange];
cell.textView.attributedText = attributedString;
Update #1
Just found Attributed String Programming Guide.
It says,
All of the methods for changing a mutable attributed string properly update the mapping between characters and attributes, but after a change some inconsistencies can develop.
Perhaps, the above reason causes your problem...
I'm not sure can it help or no, but there is example:
NSMutableAttributedString *string; // assume string exists
NSRange selectedRange; // assume this is set
NSURL *linkURL = [NSURL URLWithString:#"http://www.apple.com/"];
[string beginEditing]; // ★★★ Apple uses beginEditing ★★★
[string addAttribute:NSLinkAttributeName
value:linkURL
range:selectedRange];
[string addAttribute:NSForegroundColorAttributeName
value:[NSColor blueColor]
range:selectedRange];
[string addAttribute:NSUnderlineStyleAttributeName
value:[NSNumber numberWithInt:NSSingleUnderlineStyle]
range:selectedRange];
[string endEditing]; // ★★★ and endEditing ★★★

How to increase font size of whole content in NSMutableAttributedString

I want to increase font size of text that comes from server and text is in html format.I used NSAttributedString for showing text.
NSRange rangeOfTitle = NSMakeRange(0,[catDescLabel length]);
NSMutableAttributedString *string1 =
[[NSMutableAttributedString alloc] initWithString:catDescLabel];
[string1 addAttribute:NSFontAttributeName
value:[UIFont systemFontOfSize:20.0]
range:rangeOfTitle];
I am attaching screenshot that how it look and i am also attaching screenshot how it look in Android.I want to increase font size of whole content. how can i do this ?
Could anyone give me any Idea or help. Much appreciated
Android Screenshot
iOS Screenshot
Thanks ,
addAttribute ... but it seems it is not available for NSAttributedString
But it is available for NSMutableAttributedString.
That's how it is with all Cocoa immutable/mutable class pairs. The immutable member of the pair is, uh, immutable — that means you can't change anything about it. If you want to change something about it, convert it to the mutable member of the pair.
NSMutableAttributedString *attributedString2 =
[[NSMutableAttributedString alloc] initWithAttributedString: attributedString1];
You would do something like this…
NSMutableAttributedString *string1 =
[[NSMutableAttributedString alloc] initWithString:#"Your string"];
[string1 addAttribute:NSFontAttributeName
value:[UIFont systemFontOfSize:20.0]
range:NSMakeRange(5, 6)];
Update :
[self.label setAttributedTitle:string1];
This will set the last two words in 20-point text; the rest of the string will use the default value (which I believe is 12 points). The thing that might be confusing about setting the text size is that you have to set the typeface and the size at the same time—each UIFont object encapsulates both of those properties.
And reference link for you
https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/AttributedStrings/Tasks/CreatingAttributedStrings.html

Color the specific range of word by NSMutableAttributedString in a UITextView cause UITextView scroll to the top?

Here is a UITextView,on which i put long chapter(i wanna to make it just like a book.),when i press a word more than 2 seconds,(i set a long gesture here),then the word will be highlight(the following code can successfully hightlight the word,but also trigger some side effect which i need to eliminate),then here comes the story:
code is like follows:
NSMutableAttributedString *attrStr = [self.contentTextView.attributedText mutableCopy];
[attrStr addAttribute:NSBackgroundColorAttributeName value:[UIColor grayColor] range: _wordToSearchRange ];
self.contentTextView.attributedText = attrStr;
So far, i debugged the code, and finally targetted on this line:
self.contentTextView.attributedText = attrStr;
which lead my textView scroll to the top(not stay in the current word location),it is reasonable since this operation is similar to refresh the textView and set the totally new content for it. But is there any other method to set the specific word range in a textView which would not cause this ?
Any help would be great! Thx a lot!
Since you are editing existing text, you shouldn't replace all of it.
You need to create attributes dictionary and add it to the attributed text:
NSMutableDictionary* attributes; //set the wanted attributes
NSRange range; //set the right range
[_contentTextView.textStorage beginEditing];
[_contentTextView.textStorage addAttributes:attributes range:range];
[_contentTextView.textStorage endEditing];

Format text in UITextView

I am making an "About Page" for my application, and I have to paste pretty huge amount of text on that page (text will not be editable).
I am using a UITextView for this purpose. However, I need some words to be in bold (like headings). But I am not able to achieve it. The UITextView removes all my formatting.
I have no code to show here because I am pasting all my text in the IB only.
Is there any workaround?? For example.. I want the heading in bold..
"About ABC Corporation
gkskgsagdfgfskgfjkgfgljdgsfjgdsjfgdjlsgflgdslgfljdsgfljgdsjlgfljdsgfljdgslfgls.
jdfjkhdsjlfhdlsfhkldshfkldshflkdhlkfhdklsfhlksdhflkdshflkhdsflkhsdklfhlksdhflkshf
fjhdshfkldshfkldhsfklhdsklfhlkdshfklhdsklfhdklsfhkdshfklhdsklfhklsdfhkldshfkhdsklf
fhjdgfkdgsjkfgjkdsgfjkdsgjfgjdkgfjgsjdfgjkdsgfjkgsdjkfgjsdgfjgsdjkfgjksdgfjkgskjfgs"
First keep text property of textView as 'Attributed', after that just select the text and change it's style and font as you want.
P.S. - All you have to do this in Attribute inspector panel of IB.
EDIT:
For more, visit this link .
Also, this is very good mainly when the textField have a text that will not change, e.g. - like About info. And when this text is inserted in IB directly instead of assigning text programmaticaly.
You can use NSAttributedString, Set Text Font, Foreground And Background Colors, StrikeThrough And Shadow etc..
Attributed strings make an association between characters and their attributes. Like NSString objects, there are two variations, NSAttributedString and NSMutableAttributedString. Although previous versions of iOS supported attributed strings, it wasn’t until iOS 6 that controls such as buttons, labels, textfields and textviews defined a property to manage attributes. Attributes are applied to a range of characters, so you can for example, set a strikethrough attribute for just a portion of a string. It’s also important to note that the default font for attributed string objects is Helvetica 12-point. Keep this in mind if you set the font attribute for a range other than the complete string. The following attributes can be set with attributed strings:
NSString *const NSFontAttributeName;
NSString *const NSParagraphStyleAttributeName;
NSString *const NSForegroundColorAttributeName;
NSString *const NSBackgroundColorAttributeName;
NSString *const NSLigatureAttributeName;
NSString *const NSKernAttributeName;
NSString *const NSStrikethroughStyleAttributeName;
NSString *const NSUnderlineStyleAttributeName;
NSString *const NSStrokeColorAttributeName;
NSString *const NSStrokeWidthAttributeName;
NSString *const NSShadowAttributeName;
NSString *const NSVerticalGlyphFormAttributeName;
// Create attributed string
NSString *str = #"example for underline \nexample for font \nexample for bold \nexample for italics";
NSMutableAttributedString *attributedString =
[[NSMutableAttributedString alloc] initWithString:str];
// Add attribute NSUnderlineStyleAttributeName
[attributedString addAttribute:NSUnderlineStyleAttributeName
value:[NSNumber numberWithInt:NSUnderlineStyleSingle]
range:NSMakeRange(12, 9)];
[attributedString addAttribute:NSUnderlineStyleAttributeName
value:[NSNumber numberWithInt:NSUnderlineStyleSingle]
range:NSMakeRange(12, 9)];
// Set background color for entire range
[attributedString addAttribute:NSBackgroundColorAttributeName
value:[UIColor yellowColor]
range:NSMakeRange(0, [attributedString length])];
// Create NSMutableParagraphStyle object
NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init];
paragraph.alignment = NSTextAlignmentCenter;
// Add attribute NSParagraphStyleAttributeName
[attributedString addAttribute:NSParagraphStyleAttributeName
value:paragraph
range:NSMakeRange(0, [attributedString length])];
// Set font, notice the range is for the whole string
UIFont *font = [UIFont fontWithName:#"Helvetica" size:18];
[attributedString addAttribute:NSFontAttributeName
value:font
range:NSMakeRange(35, 4)];
// Set font, notice the range is for the whole string
UIFont *fontBold = [UIFont fontWithName:#"Helvetica-Bold" size:18];
[attributedString addAttribute:NSFontAttributeName
value:fontBold
range:NSMakeRange(53, 4)];
// Set font, notice the range is for the whole string
UIFont *fontItalics = [UIFont fontWithName:#"Helvetica-Oblique" size:18];
[attributedString addAttribute:NSFontAttributeName
value:fontItalics
range:NSMakeRange(71, 7)];
// Set label text to attributed string
[self.mytextView setAttributedText:attributedString];
Check out attributedText property of UITextView
https://developer.apple.com/library/ios/documentation/uikit/reference/uitextview_class/Reference/UITextView.html#//apple_ref/occ/instp/UITextView/attributedText
And this how you can make part of your string bold
Any way to bold part of a NSString?
You can use NSMutableAttributedString to support multi attribute property to your string.Note:- NSMutableAttributedString is available in iOS 6.0+. Edit:- Check this:- How to create a UILabel or UITextView with bold and normal text in it?
iOS SDK has included text kit in it.
iOS 7 offers the ability to enhance the legibility of text by increasing font weight, as well as an option to set the preferred font size for apps that support dynamic text. Users will expect apps written for iOS7 to honor these settings, so ignore them at your own risk!
In order to make use of dynamic type you need to specify fonts using styles rather than explicitly stating the font name and size. With iOS 7 a new method has been added to UIFont, preferredFontForTextStyle that creates a font for the given style using the user’s font preferences.
Here is a great tutorial in great website Ray wenderlich text kit tutorial
If you have time, watch WWDC 2013 video session 201
UITextView is a plain text and you can't apply different styles(font,color) for different words.
I suggest you to use UIWebView. It is html, so it can be styled.

Trouble with formatting of OHAttributedLabel when parsing markup

In a property list I have a string like this:
<string>A |picture| is worth *1000\* words.</string>
Obviously "picture" should be italic and "1000" should be bold. I'm trying to display the text using OHAttributedLabel:
NSString *theString = [pListData objectForKey:#"theString"];
NSMutableAttributedString* attrStr = [OHASBasicMarkupParser attributedStringByProcessingMarkupInString:theString];
self.myLabel.attributedText = attrStr; //self.myLabel is a UILabel
And here is what I get:
Why are the attributed words displayed in a smaller font, and how do I fix this?
I have deal with something like this before. So, this will help you. Also i have tested it for you and works fine :)
NSString *string = #"A |picture| is worth *1000* words.";
// Create an NSMutableAttributedString in order to be able to use the NSAttributedString+Attributes.h category
NSMutableAttributedString *attributedString = [NSMutableAttributedString attributedStringWithString:string];
// If using custom fonts, import all styles in the app and update the plist file
[attributedString setFont:[UIFont fontWithName:#"Helvetica" size:20.0]];
// Parse the markup and set the attributedText of the UILabel instance (no need to use the OHAttributedLabel subclass)
attributedString = [OHASBasicMarkupParser attributedStringByProcessingMarkupInAttributedString:attributedString];
label.attributedText = attributedString;
EDIT: The problem comes when using -setFont: after the calling -attributedStringByProcessingMarkupInAttributedString, since that would reset all the work done during parsing.

Resources