Limit NSAttributedString number of lines - ios

is there a way to limit number of lines in paragraph in NSAttributedString?
Im appending two strings in NSAttributedString and i want them to be maximum 3 lines, the first string will be 1-2 lines , truncated if needed. and the second string should be always on the last line
Something like:
this is my first string
if its too long i't will get trun...
But this is my second string
what i did is:
// First string
NSAttributedString *first = [[NSAttributedString alloc] initWithString:#"this is my first string if its too long i't will get trunticated"
attributes:#{NSForegroundColorAttributeName:[UIColor redColor],
NSFontAttributeName:[UIFont fontWithName:#"HelveticaNeue-Light" size:17.0]];
[str appendAttributedString:first];
// New line
[str appendAttributedString:[[NSAttributedString alloc] initWithString:#"\n"]];
// Add photo count
NSAttributedString *second = [[NSAttributedString alloc] initWithString:#"But this is my second string"
attributes:#{NSForegroundColorAttributeName:[UIColor redColor],
NSFontAttributeName:[UIFont fontWithName:#"HelveticaNeue-Light" size:14.0]}];
[str appendAttributedString:second];
But the result is:
this is my first string
if its too long i't will get
trunticated
The first string takes the first 3 lines and push the second string out of the label.
How can i limit the first string paragraph to 2 lines?

You can count the amount of letters that your graphic component (UITextView or UITextField) can handle using uppercase and bigger width ones repeatedly to see this. Than, use:
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{}
to check every input, if the amount is enough, or if it stills available for more letters. Create a character limit and decrease it everytime this method is called.

Limit the number of lines with one constraint !
Simply add a NSLayoutConstraint on your UILabel with following values :
attribute = NSLayoutAttributeHeight ('Height' in Storyboard)
relation = NSLayoutRelationLessThanOrEqual ('Less Than or Equal' in Storyboard)
constant = height-for-number-of-lines-you-want
See Storyboard integration :

Related

How could I change the color of a fixed character of placeholder text, as I am bit confused to perform this

I tried all the ways but its not as per my aspectations please help.
I have to change the color of all * to red.
I know I have to work in didload event.
I tried to get the last character of all the strings and do one by one but it makes the code quite lengthy hope there would be any should code/ approach.
Thanks
Image Here Please have a look
Try this one
NSMutableAttributedString *placeHoldertString = [[NSMutableAttributedString alloc] init];
NSAttributedString *str1 = [[NSAttributedString alloc] initWithString:#"First Name" attributes:#{ NSForegroundColorAttributeName : [UIColor lightGrayColor] }];
NSAttributedString *str2 = [[NSAttributedString alloc] initWithString:#"*" attributes:#{ NSForegroundColorAttributeName : [UIColor redColor] }];
[placeHoldertString appendAttributedString:str1];
[placeHoldertString appendAttributedString:str2];
yourTextFeild.attributedPlaceholder = placeHoldertString;
your question is still not clear you could make the textfield red on two events 1). when the user is entering the characters and jumps to the next textField you can make it red if the input is blank or incorrect
2). You can make it red on button click of submit or anything you want
and instead of writing it in View did load write it in UitextField Delegate method i.e Should change character in range method this will be called for each text field and you can use nested if else for your text field inside that method
e.g
if textField == (your textfiled name here)
{
//do your logic here for making the field red
}
remember you have to use this nested if else in should change character in length method UitextField Delegate
Try this
textField.attributedPlaceholder =
[[NSAttributedString alloc] initWithString:#"yourPlaceHolderName" attributes:#{NSForegroundColorAttributeName: yourColor, NSFontAttributeName : yourFont}];
}

UILabel adjustFont with multiline

I have a UILabel which usually has to display one or two words.
Many times one of the words doesn't fit into one line, so I would like to reduce font size in order to fit each word at least in one line (not breaking by character).
Using the technique described in http://beckyhansmeyer.com/2015/04/09/autoshrinking-text-in-a-multiline-uilabel/
self.numberOfLines = 2;
self.lineBreakMode = NSLineBreakByTruncatingTail;
self.adjustsFontSizeToFitWidth = YES;
self.minimumScaleFactor = 0.65;
I've found that it plays well when the second word doesn't fit in just one line.
But it doesn't when there is just one word, or the first word is the one
that doesn't fit.
I managed to solve the case of just one word doing this:
-(void)setText:(NSString *)text
{
self.numberOfLines = [text componentsSeparatedByString:#" "].count > 1 ? 2 : 1;
[super setText:text];
}
But how could I solve those cases where the first word doesn't fit?? Any ideas?
How about this ?
self.numberOfLines = [text componentsSeparatedByString:#" "].count;
[self setAdjustsFontSizeToFitWidth:YES];
But, this will rule out the case where your label text consists of two very small words, eg."how are". In such cases, the entire string will be visible in the first line itself. If it is your requirement to display each word in a separate line then i would recommend you adding a '\n' after every word. This means that you will have to edit the string before assigning it to the label. Thus, a universal solution could be like :
NSString *string = #"how are"; //Let this be the string
NSString *modifiedString = [string stringByReplacingOccurrencesOfString:#" " withString:#"\n"];
[self setText:modifiedString];
[self setTextAlignment:NSTextAlignmentCenter];
[self setAdjustsFontSizeToFitWidth:YES];
[self setNumberOfLines:0];
self.lineBreakMode = NSLineBreakByWordWrapping;

What's the best way to add a left margin to an NSAttributedString?

I'm trying to add a left hand margin to an NSAttributedString so that when I concatenate it with another NSAS, there is a bit of space between the two box frames.
All I have so far is this:
NSMutableAttributedString *issn = [[NSMutableAttributedString alloc] initWithString:jm.issn attributes:nil];
NSRange range = NSMakeRange(0, [issn length]);
[issn addAttribute:NSFontAttributeName
value:[UIFont fontWithName:#"AvenirNext-Medium" size:8]
range:range];
NSMutableAttributedString *textLabel = [[NSMutableAttributedString alloc] initWithAttributedString:title];
[textLabel appendAttributedString:issn];
I want the margin on the left side of the second string.
Thanks!
Edit: image upload
Why not just use a tab character between the two strings?
You could do this by changing your first line to this:
NSMutableAttributedString *issn = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:#"\t%#", jm.issn] attributes:nil];
This should output something like like what you want. You may, however, want to add 2 \t characters instead of one because depending on the string length, it may not need a tab character to align it (for example, in that exact string you posted, it didn't add anything to my output).
1 tab with your string:
2 tabs with your string:
You can't. If you're concatenating attributed strings then there is no "margin" around a specific range in the final string. How would that work with multiple lines or text wrapping?
If you want clear space within an attributed string, use white space characters - spaces or tabs. You can define the position of tab stops using paragraph styles.
All you can do is, add the required spaces(or whitespace characters) before the source string and then add it to your NSMutableAttributedString.
NSString *newString = [NSString stringWithFormat:#" %#", jm.issn] <- Have given two spaces here.
Thanks

Displaying Array in Text Label

I'm still sort of new to Xcode, so please be patient with me. Anyway, I'm having a bit of trouble trying to display the whole contents of an array in a UILabel. I'm able to display it by simply using the code
wordList.text = [NSString stringWithFormat:#"List of Words:\n %#", listA];
However upon running, the label ends up displaying a parenthesis and the words on their own lines, as well as quotation marks around the words, and the ending quotation mark and a comma in the line between each word. Example:
List of Words:
(
"apple
",
"banana
",
"etc.
While I do want the words to be displayed in their own lines, I do not want the parenthesis and the closing quotation mark and comma being displayed in a separate line. I would also prefer removing the parenthesis, quotation marks, and commas all together, but I wouldn't mind too much if I'm unable to.
Could anyone please explain why its being displayed as such, and to help me correctly display each word of an array in its own line in a UILabel?
Use this:
NSArray *listOfWords = #[#"One", #"Two", #"Three"];
NSString * stringToDisplay = [listOfWords componentsJoinedByString:#"\n"];
wordList.text = stringToDisplay;
Will Display:
One
Two
Three
The parentheses, quotation marks, and commas are being added because providing an array as an argument to the format specifier %# causes the -(NSString *)description method to be sent to the array. NSArray overrides NSObject's implementation of description and returns a string that represents the contents of the array, formatted as a property list. (As opposed to just returning a string with the array's memory address.) Hence, the extra characters.
You Can use this Code
NSArray *listOfWords = [NSArray arrayWithObjects:
#"one.",
#"two.",
nil];
for (NSString *stringToDisplay in matters)
{
//frame, setting
labelFrame.origin.x = 20.0f;
UILabel *stringToDisplayLabel = [[UILabel alloc] initWithFrame:labelFrame];
stringToDisplayLabel.backgroundColor = [UIColor clearColor];
stringToDisplayLabel.font = [UIFont boldSystemFontOfSize:12.0f];
stringToDisplayLabel.lineBreakMode = NSLineBreakByWordWrapping;
stringToDisplayLabel.numberOfLines = 0;
stringToDisplayLabel.textColor = [UIColor whiteColor];
stringToDisplayLabel.textAlignment = NSTextAlignmentLeft;
//set up text
stringToDisplayLabel.text = stringToDisplay;
//edit frame
[stringToDisplayLabel sizeToFit];
labelFrame.origin.y += stringToDisplayLabel.frame.size.height + 10.0f;
[self.view addSubview:stringToDisplayLabel];
[matterLabel release];
}

How to put different headIndent (alignment) for every paragraph in UITextView

In my application i need to align all the paragraph differently.
like, first paragraph's headIndent is 0.0f then second's 10.0f and third's 3.0f.
i am giving all the paragraph style to textview.attributedText. and it took only one style.
Here whole text will come dynamically by Typing. means when User will type in text view at that time. so, there are no static string to do this.
I am placing all the characters in UITextView by this...
UIFont *fontBold = [UIFont fontWithName:#"Helvetica-Bold" size:15];
attributesHelveticaBold = #{NSFontAttributeName :fontBold};
UIFont *fontNormal = [UIFont fontWithName:#"HelveticaNeue-Light" size:15];
attributesNormal = #{NSFontAttributeName :fontNormal};
if (varBold== 1) {
[textView setTypingAttributes:attributesHelveticaBold];
}
else {
[textView setTypingAttributes:attributesNormal];
}
And i want to get this kind of result in text view
When i am typing the typing become slow too.
but i think i'll come over that issue but for now i stuck on this alignment problem.
how to do it when bullet point come and when different text come.
any kind of link, code, tutorial will be great help...
---------- Edit : ----------
Please have a look in Evernote's application.
I need to do the exactly same thing in my app. for alignment of second,third,etc line when bullet come.
-------- Edit after searching :-------
I searched too much for this but ain't find anything by googling.
So, now i am asking if anyone now about How to give any paragraph style or any attribute style to a paragraph and just leave it as it is on text view and then perform other paragraph style on second paragraph. at this time the first paragraph will not pass throw "shouldChangeTextInRange" method.
yes, it's quite confusing whatever i am saying.
so i explaining it in general...
if user set the text view's first paragraph's headIndent=7.0f then when user will type next paragraph and set the headIndent = 13.0f then first paragraph will stay as it is in textview and just running paragraph will come in a chapter (means in a method).
right now i am doing these thing in shouldChangeTextInRange method to do style for each paragraph.
varStaringPointOfString = 0;
varEndingPointOfString = 0;
NSArray *sampleArrToGetattrStr = [txtViewOfNotes.text componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
for (int i=0; i<[sampleArrToGetattrStr count]; i++)
{
NSString *strtostoreLength = [NSString stringWithFormat:#"%#",[sampleArrToGetattrStr objectAtIndex:i]];
varStaringPointOfString = (int)strtostoreLength.length + varEndingPointOfString;
if ([strtostoreLength hasPrefix:#"\t•\t"])
{
[[textView textStorage] addAttribute:NSParagraphStyleAttributeName value:paragraphStyleForBullet range:NSMakeRange(varEndingPointOfString, strtostoreLength.length)];
}
else
{
[[textView textStorage] addAttribute:NSParagraphStyleAttributeName value:paragraphStyleNormal range:NSMakeRange(varEndingPointOfString, strtostoreLength.length)];
}
varEndingPointOfString = varStaringPointOfString;
strtostoreLength =#"";
}
but from this the speed of typing is become very slow.
Try this:
NSMutableParagraphStyle *paragraphStyle = [[[NSMutableParagraphStyle alloc] init];
[paragraphStyle setFirstHeadLineHeadIndent:firstLineIndend]; //Only the first line
[paragraphStyle setHeadIndent:headIndent]; //The rest of the lines, except the first one
[yourAttributedString addAttribute:NSParagraphStyleAttributeName
value:paragraphStyle
range:paragraphRange];
For the bullet point, that's something different. You need to find where are the bullet point, and set another indent accordingly.

Resources