text editing in text view xcode - ios

I have a text view in which text is displayed like this:
how are you?
Fine
Now if i set font for text view, then the same font is displayed for the two lines(ques and answer), however i want question to be displayed in one font and answer in some other font. How can i do this?
I set font like this:
textView = [[UITextView alloc]initWithFrame:CGRectMake(10, 80, 300, 440)];
textView.layer.borderColor = [UIColor blackColor].CGColor;
[textView setFont:[UIFont fontWithName:#"TimesNewRomanPS-ItalicMT" size:14]];
textView.layer.borderWidth = 1.0;
textView.autoresizesSubviews = YES;
textView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.view addSubview:textView];
Thanks in advance!!

From the UITextView class reference:
In iOS 6 and later, this class supports multiple text styles through
use of the attributedText property. (Styled text is not supported in
earlier versions of iOS.) Setting a value for this property causes the
text view to use the style information provided in the attributed
string. You can still use the font, textColor, and textAlignment
properties to set style attributes, but those properties apply to all
of the text in the text view.
This class does not support multiple styles for text. The font, color,
and text alignment attributes you specify always apply to the entire
contents of the text view. To display more complex styling in your
application, you need to use a UIWebView object and render your
content using HTML.
So you cannot have two on the same page for iOS 5 or less because it is not supported. Just use a webview and an HTML file. for iOS6 maybe you can try using attributedText property of UITextView. This is available under iOS 6. Never tried it though.
Or have 2 different UITextView's (its ugly but thats what it is).

I'm guessing you wanted to create a chatroom like app?
if so, I recommend make it a UITableView. And then make different Cells to match different styles.

You can use attributed strings to achieve this, for example:
NSMutableAttributedString *para1 = [[NSMutableAttributedString alloc] initWithString:#"How are you?"];
NSMutableAttributedString *para2 = [[NSMutableAttributedString alloc] initWithString:#"\nFine"];
[para2 setAttributes:#{ NSForegroundColorAttributeName : [UIColor blueColor]} range:NSMakeRange(0, para2.length)];
[para1 insertAttributedString:para2 atIndex:para1.length];
self.textLabel.attributedText = para1;
Or with a single attributed string:
NSMutableAttributedString *para1 = [[NSMutableAttributedString alloc] initWithString:#"How are you?\nFine"];
// Get the range of the last line in the string
__block NSRange range;
[para1.mutableString enumerateLinesUsingBlock:^(NSString *line, BOOL *stop) {
range = [para1.mutableString rangeOfString:line];
}];
[para1 setAttributes:#{ NSForegroundColorAttributeName : [UIColor blueColor] } range:range];
self.textLabel.attributedText = para1;
Both examples result in:

Related

IOS Objective C UILabel font size is keeping its storyboard setting

I am using objectiveC for an old project and I am setting the label font size programmatically like this :
UIFont *font = [self fontToFitHeight:NSLocalizedString(#"#61_NEW_FINAL", nil) font:self.rulesLabel.font size:self.rulesLabel.frame.size.height];
[self.rulesLabel setFont:font];
NSLog(#"after call : fontszie is : %lf",self.rulesLabel.font.pointSize);
I can include the helper function if needed, but it returns me what I want, which is a font with fontsize around 5, which i see printed.
But when running that my font size is definitely not 5, but instead whatever value I have in the Storyboard settings (in my case 16). Above code is called inside viewDidLoad.
What am I missing?
NSAttributedString can include one or more fonts, perhaps this is your issue. If you have set the text of the label to be an attributed string that contains a font or a color, changing the base font or color of the label will not make a difference. In order for it to work as expected, you can either remove any font formatting of your attributed string (that I assume that you set through IB) or recreate the string in code and add the proper font to it, like so:
NSString *text = NSLocalizedString(#"#61_NEW_FINAL", #"Don't leave this out");
UIFont *font = [self fontToFitHeight:text font:self.rulesLabel.font size:self.rulesLabel.frame.size.height];
NSMutableAttributedString *labelAttributes = [[NSMutableAttributedString alloc] initWithString:text];
[labelAttributes addAttribute:NSFontAttributeName
value:font
range:NSMakeRange(0, labelAttributes.length)];
At this point, changing the font of the label will make absolutely no difference to its apperance, since the entire text has a predefined font already.

Change color of one word in attributed textview (objective-c)

I have a textview with an Attributed text. I am trying to change the color of the first 14 letters ("Privacy Policy") of the attributed text to a stored value, "appTintColor". This app tint color is stored in the p list and has a different color for each app target.
How do I change the first 5 letters of the textView's attributed text to this variable "appTintColor"? I know I can change the color to an RGB/HEX color easily using the xCode interface... But I want to change this color to the variable "appTintColor" which is dynamic based on the app target.
Do I add an outlet to the textfield, subscript the first 14 characters, and set it to appTintColor? That is the logic I have but I can't seem to get it in code.
You need an NSMutableAttributedString - try the following code:
UIColor *color = [UIColor greenColor];
NSString *privacyPolicyFullStr = #"Privacy policy\n blah stuff things blah cat bat mongoose platypus";
NSMutableAttributedString *mutAttrStr = [[NSMutableAttributedString alloc]initWithString:privacyPolicyFullStr attributes:nil];
NSString *privacyPolicyShortStr = #"Privacy Policy"; //just to avoid using a magic number
NSDictionary *attributes = #{NSForegroundColorAttributeName:color};
[mutAttrStr setAttributes:attributes range:NSMakeRange(0, privacyPolicyShortStr.length)];
self.textView.attributedText = mutAttrStr;

Update the UITextView content dynamically in a specific range

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.

UILabel appearance font and attributed string font

In my app I have a global custom font applied to all labels like so:
UIFont *font = [UIFont fontWithName:kMyFontName size:15.0];
[[UILabel appearance] setFont:font];
This works fine. However, in some cases I want to be able to specify a different font for a specific region of a UILabel string.
So I have something like this:
NSString *string = #"Foo Bar Baz";
UIFont *boldFont = [UIFont fontWithName:kMyBoldFontName size:15.0];
NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:string];
[attrString setAttributes:#{ NSFontAttributeName: boldFont } range:NSMakeRange(0, 3)];
self.myLabel.attributedText = attrString;
However this doesn't seem to work. I expect the "Foo" to be bold, but the entire string just has the default font. It's as if the bold font is not applied at all and is being overwritten by the font set on the UILabel appearance proxy.
When I remove the UILabel appearance line then it works fine (I can see part of the string in bold). Basically I want to have my custom font applied to the label but a separate font applied to a different region of the string. Normally this works fine with attributed strings but for some reason setting the UILabel appearance font disables this functionality (or so it seems).
Expected results: "Foo Bar Baz"
Actual results: "Foo Bar Baz"
If I remove the [[UILabel appearance] setFont:] line then it works:
"Foo Bar Baz"
(but the custom font is not set on the rest of the string).
So my question is: Is there a way to specify a single font to use as the default app-wide but still be able to partially override that using attributed strings?
Also if someone can explain to me why this is not working I'd appreciate it.
Set font and textColor to nil just before setting attributed string.
You can't mix and match attributed text and plain text; that's why removing the setFont method works - because when you use it, it assumes a plaintext UILabel.
NSString *string = #"Foo Bar Baz";
UIFont *boldFont = [UIFont fontWithName:kMyBoldFontName size:15.0];
// Define your regular font
UIFont *regularFont = [UIFont fontWithName:kMyFontName size:15.0];
NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:string];
// And before you set the bold range, set your attributed string (the whole range!) to the new attributed font name
[attrString setAttributes:#{ NSFontAttributeName: regularFont } range:NSMakeRange(0, string.length - 1)];
[attrString setAttributes:#{ NSFontAttributeName: boldFont } range:NSMakeRange(0, 3)];
self.myLabel.attributedText = attrString;
There are two important parts:
UIAppearance applies at the moment of adding UI element to window
labelInstance.font = ... resets all font attributes of currently set attributed string
So if you want to keep UIAppearance customisation you have to set your custom attributed string after your label get added to window.
Reference article about how does UIAppearance work: Peter Steinberger's cool article

how to set a UITextView's text to be bolded and not clickable

I have the following HTML in a UITextView and would like to render it into a UITextView
is my body for the note
food item - more item stuff;`
Let me add: it's currently showing as blue and underlined and not clickable. I would like to make it bolded and not clickable. I have read the docs regarding linkTextAttributes but, not having used this, it is a bit beyond me and I don't really see any easy way to manipulate this. How would I just render the above link bolded and black (not blue) and maintain the non-clickable nature?
UPDATE (solution using UITextView's linkTextAttributes)
self.testTextView.editable = NO;
self.testTextView.selectable = YES;
self.testTextView.userInteractionEnabled = NO; // workaround to disable link - CAUTION: it also disables scrolling of UITextView content
self.testTextView.dataDetectorTypes = UIDataDetectorTypeLink;
self.testTextView.linkTextAttributes = #{NSFontAttributeName : [UIFont boldSystemFontOfSize:14.0f], // NOT WORKING !?
NSForegroundColorAttributeName : [UIColor redColor]};
...
self.testTextView.text = #"Lorem ipsum http://www.apple.com Lorem ipsum";
As you can see in comments, I wasn't able to set new font to linkTextAttributes, though the colour attribute was working as expected.
If you can get away with colour attribute or some other text attribute to style your URLs and you don't have to worry about disabled UITextView scrolling, then this may be your solution.
PREVIOUS (alternative solution)
If you're using Storyboard/xib then make sure you've deselected Detection -> Links for your UITextView. You can make your link bold by setting its container font to some bold typeface. If you want to support different text/font styles in one string object then you should really look for NSAttributedString or NSMutableAttributedString.
See: https://developer.apple.com/library/ios/documentation/cocoa/reference/foundation/classes/NSAttributedString_Class/Reference/Reference.html.
Example:
UIFont *linkFont = [UIFont fontWithName:#"SomeBoldTypeface" size:12];
NSString *link = #"food item - more item stuff";
NSMutableAttributedString *someString = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:#"is my body for the note %#; let me ad", link]];
[someString addAttribute:NSFontAttributeName value:linkFont range:NSMakeRange(24, link.length)];
UITextView *textView = [[UITextView alloc] init];
textView.attributedText = someString;
...

Resources